Snow Leopard で QuickTime Player が一新されました。どんなものなのかと思っていましたが...、まだまだ QuickTime Player 7 は必要ですね。そんな QuickTime Player ですが、AppleScript の対応度はどれほどのものなのか。ちょっと、調べてみました。
まず、一通りの操作は AppleScript で行えるようです。以前の QuickTime Player は Pro にすると、編集機能や書き出し機能が利用できるようになりました。これらの機能は Pro 版を購入しなくても AppleScript から利用できることはよく知られていました。
Snow Leopard の QuickTime Player は、Pro といったものがなく、最初から全機能を利用できるようになっています。フルスクリーン再生や画面収録、ビデオ収録、オーディオ収録、不要な部分を切り取るトリムなどの機能が最初から利用可能なのですが、以前の QuickTime Player Pro に比べると、かなり貧弱な機能しか利用できません。
例えば、参照ムービーで保存することはできません。トラックを個別に扱うこともできないですし、テキストトラックの追加もできません。「Web 用に保存...」というメニューで保存を行うと参照ムービーが保存されるのですが、これを開くのは QuickTime Player Launcher というアプリケーションで、参照ムービーを開くと自動的に QuickTime Player 7 が起動されるようになっています。つまり、取り扱えないのですね。
ポスターフレームを設定することもできませんし、書き出しといってもあらかじめ設定された書き出ししか行えません。以前のように細かい設定はできないようになっています。どちらかというと不要な機能を取り除き、シンプルになったという方がいいかもしれません。細かい設定を行いたい場合は iMovie 09 か QuickTime Player 7 を使うしかありません。
同じように AppleScript から扱える機能もシンプルです。
document クラスでいえば、ムービーの時間に関連する current time や duration といった属性が秒数を返すようになっています。秒数で結果が返るので、time scale 属性はなくなっています。duration 属性だけで再生時間が取得できるのは手軽でいいのですが、タイムコードを作るときはどうすればいいのでしょう?
System Events を使うと取得することはできますが。
Script Editor で開く
tell application id "com.apple.QuickTimePlayerX"
if not (exists front document) then return
set the_file to file of front document
set time_scale to my get_timescale(the_file)
set selection_start to current time of front document
set current_time to (selection_start * time_scale) as integer
set movie_length to ((duration of front document) * time_scale) as integer
set movie_length to my make_timecode(movie_length, time_scale)
set timecode_text to my make_timecode(current_time, time_scale)
set file_name to name of front document
activate
display dialog (file_name & return & return & "Length: " & movie_length & return & "Current Time: " & timecode_text) as text with icon 1 buttons {"Clipboard", "OK"} default button 2
if (button returned of result) is "Clipboard" then
set the clipboard to timecode_text
end if
end tell
on make_timecode(current_time, time_scale)
set total_seconds to current_time div time_scale
set partial_seconds to current_time mod time_scale
set h to total_seconds div hours
set hh to my add_zero(h, 2)
set m to (total_seconds - (h * hours)) div minutes
set mm to my add_zero(m, 2)
set s to (total_seconds - (m * minutes)) div 1
set ss to my add_zero(s, 2)
set partial_seconds to my add_zero(partial_seconds, 3)
set AppleScript's text item delimiters to ":"
set timecode_text to {hh, mm, ss} as text
set AppleScript's text item delimiters to {""}
set timecode_text to timecode_text & "." & partial_seconds
return ("[" & timecode_text & "]") as text
end make_timecode
on add_zero(int, digit)
set this_number to int as text
set n to count this_number
if n is digit then
return this_number
else
set zero_count to digit - n
repeat zero_count times
set this_number to "0" & this_number
end repeat
return this_number
end if
end add_zero
on get_timescale(this_file)
if (class of this_file) is in {«class furl», file, alias} then
set this_file to POSIX path of this_file
end if
tell application id "com.apple.systemevents"
tell QuickTime file this_file
return time scale
end tell
end tell
end get_timescale
でも、これって秒数を返すのですからわざわざ time scale を調べなくてもいいような気がします。
選択した範囲内を切り取る trim 命令は秒数で指定するようになっています。しかし、すべてが秒数指定かというとそうではなく、ムービーの再生場所を少しずつ移動させる step forward や step backward 命令はフレーム単位のままです。
step forward や step backward 命令がフレーム単位なら、全体のフレーム数を数えることもできますね。
Script Editor で開く
tell application id "com.apple.QuickTimePlayerX"
if not (front document exists) then return
tell front document
set current_time to current time
set current time to 0
step forward -- 1 フレーム動かす
set frame_length to current time
set current time to current_time
-- 全体の秒数を 1 フレームの秒数で乗算(総フレーム数)
set frame_count to duration / frame_length
-- 1(秒)を 1 フレームの秒数で乗算(fps)
set fps to 1.0 / frame_length
set movie_name to name of it
set msg to name of it & return & return
set msg to msg & "1 frame seconds: " & (frame_length as text) & return
set msg to msg & "Frame count: " & (frame_count as text) & return
set msg to msg & "FPS: " & (fps as text)
activate
display dialog msg with icon 1
end tell
end tell
一応このような計算で総フレーム数や FPS を算出できますが、必ずしも正確ではありません(例えば、画面収録やムービー収録で保存したムービーでは正確な数値を出せない)。正確さを求めるなら、QuickTime Player 7 を使う方がいいです。参考までに QuickTime Player 7 で行った場合を。
Script Editor で開く
tell application id "com.apple.quicktimeplayer"
if not (front document exists) then return
tell front document
set video_track to tracks whose type is "vide"
set video_track to item 1 of video_track
set time_scale to time scale
set movie_length to duration
set frame_count to count (frames of video_track)
set num to frame_count * time_scale
set fps to num / movie_length
{frame_count, fps}
end tell
end tell
copy 命令がないのも痛いですね。現在の選択範囲を画像として書き出す...そういうこともできません。そもそも、選択範囲を作り出すことができないですし。当然、ビデオトラックの左右反転や上下反転もできないですし、歪ませることもできません。開かれているすべてのムービーを連結する...そういうこともできません。こうやって見ていると、できないことの方が多いです。できることを並べていった方が早いかな?
では、ムービーのフルスクリーン再生。
Script Editor で開く
tell application id "com.apple.QuickTimePlayerX"
if not (front document exists) then return
tell front document
present
play
end tell
end tell
present 命令は、以前はいろいろとオプションを指定できましたが、そういう指定はできなくなっています。
次のスクリプトは 10 フレーム先に進むスクリプト。
Script Editor で開く
tell application id "com.apple.QuickTimePlayerX"
if not (front document exists) then return
tell front document
if playing then
stop
end if
step forward by 10
end tell
end tell
step forward を back forward にすれば 10 フレーム戻ります。ムービーの再生速度を変更させるには document クラスの rate 属性を 変更します。2 倍速にするには以下のようにします。
Script Editor で開く
tell application id "com.apple.QuickTimePlayerX"
if not (front document exists) then return
tell front document
if playing then
stop
else
set rate to 2.0
end if
end tell
end tell
rate 属性にはあり得ない値を設定することもできます。例えば、10000 倍速とか。すごいのは QuickTime Player 7 なら落ちてしまっていた、こういうあり得ない数値でもスムーズに再生し、安定していることです。もっとも、目には何も映りませんが。逆方向に倍速再生したいなら、負の値を rate 属性に設定します。スロー再生したいときは、-1.0 から 1.0 までの値...例えば、0.5 や -0.5 などを設定します。
新しい QuickTime Player は AppleScript から書き出すときでも複数のファイルを並行して書き出すことができます。この辺りが唯一のいいところかもしれません。書き出しの設定は決められたものしか使えませんが。save 命令は同じものを別名で保存するのに利用できます。
書き出しには export 命令を使います。次のスクリプトでは前面のムービーを指定されたフォーマット(複数指定可)で書き出します。
Script Editor で開く
property export_presets : {"Apple TV", "Computer", "iPhone (Cellular)", "iPhone", "iPod", "HD 480p", "HD 720p", "HD 1080p"}
property file_extensions : {".m4v", ".m4v", ".3gp", ".m4v", ".m4v", ".mov", ".mov", ".mov"}
tell application id "com.apple.QuickTimePlayerX"
activate
if not (front document exists) then return
set file_name to name of front document
set file_path to (file of front document) as text as alias
set save_folder to my parent_folder(file_path) as text
set {file_name, ext} to my splitext(file_name)
set using_presets to choose from list export_presets default items (item 1 of export_presets) with multiple selections allowed
if using_presets is false then return
set export_settings to {}
repeat with i from 1 to count using_presets
set this_preset to item i of using_presets
repeat with j from 1 to count export_presets
if (item j of export_presets) is this_preset then
set end of export_settings to {item j of export_presets, item j of file_extensions}
end if
end repeat
end repeat
repeat with this_preset in export_settings
set {preset_name, ext} to contents of this_preset
set out_file to save_folder & file_name & " - " & preset_name & ext
export front document in file out_file using settings preset preset_name
end repeat
end tell
on splitext(file_name)
set reversed_name to (reverse of (characters of file_name)) as text
set num to offset of "." in reversed_name
if num is 0 then
set ext to ""
else
set reversed_ext to text 1 thru num of reversed_name
set ext to (reverse of (characters of reversed_ext)) as text
set ext_num to count ext
set name_length to count file_name
set file_name to text 1 thru (name_length - ext_num) of file_name
end if
return {file_name, ext}
end splitext
on parent_folder(the_file)
tell application "Finder" to return container of the_file as alias
end parent_folder
書き出しに利用できるプリセットですが、「コンピュータ」、「Apple TV」、「iPod」、「iPhone」、「iPhone (Cellular)」、「HD 480p」、「HD 720p」、「HD 1080p」だけです。それぞれ、英語で正確に指定します。これらの設定がどこにあるかというと、QuickTime Player のパッケージ内の Resources フォルダにあります。それぞれ、Apple TV.plist といった設定の名前でプロパティリストファイルで保存されています。
このプロパティリストを真似して他の設定を追加することも可能だと思うのですが...。ちょっと、怖くてまだ手を出していません。もし、やってみようと思うなら自己責任でお願いします。
trim 命令は選択範囲を切り取る命令です。秒数で範囲を指定し、その範囲を切り出します。以下のスクリプトはムービーを均一の長さ(ここでは 10 分単位)に分割して保存します。
Script Editor で開く
property split_length : minutes * 10
tell application id "com.apple.QuickTimePlayerX"
if not (front document exists) then return
tell front document
set file_name to name of it
set file_path to (file of it) as text as alias
set save_folder to my parent_folder(file_path) as text
set {file_name, ext} to my splitext(file_name)
set movie_length to duration
if movie_length < split_length then return
set split_count to movie_length div split_length
set rest_length to movie_length mod split_length
set length_list to {}
repeat with i from 1 to (split_count * split_length) by split_length
set end of length_list to {(i - 1), i + split_length - 1}
end repeat
if rest_length is not 0 then set end of length_list to {movie_length - rest_length, movie_length}
repeat with i from 1 to count length_list
set {start_time, end_time} to item i of length_list
set out_file to save_folder & file_name & "_" & (i as text) & ext
trim from start_time to end_time
save it in file out_file
close it saving no
open file_path
end repeat
end tell
end tell
on splitext(file_name)
set reversed_name to (reverse of (characters of file_name)) as text
set num to offset of "." in reversed_name
if num is 0 then
set ext to ""
else
set reversed_ext to text 1 thru num of reversed_name
set ext to (reverse of (characters of reversed_ext)) as text
set ext_num to count ext
set name_length to count file_name
set file_name to text 1 thru (name_length - ext_num) of file_name
end if
return {file_name, ext}
end splitext
on parent_folder(the_file)
tell application "Finder" to return container of the_file as alias
end parent_folder
0 から 10 分、10 分から 20 分 というようにわざと最初と最後の一秒をかぶらせています。新しいドキュメントを作ってそこにコピーする...といった操作ができないので、オリジナルのファイルから範囲を切り取ったら保存せずに閉じ、またオリジナルのファイルを開く...といったことを繰り返しています。何となく、見栄えが悪いな。
最後に画面収録、オーディオ収録、ビデオ収録について。これらも AppleSciprt から利用することができます。document クラスにはこれらに関する属性、current microphone(音声を録音するのに利用するマイク), current camera(ビデオを録画するのに利用するカメラ), current audio compression(音声の圧縮設定), current movie compression(ビデオの圧縮設定), current screen compression(画面収録の圧縮設定)) があります。
これらの属性は新規に作成した画面収録、オーディオ収録、ビデオ収録、いずれかがないと利用できません。どのような設定や入力源が利用できるかは以下のようにして調べることができます。
Script Editor で開く
tell application id "com.apple.QuickTimePlayerX"
audio recording devices -- 音声入力源一覧
video recording devices -- ビデオ入力源一覧
audio compression presets -- 音声収録圧縮設定の一覧
movie compression presets -- ビデオ収録圧縮設定の一覧
screen compression presets -- 画面収録圧縮設定の一覧
end tell
これらは application クラスの要素なので、tell document 1 などとしている中では利用できません。また、新規に作成した画面収録、オーディオ収録、ビデオ収録などの属性を実際に変更するには a reference to 演算子を使って参照にしておく必要があります。
新規にオーディオ収録を作成し、オーディオの入力源を変更するには以下のようにします。
Script Editor で開く
tell application id "com.apple.QuickTimePlayerX"
activate
set device_names to name of audio recording devices -- 音声入力源一覧
set using_device to choose from list device_names
if using_device is false then return
-- 参照に
set using_device to a reference to (audio recording device (using_device as text))
close documents saving no
set audio_recording to new audio recording
set current microphone of audio_recording to using_device
end tell
途中で開かれているすべてのムービーを閉じているのは、画面収録、オーディオ収録、ビデオ収録は一度に一つしか作成することができないからです。画面収録をしながらオーディオ収録(またはビデオ収録)ということはできるのですが(QuickTime Player の隠し設定でできるようになったような...)、どのムービーがどの収録を行っているムービーなのかといったことは AppleScript から調べることができません。これも QuickTime Player 7 だと調べることができるのですが。そのため、エラーを回避するためにすべて閉じています。
start 命令で収録の開始が行えます。pause 命令で収録の一時停止ができますが、画面収録では利用することはできません。pause 命令で一時停止している収録は、resume 命令で再会することができます。stop 命令で収録を終了することができます。
これぐらいでしょうか。AppleScript で制御できるのは。QuickTime Player 7 だととてもこの分量でまとめきれないのですが。嬉しいような、悲しいような。
QuickTime Player の AppleScript をまとめたものをおいておきます。基本的にはすべて ~/Library/Scripts/Applications/QuickTime Player に置いて、スクリプトメニューからの利用を想定していますが、使いやすいようにご利用ください。Automator の「AppleScript を実行」アクションを使ってサービスメニューにするのもいいかもしれません。いつものことですが、ご利用はご自身の責任でお願いします。