サイトを移行します

まぁ...タイトルの通りなのですが、このサイトを他のブログサービスに移行させます。利用するのは Blogger です。

なぜ、移行するのかを少し。現在、ODN のホームページサービスを使っていますが、いかんせん古い。いまだにアップロードは FTP ですし(構わないといえば、構わないのですが...)、サービスも充実させる気がないようです。その昔、個人でホームページを作成するのが流行りましたが、そのときのままなのですね。サービスも使い勝手も。

HTML の手打ちは苦にならないのですが、サイトの管理が非常に面倒です。

Blogger は少し前から移行先としてぼちぼちと調べていました。ようやく、使い勝手もなんとなく分かってきました。カスタマイズの仕方や Google Data API を使った更新も慣れてきました。全面的な移行の準備が整った、というところです。

コンテンツは少しずつ移行している最中です。現在、3 分の 1 ほど終了。

移行にともない、あまり評判のよろしくなかったサイト名も変更します。ASH Planning

個人的にはテキトウな自分に最適な名称だと思っていたのですが。完全に移行(コンテンツをすべて移動し終えるまで)するまでは、ここは残しておきます。移行後は、契約解除します。

永らくご愛顧いただきありがとうございました。それでは、ASH Planning でお会いしましょう。

あ。それと Google Friend Connect ですが、せっかく導入したのですが、このサイトの終了にともない、Google Friend ConnectASH Planning に移行します。登録していただいた方には非常に迷惑な話なのですが、ASH Planning の方で再度登録していただけると幸いです。誠に申し訳ございません。

Google Chrome を入れてみた

Google Chrome の Mac、Linux 正式版が出たってことで、インストールしてみた。

興味はあったけど、インストールはしていなかった。興味はあったけど、関連するような情報は集めていなかった。ほぼ、無垢(?)な状態で無邪気に、新しいおもちゃを与えられた子供のようにわくわくしながら Google Chrome をインストールし、使い方を学び、環境を構築するまでのメモ in Snow Leopard。

Google Chrome のサイトよりディスクイメージをダウンロードし、Applications フォルダにコピー。

起動すると「Google Chrome へようこそ」というウィンドウが表示される。

google_chrome_welcome.jpg

Safari から設定のインポートを行い、Google へのレポートの送信にチェック(デフォルトの設定のまま)。「Google Chrome を起動」ボタンを押す。

なにかウィンドウが表示されるが、一瞬で消えてしまうので詳細は分からず。おそらく、インポートの状況を表すウィンドウだったのだろうが、勝手に消えない方が嬉しかった。

Google がデフォルトのホームページ。

メニューをチェック。基本的には Safari と似たようなメニュー構成、および、ショートカット(Keyboard and mouse shortcuts : Getting started - Google Chrome Help)。ヘルプが一部翻訳されていないのは、ご愛嬌。タブブラウザだからか、「新規ウィンドウ」より「新規タブ」が先にある。

Safari のようにブックマークバーのショートカットキーは割り当てられないよう。

ヘルプは Google の Web ページが表示される。

「表示」メニューに「開発/管理」メニューがある。「ソースを表示」はカラーリングと行番号が表示されて見易い。「デベロッパーツール」と「JavaScript コンソール」は Safari と同じ(Webkit!)。独特なのは「タスクマネージャ」かな。タブごとにプロセスを割り当てる Google Chrome ならでは。試しにタブのプロセスを終了させると、なかなか愛嬌のあるアイコンが表示される。一昔前の Mac を思い出させる。

google_chrome_crash.jpg

環境設定を開く。

「基本設定」タブで起動時に表示するページの設定、検索エンジンや既定のブラウザにするかどうかの設定ができる。ツールバーという見慣れないものがあるので、チェックを入れてみる。

ホームメニューはともかく、ページメニューとツールメニューがツールバー(ではないけど、似たようなもの)に右端に追加される。これは移動させられない?

「個人設定」タブで他のコンピュータとの同期(Google アカウントが必要)やパスワードの管理(キーチェーンアクセス.app で管理)、他のブラウザからの設定のインポートができる。

ブラウザからのインポートは、Safari からはパスワードと検索エンジンのインポートはできないみたい。Firefox からは可能。これは、Safari の仕様のため?

