WkWebViewを動的に生成して、YouTube上の指定ムービーを再生するAppleScriptです。
# AppleScriptでは、Webブラウザに命令を出せば数行のコマンドで簡単に任意のURLのWebコンテンツを表示させられますが、本ScriptはAppleScriptから他のアプリケーションを介さずに直接Cocoaの機能を呼び出して自前でWebコンテンツを表示させるものです
NSWindow+NSSplitView+WKWebViewを作成して、Webサーバー上の内容を表示します。WkWebViewでWebの内容を表示させるのにかなり苦労しましたが、Objective-Cのサンプル数本を比較してテストし実現しました。
WkWebViewでコンテンツを表示するのにこんなに大変だと思いませんでしたが、これができるようになったおかげで、AppleScriptの処理結果のURLを(Webブラウザを利用せずに)プレビューできます。
グラフ描画のプログラムがJavaScript+WebViewで作られているケースが多々あるため、凝ったインタラクティブなグラフの表示を行ったり画像やPDFに出力できるようにもなったわけで、たいへんけっこうなことです。
▲Auto StartでYouTube上のムービーの再生を開始する
まだ解決できていないのは、YouTubeのムービー再生が始まるとウィンドウをクローズしてAppleScriptの実行が終了していても再生中の音声が停止しないあたりでしょうか。メモリ上からWebブラウザのオブジェクトを明示的にパージする方法についてはまだ実装できていません。
あと、Script Debugger上で動かすと、WkWebView上のコンテンツの操作(YouTube映像の再生コントロールとか)ができなくなります。ねんのため。
AppleScript名:WebView+ボタンを作成 v3(URLから読み込み) |
— Created 2018-11-27 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" use framework "WebKit" property |NSURL| : a reference to current application’s |NSURL| property NSColor : a reference to current application’s NSColor property NSString : a reference to current application’s NSString property NSScreen : a reference to current application’s NSScreen property NSButton : a reference to current application’s NSButton property NSWindow : a reference to current application’s NSWindow property NSSplitView : a reference to current application’s NSSplitView property NSTextView : a reference to current application’s NSTextView property NSScrollView : a reference to current application’s NSScrollView property WKWebView : a reference to current application’s WKWebView property WKUserScript : a reference to current application’s WKUserScript property NSURLRequest : a reference to current application’s NSURLRequest property NSMutableString : a reference to current application’s NSMutableString property NSWindowController : a reference to current application’s NSWindowController property NSTitledWindowMask : a reference to current application’s NSTitledWindowMask property NSRoundedBezelStyle : a reference to current application’s NSRoundedBezelStyle property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding property NSBackingStoreBuffered : a reference to current application’s NSBackingStoreBuffered property WKUserContentController : a reference to current application’s WKUserContentController property NSMomentaryLightButton : a reference to current application’s NSMomentaryLightButton property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration property NSScreenSaverWindowLevel : a reference to current application’s NSScreenSaverWindowLevel property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd property windisp : false property wController : false set aWidth to 1100 set aHeight to 600 set aTitle to "WkWebView test" set aButtonMSG to "OK" –set aURL to "https://www.youtube.com/watch?v=GP_tVXTYdmY&autoplay=1&hd=1" set aURL to "https://www.youtube.com/embed/GP_tVXTYdmY?autoplay=1&hd=1" set paramObj to {aWidth, aHeight, aTitle, aURL, aButtonMSG, "600"} my performSelectorOnMainThread:"dispWebView:" withObject:(paramObj) waitUntilDone:true on dispWebView:paramObj set my windisp to false copy (paramObj as list) to {aWidth, aHeight, aTitle, tmpURL, aButtonMSG, timeOutSecs} set (my windisp) to true set aWidth to aWidth as integer set aHeight to aHeight as integer set tmpURL to tmpURL as string –WebViewをつくる set aConf to WKWebViewConfiguration’s alloc()’s init() set jsSource to my fetchJSSourceString(tmpURL) set userScript to WKUserScript’s alloc()’s initWithSource:jsSource injectionTime:(WKUserScriptInjectionTimeAtDocumentEnd) forMainFrameOnly:true set userContentController to WKUserContentController’s alloc()’s init() userContentController’s addUserScript:(userScript) aConf’s setUserContentController:userContentController set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight – 100)) configuration:aConf –フレームの大きさは根拠レス aWebView’s setNavigationDelegate:me aWebView’s setUIDelegate:me aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true set bURL to |NSURL|’s URLWithString:tmpURL set aReq to NSURLRequest’s requestWithURL:bURL aWebView’s loadRequest:aReq –Buttonをつくる set bButton to (NSButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, 40))) bButton’s setTitle:aButtonMSG bButton’s setTarget:me bButton’s setAction:("clicked:") bButton’s setKeyEquivalent:(return) –SplitViewをつくる set aSplitV to NSSplitView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) aSplitV’s setVertical:false aSplitV’s addSubview:aWebView aSplitV’s addSubview:bButton aSplitV’s setNeedsDisplay:true set aWin to makeWinWithView(aSplitV, aWidth, aHeight, aTitle, 1.0) –NSWindowControllerを作ってみた set my wController to NSWindowController’s alloc() my (wController’s initWithWindow:aWin) my (wController’s showWindow:me) set aCount to (timeOutSecs as string as number) * 10 –timeout seconds * 10 repeat aCount times if (my windisp) = false then exit repeat end if delay 0.1 end repeat –Purge Web Objects (not success) set aWebView to "" set userContentController to "" set aConf to "" set userScript to "" set my wController to "" my closeWin:bButton end dispWebView: –Button Clicked Event Handler on clicked:aSender set (my windisp) to false my closeWin:aSender end clicked: –make Window for Input on makeWinWithView(aView, aWinWidth, aWinHeight, aTitle, alphaV) set aScreen to NSScreen’s mainScreen() set aFrame to {{0, 0}, {aWinWidth, aWinHeight}} set aBacking to NSTitledWindowMask –NSBorderlessWindowMask set aDefer to NSBackingStoreBuffered — Window set aWin to NSWindow’s alloc() (aWin’s initWithContentRect:aFrame styleMask:aBacking backing:aDefer defer:false screen:aScreen) aWin’s setTitle:aTitle aWin’s setDelegate:me aWin’s setDisplaysWhenScreenProfileChanges:true aWin’s setHasShadow:true aWin’s setIgnoresMouseEvents:false aWin’s setLevel:(NSScreenSaverWindowLevel) aWin’s setOpaque:false aWin’s setAlphaValue:alphaV –append aWin’s setReleasedWhenClosed:true aWin’s |center|() — Set Custom View aWin’s setContentView:aView return aWin end makeWinWithView –close win on closeWin:aSender set tmpWindow to aSender’s |window|() repeat with n from 10 to 1 by -1 (tmpWindow’s setAlphaValue:n / 10) delay 0.02 end repeat my wController’s |close|() end closeWin: on viewDidLoad:aNotification return true end viewDidLoad: on fetchJSSourceString(aURL) set jsURL to |NSURL|’s URLWithString:aURL set jsSourceString to NSString’s stringWithContentsOfURL:jsURL encoding:(NSUTF8StringEncoding) |error|:(missing value) return jsSourceString end fetchJSSourceString |
ぴよまるソフトウェアが選ぶ、2018年に書いた「価値あるScript」 – AppleScriptの穴 says:
[…] ・WebView+ボタンを作成 v3(URLから読み込み) 従来のWebViewがDepricated扱いになり、WKWebViewを使わなくてはならなくなったわけですが、使いこなすのに予想外に資料が存在せず(使い方がイ […]