Expression Tips①<isDuration>
AEにおける時間値(秒)をフレーム数に変換したい場合、単純に時間値をそのコンポのフレームレートで掛ければ得る事が可能ですが、下記の表記でもOKです。
timeToFrames(t, fps, isDuration) //以下は引数の初期設定 //t = time + thisComp.displayStartTime, //fps = 1.0 / thisComp.frameDuration, //isDuration = false
引数は省略可なので、例えばシンプルにtimeToFrames()
等と書くだけでササッとフレーム数を得られます。
しかし、このように変数を端折った楽チンな書き方が原因で自分は一度悩まされた経験があり、以後は極力使わないように気をつけています。
今回はこれの検証を兼ねた覚書を記事にしたいと思います。
例
30fpsのコンポ内にて、テキストレイヤーのソーステキストにtimeToFrames(1)
と入力します。
このコンポにおける時間1秒、つまり"30"(f)を得る事を想定した式になります。
プレビューにも正しく表示されており問題ありませんね。
では、続いて次の画像をご覧下さい。
↓
先程と同様の式に見えるこの画像ですが、プレビューには"31"とあり異なる結果となっています。
はて、一体何故なんでしょうか?またいつものAEの大ボケか?
ちなみにいくら目を凝らして画像の間違い探しをしても無意味ですのでやめましょうw
眼精疲労視力低下等の健康被害を訴えられても当方一切の責任は負いません!
さておき解答ですが、原因は画像では見えない部分、コンポの開始フレームの設定の仕方の違いによるものになります。
下記にそれぞれの設定内容を並べてみます。
【前者の設定】
・プロジェクト設定のフレームを"0から開始"
・コンポジション設定で開始フレームを"1"に
【後者の設定】
・プロジェクト設定のフレームを"1から開始"
これらを要約するとつまり、タイムライン上ぱっと見は同じでも
プロジェクト設定で"0"か"1"どちらから開始かによってtimeToFrames(*)
の結果が左右されるという事です。
※*は任意の値
この点の配慮を怠ると、例えば"1から開始"の設定で作業していたaepを仕様変更等で"0から開始"に変更した場合、timeToFrames(*)
を使用している箇所全てに影響が出て思わぬ事故に繋がりかねません。
勿論逆も然りです。
まぁこんなのは相当レアなケースではあるかと思いますが、危険なのは間違いないので何とかしないとマズイです。
解決策
引数isDuration
を初期設定false
からtrue
に変更する事で差異を回避できます。
(記事タイトルがネタバレ)
ご覧のとおり。やったー♪
isDuration
は他にもtimeToFeetAndFrames()
やtimeToCurrentFormat()
等のメソッドにも使用され、同様の差異が発生し得ます。
ただし、timeToTimecode()
とtimeToNTSCTimecode()
では確認できませんでした。
"プロジェクト設定→フレーム数:タイムコード変換"では正しい値になるので、恐らくタイムコードだからでしょうか。
皆さんも引数の省略には十分にご注意ください。
ちなみに公式リファレンスによると
isDuration 引数は、初期設定では false ですが、t 値が絶対時間ではなく2つの時間の差を表す場合は、true にする必要があります。 絶対時間は負の無限大に近づくように切り捨てられます。デュレーションはゼロから離れて正の値になるように切り上げられます。
とあります。
え?初期設定のfalse
で絶対時間指定しておかしくなるやん??と思わなくも無いのですが、きっとこれは自分の理解が足りないせいでしょう。
世の中結果が全てです。I don't mind.