「高度な設定」タブでいろいろな設定ができる。設定項目が多いためか、ウィンドウ内に収まらない。そのためスクロールして設定項目を表示させる。

どうも Google Chrome の設定は、ボタンを押すと別でウィンドウかシートが表示され、詳細な設定を行うようになっているよう。これはこれで不必要な項目が並ばなくて、ごちゃごちゃしなくていいのだけど、いちいちウィンドウを閉じたり面倒でもある。環境設定のタブの数は増やしてもいいので、別のウィンドウを極力少なくしてほしいな。

また、「高度な設定」にいろいろ詰め込みすぎたためか必要な設定を探すのに時間がかかった。最初、フォントの設定がどこにあるのか分からなかった。

閲覧の履歴の削除は期間を指定して削除するみたい。だけど、閲覧履歴をどれぐらいの期間保存しておくのかの指定はどこでできるのだろう?もしかして、Google Chrome は全期間の履歴を保持するのがデフォルト?

環境設定で行える設定を行い、とりあえず、ブラウジング。自分のサイトなんかを見てみる。

基本的にブラウザに求めるものはシンプルさ。拡張機能やユーザースクリプトは、ほとんど利用したことがない。ブラウザに用意されている機能だけですませることが多い。ブックマークレットさえ、ほとんど利用しない。Google Chrome のインストールを機にいろいろと入れてみる。

といっても、Google Chrome で何ができるか分からないのだけど。

そういうわけで検索。

検索しながら気づくのだけど、URL アドレスが表示されているところ...。ホストの部分以外は灰色で表示される。また、ダブルクリックでホストの部分だけ選択できる。これは、ちょっと便利。

リンクにマウスを持っていくと、ウィンドウの下部に URL がひっそりと表示される。が、全部は表示されない。全部表示させられるのかな?これは、Safari にも欲しいな...。

ページの読み込みは速い。Google Chrome のホーム画面は、Safari の Top Sites よりも情報量が多いのだけど、なぜかシンプルで使いやすいと思った。ちなみに Safari の Top Sites は使っていない。

google_chrome_new_tab.jpg

とりあえず、Google Chrome まとめWiki を参考に色々と試してみる。Windows での情報だけど。

アドレスバーに about: と入力し、リターンキーを押すと様々な情報を得ることができるのだけど、現在ではいくつか利用できないものがある(about:stats など。Windows と Linux では使えるようだ)。

アプリケーションショートカットの作成も行えない...。これはちょっとショック。

すべての起動オプションは試していないけど、使えるみたい。Terminal などで以下を実行すれば、シークレットモード(Safari のプライベートブラウズのようなもの)で Google Chrome を起動できる。

$ /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --incognito

拡張子 command のシェルスクリプトファイルを作れば、ダブルクリックで起動オプションを適用して Google Chrome を起動できる。

#!/bin/sh

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --incognito &

exit 0

これをエディタで記述し、拡張子 command で保存する。Terminal で実行権限を与える。

$ chmod +x 保存したファイルのパス

ファイルをダブルクリックすることで Google Chrome をシークレットモードで起動できる。いちいちターミナルのウィンドウが開いてイヤだ...という方は、[Mac OS X] シェルスクリプトとかの CUI アプリケーションを Mac OS X 方式の .app にする方法 [簡単 5 ステップ]を参考にアプリケーションにしてしまうといいと思う。

これよりも簡単な方法は、拡張子を sh にしてスクリプトメニューに放り込んでおく方法。スクリプトメニューはなかなか優れもので、シェルスクリプトも実行できる(シェルスクリプト以外の Perl や Ruby や Python スクリプトでも)。

script_menu_in_shell_script.jpg

ユーザースクリプトは拡張機能として ~/Library/Google/Chrome/Default/Extensions にインストールされる。とりあえず、以下のものを入れてみた。

Create Link は、AppleScript でまともな操作ができないので必須。他にもいろいろあるみたいだけど、量が多いので、また後日。

拡張機能はわりと簡単に作れるようなので、AppleScript の対応を待つよりも拡張機能で対処した方が早いかも。

検索エンジンの追加、キーワードによる検索も利用可能。アドレスバー(Omnibox と呼ぶらしい)が地味に便利。アプリケーションショートカットは作れないけど、キーワードによるショートカットはできますね。

