動画編集

PeloReaper Extensionの情報やダウンロードはこちらからどうぞ。
PeloReaper Extension for REAPER is here.
ReaperBanner01_w250 AudioSoftBanner01_w250

REAPERで動画編集:動画再生CODEC確認方法など

動画再生時にうまく絵が出ないとか、何かしらCODECに不具合が生じたことはありますでしょうか?
と書き始めながら、自分はそういうのに出くわしたことがないんですが・・・(汗)

原則としてこちらの記事で紹介しているVLC、FFmpegを適切にセットアップ(REAPERが認識)しているという前提ですが、万が一おかしい状況が出てきたら問題を特定する方法は知っておきたいところです。

そんな時に役立ちそうな以下のTIPSを今回はご紹介します。

※ちなみに今回紹介しているこれらの内容は「動画再生時」に使われるCODECの話で、動画の書き出しには関係ありませんのでご注意ください。


動画ファイルの再生に利用されているCODEC確認方法

タイムライン(Arrange View)上に動画ファイルをドロップするとVideo Itemが出来て、動画再生出来るようになりますが、このVideo ItemのSource Propertyを見ることで、VLC・FFmpegいずれでこの動画を読み込んで再生しているかが分かります。

Video Itemを右クリック>Source properties...
↑ Video Itemを右クリック>[Source properties...]

VISrc_VLC02
↑ VLCで読み込まれていることが分かる

ここで例えばVLCで再生がうまくいかないという場合、FFmpegで再生してみたいと思うかもしれませんが、どうすればよいでしょうか。わざわざVLCをアンインストールするのも手間がかかります。

この場合、次節のCODECの優先順位変更でFFmpegを優先するのも一つの方法です。


使用されるCODECの優先順位変更方法

REAPERのPreferences(メインメニューの[Options>Preferences...])で[Video/import/Misc]に[Video decoder priority]という項目があります。ここに記述されている内容の順番で、動画のデコードに使用されるCODECの優先順位が決まります。順番として最初の方に書かれているものの方が優先されます。

PrefVideo02

デフォルトではVLCが優先されているので、これをFFmpeg優先に変えてみましょう。

PrefVideo03

これでPreferencesウィンドウの[OK]ボタンで確定し、REAPERを起動しなおします。そしてVideo Itemの[Source properties...]を見てみると、FFmpegで動画がロードされていることが分かります。

VISrc_Ffmpeg02
↑ FFmpegで読み込まれている

このようにして読み込みを行うCODECの切替を行ってみることで、「VLCではダメだったけど、FFmpegでは問題なし」などのように動画再生に問題がありそうな箇所を絞り込んでいくことが出来そうです。

この優先順位をいろいろいじってしまって元の順番が分からなくなったという場合は、右側にある[Reset to default]ボタンで元に戻せますから、問題が出た時はいろいろ試してみると良いかと思います。


REAPERで動画編集 (12) : VideoProcessor : APIリファレンス

今回はREAPERのVideoProcessor(以下VP)のAPIをまとめておきます。

ちなみにどこに書かれていたか忘れてしまいましたが、VPのAPIリファレンスはVPのスクリプトウィンドウで[F1]キーを押すと表示されます。かなり見づらいですが、これくらいしか情報源がないというのも事実です。

予約済み変数

