macOS 26上でdisplay youtube AppleScriptライブラリの機能を利用したAppleScriptを、macOS標準搭載の「スクリプトメニュー」から呼び出すと、

のようにエラー表示されるようになっていました。
macOS 26.0βのときには再生されたりしていたのですが、リリース後のmacOS 26.2では再生されません。
これが、macOSの内部機能やポリシーの変更によるものなのか、あるいはmacOS 26のデフォルト設定の変化によるものかは不明です。YouTube側の仕様変更という疑いもありますが、定かではありません。
以前は文字列で組み立てたHTMLをWkWebViewに読み込ませていましたが、いまmacOS 26上ではそのやり方ではYouTubeのムービーは再生されません。
そこで、根本的な解決を図るため、local web server(httpd)を介してHTMLを表示する方式に変更。docrootをtemporary items folderに設定したhttpdを起動。temporary items folderに書き込んだhtmlをダイアログ上のWkWebViewに表示するようにしました。
このlocal web serverの起動にpython3を呼び出しており、インストールされていない環境(一般的な環境ではインストールされていない)ではDeveloper Toolsのインストールが実行初回時に行われます。一般ユーザーのことを考えるとPython3以外のツールを使って起動すべきなんでしょう。

以前のバージョンと異なるのは、ダイアログ上のWkWebViewに再生用のUI(中央にYouTUbeロゴ)が配置され、それをクリックしないとムービーの再生が始まらないことです。このあたりは、自動再生を開始できるように改変できそうではあるものの、同時にデメリット(音声の再生が行えないとか)が生じるおそれがあるため、現状のままがよさそうです。

それでも、macOS 26上でWkWebViewでYouTubeムービーを再生させられるようになりました。まだ、繰り返し実行して問題が出ないかといったテストを行なっている段階です。

htmlファイルの書き込みが間に合わないと上記のようなエラーが出ていましたが、処理の冒頭で明示的にhttpdをkillすることで、この問題を解消できるようになりました。httpdのkillについては、他のプログラムが起動していた場合には問題になりそうなので、そこも様子見といったところでしょう。
ちなみに、YouTubeムービー再生以外の用途では、とくにこのような大幅な改変は必要ではないと認識しています。たとえば、CDN上のJavaScriptライブラリを呼び出してアニメーション表示つきのグラフ表示をAppleScriptで行なっていますが、こちらでは書き換えは必要ありませんでした。


| AppleScript名:youtubeムービー再生実験.scpt |
| — – Created by: Takaaki Naganoya – Created on: 2025/11/12 — – Copyright © 2025 Piyomaru Software, All Rights Reserved — use AppleScript version "2.8" use framework "Foundation" use framework "AppKit" use framework "WebKit" use scripting additions property |NSURL| : a reference to current application’s |NSURL| property WKWebView : a reference to current application’s WKWebView property NSURLRequest : a reference to current application’s NSURLRequest property NSRunningApplication : a reference to current application’s NSRunningApplication property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration property returnCode : 0 set mainMessage to "Youtube Test" set subMessage to "Using local Web Server" set viewSizeArray to {1200, 640} set youtubeMovieID to "GP_tVXTYdmY" –テスト用HTML文字列 –set htmlString to "<!DOCTYPE html><html><body><h1>Hello World</h1></body></html>" — HTML文字列 set htmlString to " <!DOCTYPE html> <html lang=\"ja\"> <head> <meta charset=\"UTF-8\"> <title>YouTube Embed</title> <style> body { margin:0; padding:0; } iframe { width:100%; height:100vh; border:none; } </style> </head> <body> <iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/" & youtubeMovieID & "?start=1\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe> </body> </html> " try do shell script "pkill -f ’http.server’ || true" end try set docroot to POSIX path of (path to temporary items) –1. Python3でバックグラウンドサーバー起動(Local Web Server) set pythonCmd to "python3 -m http.server 8000 –directory " & quoted form of docroot & " >/dev/null 2>&1 & echo $!" set pidStr to do shell script pythonCmd set serverPID to pidStr as integer — 2. HTMLを書き出す set htmlPath to docroot & "index.html" set nsHTML to current application’s NSString’s stringWithString:htmlString nsHTML’s writeToFile:htmlPath atomically:true encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) — 3. 少し待ってサーバー起動を待機 delay 0.5 try — 4. WKWebViewでHTTP URLを読み込む set httpURL to "http://localhost:8000/index.html" set paramObj to {myMessage:mainMessage, mySubMessage:subMessage, viewSize:viewSizeArray, htmlStr:"", myURL:httpURL} –my browseURLContents:paramObj my performSelectorOnMainThread:"browseURLContents:" withObject:(paramObj) waitUntilDone:true on error errMsg display dialog errMsg end try — 5. サーバープロセス終了 try do shell script "pkill -f ’http.server’ || true" end try — WKWebView表示用ハンドラ on browseURLContents:paramObj set webSize to viewSize of paramObj copy webSize to {aWidth, aHeight} set aURL to myURL of paramObj set aConf to WKWebViewConfiguration’s alloc()’s init() set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) configuration:aConf aWebView’s setNavigationDelegate:me aWebView’s setUIDelegate:me aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true set bURL to |NSURL|’s URLWithString:aURL set bReq to NSURLRequest’s requestWithURL:bURL aWebView’s loadRequest:bReq — Move to frontmost current application’s NSApplication’s sharedApplication()’s setActivationPolicy:(current application’s NSApplicationActivationPolicyRegular) current application’s NSApp’s activateIgnoringOtherApps:true — アラートに埋め込む set theAlert to current application’s NSAlert’s alloc()’s init() tell theAlert –addButtonWithTitle_("Cancel") its setMessageText:(myMessage of paramObj) its setInformativeText:(mySubMessage of paramObj) its addButtonWithTitle:"OK" its setAccessoryView:aWebView set myWindow to its |window| tell myWindow its setLevel:(current application’s NSScreenSaverWindowLevel) setInitialFirstResponder_(aWebView) end tell end tell — モーダル表示 NSRunningApplication’s currentApplication()’s activateWithOptions:0 set returnCode to (theAlert’s runModal()) as number — WKWebViewの後始末 set jsStop to "try { document.getElementById(’ytplayer’).contentWindow.postMessage(’{\"event\":\"command\",\"func\":\"stopVideo\",\"args\":\"\"}’, ’*’); } catch(e) {}" aWebView’s evaluateJavaScript:jsStop completionHandler:(missing value) delay 0.1 aWebView’s loadRequest:(NSURLRequest’s requestWithURL:(|NSURL|’s URLWithString:"about:blank")) delay 0.1 aWebView’s stopLoading() set aWebView to missing value set aWebView to missing value end browseURLContents: |