google_chrome_search_engine.jpg

これでアドレスバーに gmail と入力し、リターンキーを押すと Gmail が表示される。

ダウンロードと全履歴からの検索が便利。

AppleScript にはいちおう対応はしているけれど、ブラウザとして必要な機能は提供されていない。Automator のサービスは一部対応。アドレスバー(Omnibox というらしい)での文字列選択時にはコンテクストメニューからサービスの実行が可能。Web ページ上の文字列選択ではサービスは利用できない。

Omnibox の文字列選択からは文字列を選択したときのサービスが利用できるので、「URL を開く」を使えば、同じページをデフォルトのブラウザで表示することは可能。

とりあえず、一日使った感想。

起動が速いし、動作はきびきびとしている。Safari を常用している人なら、ショートカットキーも同じような感じだしそれほど違和感なく利用できると思う。個人的には常用してみようと思う。

Google Friend Connect を導入してみました

load script 命令におけるスクリプトの再利用」で書いたように Google ドキュメントのフォームを利用してコメント機能を使ってみたのですが、どうもしっくりこない。で、Google Friend Connect を導入してみました。

参考にしたのは以下のページ。

ほとんどそのまま、踏襲...。ログインしないとコメントもお薦めもできないので、少し、敷居が高い(というより、ちょっと面倒)かもしれませんが、よろしければ気軽にお願いします。

Automator in Snow Leopard - テキスト編

(個人的に)わりと評価が高い Automator。Snow Leopard で何が変わったかといえば、サービスを作成することができるようになったということだけなのですが、これが地味に便利。コンテクストメニュー地味に便利。

そんなわけで勢いに任せて、作ってみました。

インストーラーパッケージが解凍されるので、あとはダブルクリックしてインストールしてください。いつものことですが、ご利用はご自身の責任でお願いします。

収録されている内容は以下の通りです。

  • Finder • Insert Selections Name

Finder で選択されている項目の名前を挿入します。

  • Finder • Insert Selections POSIX path

Finder で選択されている項目の POSIX パスを挿入します。

  • iTunes • Insert Current Track

iTunes で現在再生されている曲名を挿入します。

  • iTunes • Now Playing

Twitter でよく見かけるようなフォーマット(Now Playing: [Artist] - [Track name])で iTunes で現在再生されている曲名を挿入します。

  • iTunes • Search Artist in ITS

選択されているテキストをアーティスト名としてい iTunes Store で検索を行います。

  • Safari • Insert Current URL

Safari で現在閲覧している Web ページの URL を挿入します。

  • Text • Add Line Number

行頭に 3 桁の行番号を追加します。

  • Text • Add Prefix

行頭に引用符(>)を追加します。

  • Text • Appley Markdown

選択されているテキストに Markdown を適用します。Markdown.pl が /usr/local/bin にインストールされている必要があります。

  • Text • Evaluate Date Format

UNIX の date コマンドで利用できる日時フォーマットを評価します。例えば、%Y-%m-%d なら、2010-05-22 になります。フォーマットについては Terminal で strftime のマニュアルを参照してみてください。

  • Text • Force Line Break

選択されているテキストを 80 文字で強制改行します。

  • Text • Insert Current Date

今日の日付を挿入します。実行するとダイアログでデータのフォーマットを尋ねます。UNIX の date コマンドで利用できるフォーマットを指定してください。デフォルトでは %FT%T%z (2010-05-22T00:10:59+0900)が指定されています。フォーマットについては Terminal で strftime のマニュアルを参照してみてください。

  • Text • Insert MIT License

MIT License を挿入します。現在の年とログインしているユーザーの名前が利用されます。

  • Text • Postal Code to Address

郵便番号を XML-RPC(全国郵便番号一覧 | 郵便専門ネットのWEBサービスAPI)を利用して住所に置き換えます。

  • Text • Replace Numbers to X

選択テキスト内にある半角数字を「X」に置き換えます。

  • Text • Search and Replace by Regex

選択テキストの検索と置換を正規表現を利用して行います。

  • Text • Search and Replace

選択テキストの検索と置換を AppleScript の text item delimiter を利用して行います。

  • Text • Separate by Space