既に予約されている変数があり、様々な値が設定されている。これらを上書きすることで、設定を変更できるものもある。
  • project_time
    タイムライン上での現在の再生時刻(秒)
  • project_tempo
    テンポの値(BPM)
  • project_ts_num
    現在の拍子の分子の値
  • project_ts_denom
    現在の拍子の分母の値
  • project_time_qn
    タイムライン上での現在の再生時刻(QN(4分音符)単位)
  • time
    VPを実行しているItemかTrack先頭からの経過時間。ItemとTrackいずれにVPを挿しても、実際より0.02秒程度大きい値が返るが、理由は不明。
  • framerate
    プロジェクトのVideo設定で指定されたフレームレート(FPS)
  • project_w
    画像の出力サイズ(幅)。値を変更することで、強制的に出力サイズを変更可能。
  • project_h
    画像の出力サイズ(高さ)。値を変更することで、強制的に出力サイズを変更可能。
  • project_wh_valid
    プロジェクトのVideo設定の画像サイズになっているか(0の場合はメディア側のサイズなどになっている)
  • colorspace
    現在の描画用色空間。'RGBA'、'YV12'、'YUY2'が設定できる。文字列ではないため、シングルクォートで囲むこと。設定によって色の解釈が変わる。
  • param_wet
    FXに挿したVPであれば、そのFXのWet値。Wet値はエンベロープ等で変更可能。
  • param1~param16
    GUI(ノブ)で操作できるパラメータ。以下のような記述方法で定義するが、VPプリセットのサンプルを見ると分かりやすい。
    //@param <index>[:varname] 'name' [defval minval maxval centval step]

描画用の状態変数

描画の前に設定することで、描画に影響を与えられる変数たち。
  • gfx_r, gfx_g, gfx_b, gfx_a
    矩形描画や文字列描画などに使用されるRGBA値を個別に設定できる。
  • gfx_mode
    いわゆる描画のブレンドモード指定。colorspaceにより使えるものが異なる。
    • 0:通常のαブレンドモード
    • 1:加算モード
    • 3:乗算モード(RGBAとYUVとで結果が大きく異なる)
    • 17:[YUVのみ有効] (dest + src * gfx_a) * 0.5 + 0.5
    • 18:[YUVのみ有効] dest + (src -0.5) * gfx_a * 2
    • 19:[YUVのみ有効] 差分の絶対値 abs(dest - src) * gfx_a
    また、以下のフラグ追加で挙動が変わる模様。
    • 0x100:可能な場合、blit()でフィルタリングがかかるようになる
    • 0x10000:[RGBAのみ有効] ソースα値を使用
    • 0x40000:通常モードで追加のクランプを行う(αやGradient値の範囲外防止)
    • 0x80000:[YUVのみ有効] gfx_r, gfx_g, gfx_b をYUV値として扱う
  • gfx_dest
    描画先になる画像ハンドルを設定できる。-1に設定するとメインのフレームバッファに戻せる。

入力画像関連

画像管理のしくみについてはこちらの記事を参照。
  • input_count()
    現在アクセス可能な画像の個数
  • input_track_count()
    現在の再生時刻でアクセス可能な有効トラック数(動画・VPが配置されているもののみ)
  • input_track( trackIndex )
    指定したトラックの最終出力画像を取得。trackIndex=0はこの関数を呼ぶVPがある次のトラックを指し示すことに注意。
  • input_track_exact_count()
    現在の再生時刻における、トラック数を返す。これには動画・VPを含まないトラックも数に含まれる。
  • input_track_exact( trackIndex )
    指定したトラックの最終出力画像を取得。エラーとして、トラックに動画・VPがない場合は-1000、trackIndexが有効範囲外であれば-10000という値が返る。
  • input_next_item( img )
    imgの次の画像を取得する。検索はアイテム単位で順に進んでいく。
  • input_next_track( img )
    imgの次の画像を取得する。検索はトラック単位で順に進んでいく。
  • input_ismaster()
    通常は0が返るが、MasterFX, MonitorFXにVPを挿していると以下の値が返る。
    • 1:MasterFX ChainにVPが挿入されている
    • 2:MonitorFX ChainにVPが挿入されている
  • input_info( img, w, h [, srctime, wet, param1, ...] )
    画像の情報を取得する。img以外は全て画像の情報が引数の変数に書き込まれる。

動的な画像確保関連

