AppleScript で iPhone 用ムービーに変換する
昨日 の続き。 Autometer でだめなら AppleScript ではどうか。
QuickTimeX の Player を手動で立ち上げて読み込ませれば、 希望通りに保存できるのだから、 AppleScript なら思ったことができるのではないかと考えた。 そこでとりあえず、 ファイルを一つ選んで保存する AppleScript を組んでみた。
-- Covert 1 Movie To iPhone Movie property aDestExtName : ".m4v" set aMovieFile to choose file with prompt "変換するムービーを選択してください" set aDestFolder to choose folder with prompt "出力先フォルダを選択してください" set anExt to name extension of (info for aMovieFile) set aMoviePath to POSIX path of aMovieFile set aCommand to "basename " & quoted form of aMoviePath & " ." & anExt set aDestFile to (aDestFolder as string) & (do shell script aCommand) & aDestExtName tell application "QuickTime Player" set aMovie to open aMovieFile activate -- play document 1 export aMovie in aDestFile using settings preset "iPhone" close aMovie saving no end tell
export
ハンドラの using settings preset
オプションに、
何を指定したらいいものかしばし悩んだが、
「ファイル>別名で保存...」の「フォーマット」ポップアップメニューの項目を指定してみたらズバリだった。
でもプリセットの設定でしか保存できないって QuickTime 7 (Pro) から機能ダウンしているよな。
後で
/Applications/QuickTime Player.app/Contents/Resources/SaveAsExportPresets.plist
というプロパティリストを見つけた。
この中にいくつかプリセットの名称が書かれている。
プリセットのすべてかはわからないけれど。
さて、 これで気をよくして複数のムービーをバッチ処理で iPhone 用のムービーに書き出す (export する) フォルダアクション用の AppleScript を書いてみた。 Snow Leapard の QuickTimeX じゃないと動きません。
スクリプトを書く際には
/Library/Scripts/Folder Action Scripts/Image - Duplicate as JPEG.scpt
を参考にした。
property done_foldername : "iPhone Movies" property originals_foldername : "Original Movies" property settings_preset : "iPhone" property newmovie_extension : "m4v" -- the list of file types which will be processed property type_list : {"3gpp"} -- since file types are optional in Mac OS X, -- check the name extension if there is no file type -- NOTE: do not use periods (.) with the items in the name extensions list -- eg: {"txt", "text", "jpg", "jpeg"}, NOT: {".txt", ".text", ".jpg", ".jpeg"} property extension_list : {"mov", "m4v", "mp4", "3gp", "3gpp", "3g2", "3gpp2", "dv", "mpg", "mpeg", "flv", "avi", "wmv"} on adding folder items to this_folder after receiving these_items tell application "Finder" if not (exists folder done_foldername of this_folder) then make new folder at this_folder with properties {name:done_foldername} end if set the results_folder to (folder done_foldername of this_folder) as alias if not (exists folder originals_foldername of this_folder) then make new folder at this_folder with properties {name:originals_foldername} set current view of container window of this_folder to list view end if set the originals_folder to folder originals_foldername of this_folder end tell set processed_number to 0 repeat with this_item in these_items set the item_info to the info for this_item if (alias of the item_info is false and the file type of the item_info is in the type_list) or (the name extension of the item_info is in the extension_list) then try tell application "Finder" set the new_name to my resolve_conflicts(this_item, results_folder, newmovie_extension) end tell process_item(this_item, new_name, results_folder) tell application "Finder" my resolve_conflicts(this_item, originals_folder, "") move this_item to the originals_folder with replacing end tell set processed_number to processed_number + 1 on error error_message number error_number if the error_number is not -128 then tell application "Finder" activate say "error has occured" display dialog error_message buttons {"Cancel"} default button 1 with title "on adding" giving up after 120 end tell end if end try end if end repeat if processed_number > 0 then say "movies exporting has done" end adding folder items to on resolve_conflicts(this_item, target_folder, new_extension) tell application "Finder" set the file_name to the name of this_item set file_extension to the name extension of this_item if the file_extension is "" then set the trimmed_name to the file_name else set the trimmed_name to text 1 thru -((length of file_extension) + 2) of the file_name end if if the new_extension is "" then set target_name to file_name set target_extension to file_extension else set target_extension to new_extension set target_name to (the trimmed_name & "." & target_extension) as string end if if (exists document file target_name of target_folder) then set the name_increment to 1 repeat set the new_name to (the trimmed_name & "." & (name_increment as string) & "." & target_extension) as string if not (exists document file new_name of the target_folder) then -- rename to conflicting file set the name of document file target_name of the target_folder to the new_name exit repeat else set the name_increment to the name_increment + 1 end if end repeat end if end tell return the target_name end resolve_conflicts -- this sub-routine processes files on process_item(source_file, new_name, results_folder) try tell application "QuickTime Player" -- the target path is the destination folder and the new file name set the target_path to ((results_folder as string) & new_name) as string set this_movie to open file (source_file as string) set export_timeout to (duration of this_movie) * 2 launch -- always use with Folder Actions with timeout of export_timeout seconds play this_movie export this_movie in file target_path using settings preset settings_preset my wait_for_process(target_path, export_timeout) close this_movie saving no end timeout end tell on error error_message tell application "QuickTime Player" close this_movie saving no end tell tell application "Finder" activate say "error has occured" display dialog error_message buttons {"Cancel"} default button 1 with title "process_item" giving up after 120 end tell end try end process_item on wait_for_process(target_path, timeout_sec) tell application "Finder" set timeout_msec to timeout_sec * 10 set rest_timeout_msec to timeout_msec repeat while rest_timeout_msec > 0 do shell script "sync" if exists target_path then set target_size to the size of the document file target_path else if timeout_msec - rest_timeout_msec < 150 then set target_size to 0 else error "target file ''" & target_path & "'' was not created" number 1 end if if target_size > 0 then exit repeat end if delay 0.1 set rest_timeout_msec to rest_timeout_msec - 1 end repeat end tell return true end wait_for_process
以上を /Library/Scripts/Folder Action Scripts/Movie - Export as iPhone.scpt
に保存して、
~/Movies/Movies for iPhone
フォルダのフォルダアクションとして登録した。
後はこの Movies for iPhone
フォルダにムービーをドロップすると、
そのフォルダの中の iPhone Movies
に export される。
ドロップしたファイルは同じく Original Movies
に移動するようにしている。
export 出来ないファイルは移動しない。
後、
書き出すのに時間がかかるので少し寂しいので、
process_item サブルーチンの中で
export ハンドラを実行する前に play this_movie
としてムービーを再生するようにしてみた。
うるさいと思う人は play this_movie
を削除してほしい。
また FLV や WMV ムービーも受け付けるようにしてみたけれど、
Perian や Flip4Mac WMV をインストールしていないと書き出しに失敗すると思う。
受け付けるムービーは、
スクリプト冒頭の extension_list
に拡張子のリストを設定しているので、
そこら辺を微調整するといいだろう。