テキスト内の半角英字の前後に半角スペースを挿入します。英単語を半角スペースで区切る(CotEditor) -avoidnote- を参考にさせていただきました。

  • Text • Shift Left

選択テキストの行頭にあるタブを一つ削除します。

  • Text • Shift Right

選択テキストの行頭にタブを一つ追加します。

  • Text • Sort

UNIX の sort コマンドを利用して選択テキストをソートします。

  • Text • Trim Empty Lines

空行を削除します。

  • Text • Trim White Space

行頭と行末にある空白(半角スペースとタブ)を削除します。

  • Text • URL Encode

選択テキストを URL エンコードします。

  • Text • View Postal Code in Google Maps

郵便番号から XML-RPC(全国郵便番号一覧 | 郵便専門ネットのWEBサービスAPI)を利用して住所の緯度と経度を取得し、Google Maps で表示します。

  • Text • View Selection Info

選択されているテキストの情報(文字数、行数、単語数)を表示します。

  • TextEdit • View Header File in TextEdit

open コマンドの -h オプションを利用し、Objective-C ヘッダファイル(NSView.h)を TextEdit で表示します。

  • Xcode • View Header File in Xcode

open コマンドの -h オプションを利用し、Objective-C ヘッダファイル(NSView.h)を Xcode で表示します。

以上、全 28 項目。使いやすいように変更、もしくはそのままでご利用ください。

QuickTime Player と AppleScript

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 を実行」アクションを使ってサービスメニューにするのもいいかもしれません。いつものことですが、ご利用はご自身の責任でお願いします。

Automator と AppleScript

Automator で作業をしていると、同じような作業を繰り返していることに気がつきます。定型作業を自動化させるのが Automator の目的なのに、その Automator で同じ作業を繰り返しているなんて。どうも、腑に落ちません。

Automator は登場した当初から AppleScript に対応していました。登場した当初はどうにも重たくて、以来使っていませんでした。Leopard の Automator で「変数」が使えるようになり、「ほう」と思ったものですが、やはりほとんど使いませんでした。

Snow Leopard インストールを期に使ってみたのですが、Automator 自身を Automator で操作できるわけでもなく、Automator の自動化は AppleScript からという環境に変わりはないようです。

唯一、変わったことといえば AppleScript からは「変数」が操作できるようになっていることぐらいでしょうか。反面、新規ワークフローの作成はスムーズにできなくなっています(必ずテンプレートを選択するシートが表示されるので)。

最初にも書いたように Automator は定型作業の繰り返しです。どのワークフローもおおむね同じようなアクションと変数を使います。特に「サービス」関連のワークフローにその傾向があります。

また、デバッグ時に同じようなアクションを何度も追加したり、削除したり...という作業が少なからず発生します。これが、結構手間だったりします。そのためでしょうか、Automator には add と remove という命令が備わっています。

Script Editor で開く

tell application "Automator"
    if not (front workflow exists) then return

    add Automator action "選択された Finder 項目を取得" to front workflow at index 1
end tell

名前参照で書いていますが、互換性を考えるなら Automator action の bundle id 属性などを使う方がいいと思います。

Script Editor で開く

tell application "Automator"
    if not (front workflow exists) then return

    set bundle_identifier to "com.apple.Automator.Get_Selected_Finder_Items_2"
    add Automator action id bundle_identifier to front workflow at index 1
end tell

ファイルやフォルダを処理するサービスなどは「選択された Finder 項目を取得」アクションを最初においてワークフローのデバッグを行うのですが、デバッグが終われば必要なくなります。remove 命令を使えば不必要なアクションや変数を取り除くことができます。

Script Editor で開く

tell application "Automator"
    if not (front workflow exists) then return

    set bundle_identifier to "com.apple.Automator.Get_Selected_Finder_Items_2"

    tell front workflow
        set remove_actions to Automator actions whose bundle id is bundle_identifier
        repeat with this_action in remove_actions
            remove this_action
        end repeat
    end tell
end tell

デバッグ時には特定のアクションの使用、不使用の切り替えを行いたいときがあります。Automator action の enabled 属性で切り替えることができます。次のスクリプトでは使用されているアクションの中から選択されたものを使用停止にします。

Script Editor で開く