画像をVP内で一時的に確保して、効果を作るための画像バッファとして利用できます。
  • gfx_img_alloc( [w, h, clear] )
    新しい画像インスタンスを確保します。戻り値に画像ハンドルが返ります。
  • gfx_img_free( img )
    gfx_img_alloc()で確保した画像インスタンスを解放します。
  • gfx_img_info( img, w, h )
    画像の情報(幅、高さ)を取得します。戻り値に取得できたかどうかが返ります。
  • gfx_img_resize( img, w, h [,clear] )
    画像のリサイズ。
  • gfx_img_hold( img )
    現在の画像を後のフレームでも参照できるようにコピーして保持(戻り値に画像ハンドルが返る)。これで取得したハンドルは不要になったらgfx_img_free()で解放する必要があります。
  • gfx_img_getptr( img )
    画像単位で割り振られる?ユニークなID値を取得します。gfx_img_hold()で画像が保持されている間だけ有効。

描画関連

画像や矩形の描画や色変換等の関数がいろいろと用意されています。意外とラインや円を描画するといったものはないので、それに近い表現をするには画像を用意するとか、gfx_evalrect()で頑張るとかする必要がありそうです。
  • gfx_set( r, g, b [, a=1, mode=0, dest] )
    描画用状態変数の設定。R,G,B,A, Modeは省略も含めて必ず設定されます。destのみ指定されたら更新されます。
  • gfx_blit( img [, preserveAspect=0, x, y, w, h, srcX, srcY, srcW, srcH] )
    画像を描画。アスペクト保持や描画範囲などの指定が可能。
  • gfx_fillrect( x, y, w, h )
    現在の色設定で矩形を描画
  • gfx_procrect( x, y, w, h, channelTable [, mode] )
    チャンネルカラーテーブルを使って色変換を行う。使い方はこちらの記事を参照。
  • gfx_evalrect( x, y, w, h, codeString [, flags, src2] )
    ピクセルフォーマットの処理単位でスクリプトを実行する。使い方はこちらの記事を参照。
  • gfx_gradrect( x, y, w, h, r, g, b, a [, drdx, dgdx, dbdx, dadx, drdy, dgdy, dbdy, dady] )
    グラデーションの具合を指定して矩形を描画。
  • gfx_rotoblit( srcIndex, angle [, x, y, w, h, srcX, srcY, srcW, srcH, clipToSrcRect=0, centXOffs=0, centYOffs=0] )
    画像を回転させて描画。centXOffs, centYOffsで回転の中心をずらすことが出来る。
  • gfx_deltablit( srcIndex, x, y, w, h, srcX, srcY, dsdx, dtdx, dsdy, dtdy, dsdxdy, dtdxdy [, dadx, dady, dadxdy] )
    画像の読み書き参照位置等をずらしながら描画を行う。どんなパラメータを設定すればいいのか、かなり分かりづらいので、まず通常に描画される設定である以下の設定からはじめるとよい。
    gfx_deltablit(img, 0, 0, w, h, 0, 0, 1, 0, 0,1, 0, 0);
  • gfx_xformblit( srcIndex, x, y, w, h, vW, vH, table [, wantAlpha=0] )
    画像を横方向・縦方向に分割し、その分割位置での画像参照位置をテーブルで指定する。言葉で説明すると難しそうですが、3DCGの知識がある人は平面の頂点にUVを張り付けるイメージでとらえれば分かりやすい。
    vW, vHは横方向・縦方向の頂点数(画像が矩形なので、必ずそれぞれ2以上が必要)を表し、この個数分だけ画像参照位置(いわゆるテクスチャUV。値域は[0,1])を用意します。つまりテーブルの要素数は vW * vH * (頂点情報数) 。頂点情報数は通常はUV座標なので2ですが、wantAlpha=1の場合はUVとα値で3になります。
  • gfx_keyedblit( img [, x, y, w, h, srcX, srcY, kv1, kv2, kv3, kv4] )
    カラーを指定して特定の色を透過させつつ画像を描画。要するにクロマキー合成を行うのに利用できる。k1~k4の指定はcolorspace毎に意味が異なるので注意。クロマキー合成の方法についてはこちらの記事を参照。
    • YV12・YUY2
      kv1:U(default: -0.5)、kv2:V(default: -0.5)、kv3:許容範囲値(Clossness-Factor、default: 0.4)、kv4:ゲイン(default: 2.0)
    • RGBA
      kv1:GreenFactor(default:1)、kv2:BlueFactor(default: -1)、kv3:オフセット(default: -1)、kv4:色が漏れ出し(オーバーフロー?)たら削除(default: 1)
  • gfx_destkeyedblit( img [, x, y, w, h, srcX, srcY, kv1, kv2, kv3, kv4] )
    描画先のピクセルカラー値を参照して、キーカラーに該当する部分にこれから描画する画像を描画します。パラメータはgfx_keyedblit()と同様。つまりkv1~kv4を省略すると、デフォルトでは緑っぽいところにだけ画像が描画されることになります。
    gfx_blit( imgBG ); // 背景側の描画
    gfx_destkeyedblit( imgFG, 0, 0, w, h ); // imgBGの緑色部分にだけ画像を描画
    