tell application "Automator"
    if not (front workflow exists) then return

    tell front workflow
        set action_list to a reference to (Automator actions whose enabled is true)
        if (count of action_list) is 0 then return

        set action_names to name of action_list
        set use_actions to choose from list action_names default items (item 1 of action_names) with multiple selections allowed
        if use_actions is false then return
        repeat with this_action in use_actions
            set enabled of Automator action this_action to false
        end repeat
    end tell
end tell

変数なども同じように add, remove 命令で追加や削除が行えます。次のスクリプトは変数の一覧の中から選択されたものをワークフローに追加します。

Script Editor で開く

tell application "Automator"
    if not (front workflow exists) then return
    set variable_list to name of variables
    my combSort(variable_list)
    set used_variables to choose from list variable_list default items (item 1 of variable_list) with multiple selections allowed
    if used_variables is false then return

    repeat with this_value in used_variables
        add variable this_value to front workflow
    end repeat
end tell

on combSort(theList)
    set gap to count theList

    repeat
        set gap to (gap * 10) div 13
        if gap is 0 then set gap to 1

        set flag to false
        repeat with i from 1 to (count theList) - gap
            if (item i of theList) is greater than (item (i + gap) of theList) then
                set flag to true
                set tmp to item i of theList
                set item i of theList to item (i + gap) of theList
                set item (i + gap) of theList to tmp
            end if
        end repeat
        if not ((gap is greater than 1) or flag) then exit repeat
    end repeat
end combSort

変数などは複数のワークフローで使い回したいときがあります。テンポラリなファイルの保存先などはそういったものの一つです。あるワークフローにある変数を他のワークフローにコピーする...こういうことも add 命令で可能です。次のスクリプトはワークフローの変数を他のワークフローにコピーするスクリプトです。

Script Editor で開く

tell application "Automator"
    activate
    if (count workflows) < 2 then return

    set name_list to name of workflows

    set source_document to choose from list name_list default items (item 1 of name_list) with prompt "Select source workflow:"
    if source_document is false then return
    set source_document to source_document as text

    set name_list to my remove_item(name_list, source_document)

    set destination_document to choose from list name_list default items (item 1 of name_list) with prompt "Select destination workflow:"
    if destination_document is false then return
    set destination_document to destination_document as text

    set original_variables to name of variables of workflow source_document
    set used_variables to choose from list original_variables default items (item 1 of original_variables) with multiple selections allowed
    if used_variables is false then return
    repeat with this_value in used_variables
        set contents of this_value to variable this_value of workflow source_document
    end repeat

    repeat with this_value in used_variables
        add this_value to workflow destination_document
    end repeat
end tell

on remove_item(the_list, removed_item)
    set new_list to {}

    repeat with this_item in the_list
        set this_item to contents of this_item
        if this_item is not removed_item then
            set end of new_list to this_item
        end if
    end repeat

    return new_list
end remove_item

保存されたワークフローの実態はパッケージなんですが、パッケージの中身は至ってシンプルで document.wflow というファイルがあるだけです(サービスなんかだと Info.plist も追加されるけど)。このファイルはすべての情報が書かれているプロパティリストファイルです。ファイルの中をのぞくだけで、そのワークフローがどんなアクションを利用しているかが分かります。

ダウンロードしてきたワークフローの中身を確認するのに Automator を起動する必要はなく、このファイルを見るとすべてが分かります。このことを利用して、Finder で選択されているワークフローで使われているアクションの一覧を表示するスクリプト。

Script Editor で開く

set workflow_plist to ":Contents:document.wflow"

tell application "Finder"
    set current_selection to selection
    if selection is {} then return

    set info_list to {}
    repeat with this_item in current_selection
        set this_item to this_item as text
        set plist_file to this_item & workflow_plist
        if exists (alias plist_file) then
            set workflow_info to my get_action_info(POSIX path of plist_file)

            if workflow_info is not {} then
                set action_text to my join(workflow_info, return & tab)
                set end of info_list to displayed name of alias this_item & return & tab & action_text & return
            end if
        end if
    end repeat
end tell

if info_list is not {} then
    tell application "TextEdit"
        activate
        set the_document to make new document
        set text of the_document to my join(info_list, return)
    end tell
end if

on join(the_list, delimiter)
    tell (a reference to text item delimiters)
        set {tid, contents} to {contents, delimiter}
        set {the_text, contents} to {the_list as text, tid}
    end tell

    return the_text
end join

on get_action_info(workflow_file)
    tell application "System Events"
        set plist_file to property list file (workflow_file)
        tell plist_file
            set action_info_list to {}
            repeat with this_item in property list items of property list item "actions"
                set end of action_info_list to value of property list item "ActionName" of property list item "action" of this_item
            end repeat
        end tell
        return action_info_list
    end tell
end get_action_info

サービスをいくつか作っていると、メニューに表示される名前を変更したいときがあります。これはワークフローの名前を Finder で変更しても変わるわけではなく、変更するには Automator でワークフローを開き別名で再保存するか、ワークフローのパッケージ内にある Info.plist の値を変更する必要があります。いちいちそういうことをするのも面倒なので、作ったのが次のスクリプト。

Script Editor で開く

property file_extensions : {".workflow"}

tell application "Finder"
    set current_selection to selection
    if current_selection is {} then return

    set workflow_files to {}
    repeat with this_item in current_selection
        set file_name to displayed name of this_item
        set this_item to POSIX path of (this_item as text)
        set {file_name, ext} to my splitext(file_name)
        if ext is in file_extensions then
            set plist_file to this_item & "/Contents/Info.plist"
            my set_defaut_menu_item_name(plist_file, file_name)
        end if
    end repeat
end tell

on set_defaut_menu_item_name(plist_file, document_name)
    tell application "System Events"
        if not (disk item plist_file exists) then return missing value

        tell property list file plist_file
            if not (property list item "NSServices" exists) then return missing value
            tell property list item "NSServices"
                if not (property list item "NSMenuItem" of property list item 1 exists) then return missing value
                tell property list item "NSMenuItem" of property list item 1
                    set menu_text to value of property list item "default"
                    if menu_text is not document_name then
                        set value of property list item "default" to document_name
                    end if
                    return value of property list item "default"
                end tell
            end tell
        end tell
    end tell
end set_defaut_menu_item_name

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

Finder で選択されているワークフローのメニュー名をファイルの名称に変更します。

以上のスクリプト以外にもいくつかまとめて。

いつものことですが、ご利用はご自身の責任でお願いします。

ところで、Automator には AppleScript という変数があります。この変数は変わった変数で、AppleScript の実行結果を変数として利用することができます(「シェルスクリプト」という変数もそうだけど)。変数のレベルで AppleScript やシェルスクリプトが利用でき、かつ、アクションにも同じようなアクションがある...。ここまでくるとやりたい放題ですね。

Automator でサービスを作成する前に...

ようやくのことで Snow Leopard を入れてみました。環境を整備し、ソフトウェアを入れ、じっくりと触ってみました。なんだか、描画が変になることがありますし、微妙な違和感(バグかどうかよくわからない現象が時々起こる)があります。Leopard の方が使いやすかったなぁ...。Leopard は手に馴染んでいた。まぁ、使い勝手は慣れてくるのでしょうが。

さて。

今更の感もありますが、Snow Leopard の目玉の一つ、Automator。以前にも Automator の記事を書きましたが、Snow Leopard になっていろいろと便利になったようなので、Snow Leopard に対応したものを。

Automator は、基本的にはなんらかの「入力」を受け取り、それらを「加工」し、加工したものを「出力」します。この処理プロセスはプログラムの基本なのですが、Automator はプログラムらしさを排除し、わかりやすいインターフェースで処理プロセスを作成することができるアプリケーションです。

Automator が入力として受け取れるデータはいろいろとありますが、基本は「ファイル/フォルダ」か「テキスト」です。出力も同様です。

Automator は入力されたデータを「加工」するのですが、データを加工するのが「アクション」です。アクションは単体で動作するものもありますし、それだけでは動作しないものもあります。アクションを一つ、または複数つなげることで目的のデータに加工し、出力します。アクションは直前のアクションが加工したデータを入力として受け取り、次のアクションに加工したデータを渡します。最後のアクションが出力するデータが最終的な結果となります。

アクションを一つ、または複数並べたものを「ワークフロー」といいます。ワークフローを保存しておくことで様々な場面で繰り返し利用することができます。