文字列描画関連

文字列を描画するための関数があります。文字列の幅も取得できるので、意外と便利。
  • gfx_setfont( pxSize [, #fontname, flags] )
    フォントや書式の指定
    • pxSize:フォントサイズ
    • #fontname:フォント名(日本語指定は不可。英文名で指定)
    • flags:Bold:'B'、Italic:'I'、複合指定は 'BI' のようにする。文字列ではなくシングルクォートで囲った値にする。
  • gfx_str_measure( #string [, w, h] )
    文字列を描画した場合のサイズを取得。戻り値には幅(w)が返る。幅と高さを取得したい場合はw, hに変数を指定してやれば取得できる。
  • gfx_str_draw( #string [, x, y, r, g, b] )
    文字列を指定位置に描画する。r, g, bで色を指定出来るようですが、指定しても変化がありませんでした(バグかも?)

その他の関数など

いくつか値の変換関数などが用意されています。
  • rgb2yuv( r, g, b )
    r, g, bをy, u, vに変換(結果は引数に上書きされる)。[0, 1]の範囲へのクランプは行われません。
  • yuv2rgb( y, u, v )
    y, u, vをr, g, bに変換(結果は引数に上書きされる)。[0, 1]の範囲へのクランプは行われません。


REAPERで動画編集 (11) : VideoProcessor : 画像を作ったVPのパラメータを受け取る

前回だいぶ面倒なところの説明を終えたので、さらに応用編という感じでいってみましょう。

画像を生成したVPのパラメータ取得について

再生カーソルのタイミングで存在する動画とVoiceProcessor(以下VP)はそれぞれ画像を生成していて、VPのAPIでそれらの画像にアクセス出来ることは前回説明しました。

画像の幅などの情報は input_info() というAPIを使って取得するのですが、このAPIに渡す画像を生成したVPのパラメータ値を取得することも可能になっています。
// 画像の生成に使われたVPのパラメータ1, 2も取得する例
isOK = input_info( img, w, h, srctime, wet, param1, param2 );
  • img: 情報を取得したい画像のハンドルを渡す
  • w: 画像の幅を取得
  • h: 画像の高さを取得
  • srctime: ItemのSourceメディアにおける再生時刻(Item最初からの再生時刻ではなく、Source内の時刻)を取得
  • wet: VPのFX Wet値(Itemクロスフェード具合も考慮)を取得
  • param1:imgを生成したVPのパラメータ1を取得
  • param2:imgを生成したVPのパラメータ2を取得
ここではparam1~2までを取得していますが、必要なだけ引数を続ければこれより後ろも取れるようです。とはいえ、VPのパラメータを取得できたからといって何が嬉しいんでしょうか。

もし他のVPのパラメータも参照できるのであれば、VP間でパラメータを連動させたり出来ます。1つのVPだけでは可変パラメータが足りなくても複数のVPで構築が可能になったり、パラメータモジュレーションなども出来たりと、アイデア次第でいろいろ出来そうな気がしてきます。

とはいえ実際のところ、この input_info() を呼び出している側は相手のVPがどんな効果を実装しているのか、パラメータが一体何なのか、などといった情報を一切知ることは出来ません。VPは全て単なるスクリプトなので、VPで実装しているエフェクトのタイプといったものも存在しませんし、単純にパラメータの値を取れるというだけです。

こういう場合は、ある画像のためのVP(パラメータ送信側)とこのパラメータを取得する側のVP(パラメータ受信側)をうまくつながるように手動で合わせてやれば、意図したパラメータを送受信可能です。これを実現するには、自分で決まりを作って、それに沿ってパラメータが受け渡されるようにVPを挿入してプログラムを書くといった比較的高度な技量が要求されます(要するに自分で設計しないといけない)。

自分の書いているVPがどの位置関係にいるVPの画像を使用するかを正確に把握し、そのVPのパラメータセットも自分で構築しないといけません。この時どの画像を利用するのか正確に把握する必要がありますが、前回の記事に書いたような画像管理について理解していれば難しくはありません。

パラメータ送受信のやり方の例

ここではパラメータ送受信の大まかなやり方を説明します。
やるべきことは以下の通り。
  • 送信したいパラメータを並べたVPを実装。パラメータ以外は gfx_blit( 0 ); とだけ書いておけば、ひとまず問題ないかと。これを送信側VPと呼ぶことにします。
  • 送信側VPはItemFXやTrackFXの最後尾に配置。ここに置かないとVPのAPIで辿れません。
  • 受信側VPを作成。これは必ず送信側VPより上側のトラックにないといけません。送信側VPの画像を取得し、その画像から input_info() でパラメータを取得するようなコードを実装。
これで送信側VP、受信側VPが繋がるはずなので、パラメータ送受信が出来るはずです。

受信側VPから画像を取得する際に気を付ける必要がある点は、TrackFXにVPがあると、そのトラックが生成する最終画像はItem側ではなくTrackFX側のVPの画像である点です。Item単位で送信するパラメータを変えたいなどといった場合は、input_next_item()などのAPIを駆使して正確にそのItemのVPの画像を指定するようにして下さい。

実装例を見てみる

・・・ハイ、言葉で説明するより実装を見た方が早いですね。

まずは送信側VPスクリプト。
VP_SendRec01
送信用パラメータを1つ実装しました。名前はprm1にしてますが何でも構いません。

受信側のVPスクリプトはこんな感じにしました。
VP_SendRec02
色のついた半透明の矩形を動画の上に描画するだけです。
色のRチャンネルに受信したパラメータを使っていますので、これによって色が変わります。

で、動画とVPをセットしたのが以下のような感じ。
VP_SendRec03
動画のItem 1, 2がありますが、Item1ではprm1=1、Item2ではprm1=0に設定しています。
今は再生カーソルがItem1に重なっているのでprm1=1ですが、次の画像だとItem2に重なっているためprm1=0になり、矩形の色が変わります。
VP_SendRec04

動画にするとこんな感じ。
VPSendRec

何やら説明の段階では難しそうな印象だったかもしれませんが、やってみると簡単ですね。

まぁでも正直に言うとここまでやる機会は少ないかもしれません。どうしても複数のVPを連携させたいという場合の切り札という感じでしょうか。それにしてもこういった自由度の高い機能を用意してくれているというのはありがたいですね。

このブログについて
ぺろりがREAPERで遊びたいというだけのブログかもしれない

必ずこちらをお読みください

twitter: @pelori

管理人用
  • ライブドアブログ