Automator を起動すると、最初に「ワークフロー」のテンプレートを選択することになります。利用目的によってこれらのテンプレートから一つを選び、ワークフローの作成を開始します。

テンプレート「ワークフロー」は汎用的なワークフローです。目的に応じてワークフローを作成し、保存しておきます。保存したワークフローの利用方法は多岐に渡ります。

保存されたワークフローを ~/Library/Scripts に入れておくことで、スクリプトメニューから利用することができます。また Terminal からワークフローを指定して automator コマンドで処理をさせることができます。

テンプレート「ワークフロー」で作成したワークフローは「プリントプラグイン」、「イメージキャプチャ・プラグイン」としても利用できます。これらは特別に Automator のテンプレートを利用しなくても特定のフォルダの中に入れておくだけで利用できます。

また、ワークフローを「アプリケーション」として保存しておくとドラッグ & ドロップでデータを受け取ることができるようになります。アプリケーション形式だと「iCal アラーム」としても利用できます。

基本的にはテンプレート「ワークフロー」でワークフローを作成、保存しておくことで上記のような利用が可能になります。しかし、このテンプレートでは「サービス」と「フォルダアクション」として利用できるワークフローにはなりません。「サービス」と「フォルダアクション」だけは少し特殊で、これらはテンプレートを利用しないと作成することはできません。

「フォルダアクション」は最初に対象となるフォルダを設定しておく必要があります。フォルダを設定し、保存(~/Library/Workflows/Applications/Folder Actions に保存される)した時点でフォルダアクションは実行されるようになります。停止は ~/Library/Workflows/Applications/Folder Actions から対象のワークフローを取り除くことによって行います。

「サービス」は ~/Library/Services にワークフローとして保存されるのですが、普通のワークフローではなく、サービス経由でデータを受け取れるように設定されて保存されます。この設定があるため、通常のワークフローは「サービス」として利用することができません。

と、まぁ基本的なところは以上でしょうか。

なんといっても目玉は「サービス」なんでしょうね。ところで、Snow Leopard になってから /Library/Scripts にインストールされるスクリプトが減りましたね。Finder 関連のものは全てなくなってしまいました。また、ColorSync のスクリプトは ColorSyncScripting を利用していたのが sips で代用するようになっていますね。Finder 関連のものがなくなったのは Automator の「サービス」があるからいいでしょ、ということでしょうか。

なくなった Finder 関連のスクリプトの代替サービスは Mac OS X Automation: Services Downloads で入手することができます。ここからダウンロードできるサービスとアクションは全て入れておくといいと思います。便利なものが揃っています。中でも面白いのが「Website Popup」というアクション。URL を渡すと半透明の HUD ウィンドウにウェブサイトを表示してくれます。

今回、久しぶりに Automator を本格的に触ってみました(Mac OS X 10.5 の時は全く使っていませんでした)が...、なかなか楽しませて頂きました。Finder 関連のスクリプトがなくなるのもむべなるかな。

しかし、分かりにくいところもありますが。とてつもなく分かりにくいのが、変数。その次に分かりにくいのが「サービス」の「選択項目」と「検索対象」。両方とも理解できるとどうってことないのですが。

まず、「サービス」の「選択項目」。基本的には「選択されているテキスト」か「選択されているファイルまたはフォルダ」のいずれかになります。さらに「選択されているテキスト」は「URL」、「アドレス」、「電話番号」、「日付」、「メールアドレス」のいずれかから選択することができます。例えば、URL を選んでおくと URL 以外の文字列を選択してもサービスのメニューには表示されません。

サービスはこのように賢く振る舞ってくれるのですが、正確には URL を含んでいる文字列を認識し、それをワークフローの入力として渡します。ですから、入力された文字列は、必ずしも正確な URL だとは限りません。正確な URL を抜き出す作業はユーザーに一任です。この作業を行ってくれるアクションは Mac OS X Automation: Services Downloads からダウンロードできます。Get URLs from Text がそれですが、Get Dates from Text というアクションも一緒にぜひとも入れておきましょう。

「ファイルまたはフォルダ」も同様で、例えば「イメージファイル」を選択しておくと「イメージファイル」以外が選択されているときはメニューに表示されません。

「検索対象」は作成した「サービス」がどのアプリケーションで表示されるかを設定するためのものですが、「すべてのアプリケーション」を選択することでどのアプリケーションであってもメニューに表示されるようになります。問題は「選択項目」でこれを「入力なし」にするとアプリケーションのサービスメニューにしか表示されないようになります。コンテキストメニューの方では表示されません。

つまり「選択項目」を「入力なし」、「検索対象」を「すべてのアプリケーション」にすると、すべてのアプリケーションで利用できるけど、アプリケーションメニューのサービスメニューにしか表示されないサービスになるのです。このようなサービスはいつでもどのような状況からでも利用できるメニューになるのでキーボードショートカットを与えておくと便利に利用できます。

「選択項目」と「検索対象」でどこのメニューに表示されるか、どのようなときに表示されるかが決定されます。

Automator は Mac OS X 10.5 の時から「変数」が使えたのですが...正直、目的の変数をどのように作るのか理解するのには骨が折れました。

「変数」は便利なように最初からデフォルトの値を持ったものがあります。歯車のアイコンがついているものがそれです。他方、値をカスタマイズできるように設定を行える変数があります。V というアイコンがついているものがそれです。

これらの用意さている変数を組み合わせて目的の変数を作成します。では、例えば、ファイルを保存するのに一意の名前を付けたい、といったとき。スクリーンキャプチャしてファイルを保存するとき、「Capture-ユーザー名年月日時間」といった書式のファイル名を作りたいとします。

必要なのは「ユーザー名」と「年月日」と「時間」、それに保存する「場所」です。これらは用意されている変数から作成します。

まず、Automato の「変数」を表示し「ユーザー」を選択、その中にある「ユーザー名(ショートネーム)」をダブルクリックします。

Automator で変数を配置する

すると、ウィンドウの下部にある「変数」に「ユーザー名(ショートネーム)」が追加されます。

変数一覧に追加された変数

同様の手順で「場所」から「ピクチャ」を。そして、「日付と時刻」から「今日の日付」と「現在の時刻」を追加します。これらは値をカスタマイズできる変数です。現在、変数一覧は次のようになっています。

追加された変数一覧

「時刻」と「日付」の書式をカスタマイズします。変数一覧にある「今日の日付」をダブルクリックすると小さなウィンドウが表示されます。「名前」は変数名になります。the_date としておきます。「フォーマット」から「カスタムフォーマット...」を選択し、下図のようにします。

日付のフォーマットを変更

年月日の間にあるハイフンは自分で入力します。また、月日はそれぞれ 2 桁になるように変更しておきます。

月日を 2 桁表示に

同様の手順で「現在の時刻」も下図のように変更しておきます。

時刻のフォーマットを変更

以上で必要な変数は揃いました。後はこれらを組み合わせてファイル名を作成します。変数一覧の部分でコンテキストメニューを表示すると「新規変数...」というメニューが現れます。これが、欲しかった変数で見つけるのに時間がかかった変数です。

コンテキストメニューの「新規変数...」メニュー

この変数は「テキストとデータ」にある「テキスト」という変数なのですが、まさか、これを使って複数の変数を組み合わせるなんて思いもよりませんでした。ともかく、「新規変数...」を選択するとこの変数が追加されます。追加された変数をダブルクリックし、下図のようにします。

変数の変更

分かりにくいのですが「値」は変数一覧にある変数をドラッグ & ドロップして追加します。『ピクチャ』「Capture-」『ユーザー名(ショートネーム)』「_」『the_date』「T」『the_time』という並びになっています(『』で囲んでいるものが変数一覧からドラッグ & ドロップしたもの。「」で囲んでいるものは記述したもの)。

この file_name という変数をワークフローのところにドラッグ & ドロップし、「結果を表示」アクションを使うと変数がどのような結果を返すかが確認できます。

変数の結果を確認

こうやって作った変数はスクリーンキャプチャの保存先や、新規テキストファイルの保存先などとして利用することができます。拡張子は必要ありません。適宜、補ってくれます。

変数を保存先に適用

変数はこうやって使うのですね...。全く知りませんでした。

実際にいくつかサービスを作ってみようと思ったのですが...そこにたどり着くまでが長かった。ということで、次の機会にでも。