WPF で動画に文字や図形を合成して再生する方法

C# 動画プログラミングの 1 つです。

WPF の MediaElement や MediaPlayer で動画を再生する方法を紹介したページはいくつか見たのですが、通常再生のみが紹介されており、加工しながらの再生について言及されているページが見当たらなかったので、ここにまとめてみます。

目次


やりたいこと

overlay2動画再生時に、再生している動画の映像に、テキスト等を重ねます。

例として、映像の左上に灰色の長方形を描き、フレームレートや動画再生位置(秒数)といった文字を重ねてみます。

サンプルコード

GitHub にアップしてありますので、そちらからダウンロードしてください。

動作環境については GitHub リポジトリ内のヘルプファイルを参照して下さい。

実装の基本方針

WPF には、(動画に限らず)表示の更新を行うタイミング(つまりフレームごと)で発生するイベントがあり、それが CompositionTarget.Rendering イベントです。

このイベント内で再生中の動画をキャプチャした上で、テキスト等を書き込んでいく、というのが基本的な考え方です。

プログラムの大まかな動作としては、ドラッグ&ドロップされた動画を再生(もちろん音声も)しつつ、上記の方法で映像にテキスト等を重ねています。

プログラムの解説

MainWindow.xaml.cs の解説です。

ファイルをドロップされた際に発生するイベント Window_Drop() において、動画の再生 Play() と、重ね合わせの準備 PrepareOverlay() を行っています。

Play() は単純に、ドロップされたファイルを MediaPlayer で再生しているだけです。

今回の 1 つのポイントは PrepareOverlay() で、ここでフレーム描画イベントハンドラー CompositionTarget.Rendering の設定を行っています。

ここで設定されたイベントハンドラーは WPF での描画が必要なタイミングで常に呼びだされるため、仮に動画が再生されていなくても定期的に呼びだされます。呼びだされる頻度は環境によって異なるとのことで、私の環境では通常 60 fps 程度で呼びだされていますが、100 fps 程度に上がることもあります。あくまでも「WPF 描画のフレームレート」であって、動画のフレームレートではないことに留意してください。

イベントハンドラーとして設定された CompositionTargetRendering() の後半部分で合成を行っています。

DrawingVisual の DrawingContext に対して、動画、図形(背景の灰色四角形)、テキスト(フレームレートや再生位置)を書き込み、最後にそれらを表示用のビットマップ(mBmp)に書き込みます。

ImagemBmp は PrepareOverlay() で Image コントロールのソースに指定されているため、mBmp の内容がユーザーの目に見える形で表示されることになります。

WPF で動画を扱うメリット

WPF で動画を扱うメリットは、なんといっても手軽なことです。

加工しない再生だけなら MediaElement コントロール 1 つで簡単に動画を再生できますし、加工しても今回のサンプルコードのようにわずかなコード量で実現できます。

標準の C# 開発環境のみで実現できるため、追加のサードパーティーライブラリを用意したり、それをユーザーにインストールしてもらう(または一緒に配布する)という手間もありません。

GPULoadGPU ハードウェア支援が使える場合は、自動的に活用してくれているようです。

また、詳しくは未検証ですが、インストールされているコーデックライブラリ(K-Lite 等)も WPF 側で自動的に利用してくれているようで、扱える動画の形式も無限に広がっていきます。

WPF で動画を扱うデメリット

WPF で動画を扱うデメリットは、(動画の)フレームを厳密に扱えないのではないかということです(扱える方法をご存じの方は教えてください)。

まず、根本的な課題として、動画のフレームレートが取得できません。動画の縦横サイズ等はプロパティーで取得できるのですが、フレームレートを取得するプロパティーはありません。

また、WPF で動きのあるものを処理する際はアニメーションという仕組み(Animatable クラスないしは IAnimatable インターフェース)に則っており、動画(MediaElement / MediaPlayer)も例外ではありませんが、動きの管理が時間単位で行われています。

何らかの方法で動画のフレームレートを取得できたとしても、厳密な意味でのフレーム送りはできず、1 フレームは○○ミリ秒だから○○ミリ秒進める、というような形でのフレーム送りになるのではないかと思います(この辺りは未検証ですが)。30 fps だと 1 フレーム当たり 33.3333.... ミリ秒ですが、小数点の丸めによって微妙に進まない(または 2 フレーム進んでしまう)瞬間が発生したり、そもそも可変フレームレートだとどうしようもないのではないかと思います。

スクリーンショットの動画

このページ冒頭のスクリーンショットに映っている動画は、ダブルレンさんの「お願い☆EternalSummer!」という曲です。素敵な曲なので、是非聴いてみて下さい!


歌いたい時はニコカラバージョンでどうぞ。








ニコカラ動画のオンボとオフボを簡単に結合するツール おすそ分け

ニコカラ動画(カラオケ字幕動画)のオンボーカル動画とオフボーカル動画を結合し、1 つの mp4 動画ファイルに「字幕映像+オンボーカル音源+オフボーカル音源」をまとめるためには、こちらの記事にあるように Yamb で様々な入力をしていく必要がありますが、ファイルドロップだけで手軽に結合するツールを自分用に作りましたので、おすそ分けします。

※縮小表示されている画像は、クリックすると元のサイズで表示されます。

目次

ツールの概要

オンボとオフボを手軽に結合してマルチトラック化するツールです。

元の動画をドラッグ&ドロップするだけで、トラック名の設定やトラックの言語設定も自動で行います。

Yamb で作成するより手間を削減できます。一方で、複雑な結合はできませんので、その場合はこれまで通り Yamb をお使い下さい。

インストール

ニコカラ動画のオンボとオフボを簡単に結合するツールは、ダウンロード先からダウンロードして zip を解凍します。

ニコカラ動画のオンボとオフボを簡単に結合するツールの動作には MP4Box が必要です。MP4Box はこちらのサイトから GPAC の最新インストーラー(2019 年 10 月現在、32 ビット Windows 用は gpac-0.8.0-rev1-gc1990d5c-master-win32.exe、64 ビット Windows 用は gpac-0.8.0-rev1-gc1990d5c-master-x64.exe)をダウンロードします。exe を実行し、指示に従って GPAC をインストールすると、インストールしたフォルダーに MP4Box.exe ができるので、ニコカラ動画のオンボとオフボを簡単に結合するツール(MergeNicoKaraTracks.exe)と同じフォルダーに MP4Box.exe をコピーします。

簡単な使い方

Mnkt1ツールを起動すると、ウィンドウ上部に案内が表示されるので、案内に従って作業を進めていきます。

Mnkt2エクスプローラーからオンボ動画(映像+オンボ音声)または元の PV 動画(オンボ音声のもの)をドラッグ&ドロップします。オンボーカル行(トラックが On の行)にドロップした動画が入ります。

(補足)
PV 動画とオンボニコカラ動画の 2 つがある場合、可能であれば PV 動画を使う方が良いです。オンボニコカラ動画の音声部分は PV 動画の再エンコのため、音質が下がっていることが多いです。
Mnkt3次に、オフボ動画(映像+オフボ音声)もドラッグ&ドロップします。オフボーカル行(トラックが Off の行)にドロップした動画が入ります。

「出力開始」ボタンが水色に光りますので、クリックすると、マルチトラック結合動画が出力されます。

デフォルトでは、「オフボ動画の映像+オンボ音源+オフボ音源」が結合され、オフボ動画と同じフォルダーに結合動画が出力されます。デフォルトで映像をオフボのものにしているのは、オンボとして(字幕のない)元の PV を指定することを想定しているためです。

動画内のトラック名(On Vocal / Off Vocal)や言語設定(オンボ音源は Japanese)は自動的に設定されています。

以上、2 つのファイルのドロップだけで手軽に結合が完了しました。

高度な使い方

このツールでは、オンボ 2 つ+オフボ 2 つの合計 4 トラックまで結合できます。

Mnkt42 つめのオンボや 2 つめのオフボを指定したい場合は、「On-2」「Off-2」行の参照ボタンをクリックして動画を指定します。ドラッグ&ドロップの場合は、「On-2」→「Off-2」の順に動画が追加されていきます。

Langオンボやオフボが 2 つあると動画再生時のトラック選択で見分けがつきづらいので、「トラック名追加」欄に追加情報を入力して見分けやすくすると良いでしょう。例えば、「トラック名追加」欄に「初音ミク版」と入れると、生成されるトラック名が「On Vocal (初音ミク版)」のようになります。

(補足)
最新版の MP4Box を使っていれば基本的に問題ありませんが、環境によっては、トラック名に日本語を使うと問題が発生するかもしれません。その場合は、入力する文字を英数字にして下さい。
デフォルトのトラック名を「On Vocal」のように英字にしているのはそのリスクを避けるためです。

ダウンロード

本ツールのダウンロードは、こちらのリンク先の中から、「MergeNicoKaraTracksXXX.zip」を探してダウンロードして下さい。

補足

本ツールは開発者自身が使用するために開発したものをおすそ分けという形で公開はしておりますが、今後バージョンアップの予定はありません。

また、機能アップなどのリクエストは受け付けておりません。

完全に as-is(あるがまま)となります。

1 つの mp4 動画に複数の音声トラックを結合する方法

便利なマルチトラック動画(複数の音声トラックを持つ動画)の作り方についてまとめました。

縮小表示されている画像は、クリックすると元のサイズで表示されます。

目次

マルチトラックのメリット

ニコカラ(カラオケ字幕動画)を例にすると、同じ曲でも「オンボーカル(オンボ):元の音声付き楽曲」「オフボーカル(オフボ):カラオケ音源」の 2 つの動画があります。

オンボとオフボを別々の動画にしておくと、それぞれの動画に「映像+音声」がありますが、映像(字幕)はどちらも同じなのでディスク容量の無駄になります。1 つの動画に「映像+オンボ音声+オフボ音声」を同居させるマルチトラック動画にすれば、映像 1 つ分のディスク容量が節約できます。

例えば、映像のビットレートが 2 Mbps の 5 分間の動画の場合、75 MB の容量を節約できます。

また、マルチトラック動画にすると、再生中にオンボとオフボを切り替えられるのも大きなメリットです。

必要なツール

マルチトラック動画の作成に必要なツールは、Yamb と MP4Box の 2 つです。私たちは Yamb を使い、Yamb が MP4Box を使います。

Yamb はこちらのサイトから最新の zip 版(2019 年 10 月現在は Yamb-2.1.0.0_beta2.zip)をダウンロードします。PC の好きなフォルダーに zip を解凍しておきます。

MP4Box はこちらのサイトから GPAC の最新インストーラー(2019 年 10 月現在、32 ビット Windows 用は gpac-0.8.0-rev1-gc1990d5c-master-win32.exe、64 ビット Windows 用は gpac-0.8.0-rev1-gc1990d5c-master-x64.exe)をダウンロードします。exe を実行し、指示に従って GPAC をインストールすると、インストールしたフォルダーに MP4Box.exe が入ります。

Yamb の設定

YambYamb が MP4Box を使えるように設定します。

Yamb を起動し、左側のアイコンから「Settings」をクリック、右側の「Advanced Settings~」をダブルクリックします。

Yamb2Advanced Settings 画面になるので、左側から「MP4Box」をクリックし、Location のフォルダーアイコンをクリックして、前章でインストールした GPAC に含まれている MP4Box.exe の場所を指定します。

指定を終えたら「Next」をクリックして設定完了です。

結合作業

マルチトラック動画を作るために、映像や音声を結合します。

Yamb3Yamb を起動し、左側のアイコンから「Editing」をクリック、右側の「Click to join~」をダブルクリックします。

「Concatenation of Files」の画面になるので、エクスプローラーからオンボ動画(映像+オンボ音声)または元の PV 動画(オンボ音声のもの)をドラッグ&ドロップします。

(補足)
PV 動画とオンボニコカラ動画の 2 つがある場合、可能であれば PV 動画を使う方が良いです。オンボニコカラ動画の音声部分は PV 動画の再エンコのため、音質が下がっていることが多いです。
その後、オフボ動画(映像+オフボ音声)もドラッグ&ドロップします。

Yamb4aドロップした動画のトラックが一覧表示されます。通常は上から順に、PV(オンボ)の映像、PV(オンボ)の音声、オフボの映像、オフボの音声、となります。

一番上、PV(オンボ)の映像は不要なので、チェックを外します。

Yamb5上から 2 番目、PV(オンボ)の音声トラックをクリックして選択してから、右側の「Properties」ボタンをクリックすると、音声トラックの情報を設定する Properties ウィンドウが開きます。

「Language」は必須ではありませんが、「Japanese」を選択すると良いでしょう。また、「Track Name」に「On Vocal」と入力します(日本語ではなく英語で入力するほうがトラブルが少ないです)。

Ok ボタンをクリックすると Concatenation of Files ウィンドウに戻ります。

Yamb6同じように、一番下、オフボの音声トラックをクリックしてから Properties ウィンドウを開きます。

オフボの場合は言語は関係ありませんから、「Language」はデフォルトのまま「Unspecified」で良いでしょう。「Track Name」に「Off Vocal」と入力して Ok します。

Concatenation of Files ウィンドウに戻ったら、「Output」に出力動画ファイル名を入力します(デフォルトではドロップした動画のファイル名になっていますので、変更しないと上書きされてしまいます)。

ファイル名は、オンボとオフボの両方が含まれることが分かるように付けると良いでしょう。

例)
楽曲名_歌手名(On-Off).mp4
千本桜_初音ミク(On-Off).mp4

Yamb7これまでの作業内容をまとめると右の図のようになります。

すべての入力を終えたら、「Next」ボタンをクリックします。マルチトラック動画が生成されます。

再生

【Windows Media Player での再生】

マルチトラック動画は、通常の動画と同じように Windows Media Player で再生できます。

音声を切り替えたい場合は、ウィンドウ右上にある「ライブラリに切り替え」ボタン(LibChange)をクリックします。

WMPMenu画面が切り替わり、メニューバーが表示されるので(メニューバーが非表示になっている場合は、ウィンドウタイトルバーの少し下を右クリックするとメニューが表示されます)、メニューから[再生→オーディオおよび言語トラック→再生したい音声トラック]をクリックすると音声が切り替わります。

【MPC-HC / MPC-BE での再生】

Windows Media Player で音声を切り替えるのは手順が多く面倒なので、MPC-HC または MPC-BE で動画を再生するほうが簡単です。

これらのプレーヤーの場合、動画再生中に「A」キーを押すことで音声を切り替えられます。

MPCMenuメニューから切り替える場合は、[再生→音声トラック→再生したい音声トラック]です。メニューに「On Vocal」など Yamb で設定したトラック名が表示されるので分かりやすいです。


カラオケ動画のタイムタグ打ちのコツ

カラオケ動画(ニコカラ)を作る際、より歌いやすい字幕にするための、タイムタグの打ち方のコツをまとめました。丁寧にタイムタグを打つための Tips 集で、どちらかといえば上級者向けです。使用するツールは RhythmicaLyricsニコカラメーカーを前提としています。

(補足)
そもそものカラオケ動画の作り方については、こちらの記事をご覧ください。

目次

チェックの間引き(同じリズム)

同じリズムRhythmicaLyrics は基本的に、すべての歌詞の文字にチェック(タイムタグを打つ位置を示す白い三角)を入れてくれています。

しかし、同じ長さの音符が続くところ(同じリズムのところ)は、チェックを外した方が歌詞のワイプが滑らかになります。

右の図で、「オトメ」はそれぞれ 8 分音符、「は目」はそれぞれ 4 分音符です。その場合、音符の長さの境目の「オ」と「は」にだけ、チェックを入れるようにします。

すべての文字にチェックを入れてタイムタグを打つと、人間の作業ですから、どうしてもタイムタグ間隔に多少のズレが生じてしまい、ワイプする時に速度が速くなったり遅くなったりして歌いづらくなってしまいます。

チェックを間引いておくと、その間のワイプはニコカラメーカーが自動的に均一の速度にしてくれますので、滑らかで歌いやすい字幕ワイプになります。

チェックの間引き(アクセントの無い母音)

あいまい母音母音(あいうえお)のうち、強調して発音されない母音(母音にアクセントが乗っていない場合)も、チェックを外した方が歌詞のワイプが滑らかになります。

右の図で、「い」は単独で明確に発音するものではなく、直前の「な」とセットになって「ない」として一括りで発音されます。その場合は、「い」のチェックを外します。

アクセントの無い母音である「い」がどのタイミングで始まるのか明確ではないので、「い」にチェックをいれてタイミングを意識させるよりは、「ない」セットで均等にワイプするほうが自然に感じられます。

ただし、同じ歌詞であっても、母音にアクセントがあるかどうかはメロディーによって変わってきます。母音単独で明確に発音される状況ならば、チェックを残すようにします。

チェックの間引き(行末)

行末歌詞の行末と、次の行の先頭がタイミング的にすぐの場合は、行末のチェックを外すと、行末と次の行頭のタイムタグが一致して滑らかに次の行に遷移する感覚になります。

一方、行末で一呼吸入れてから次の行に行くようなタイミングの場合は、行末にしっかりとチェックを入れておく方がメリハリのあるワイプになります。

(補足)
RhythmicaLyrics の[ツール→設定]メニューにて、自動チェック→チェックの付け方で「キーアップチェック」がデフォルトで ON になっていますが、この Tisp のように行末にチェックを付けたり付けなかったりする手法を使う場合には、「キーアップチェック」を OFF にしておくほうがやりやすいと思います。

全体のワイプタイミング一括調整

RhythmicaLyrics には、[ツール→設定]メニューから、時間→タイムタグ打ち込みの「タイムタグ打ち込み時にずらす時間」設定で、自分がスペースキーを押したタイミングと打ち込まれるタイムタグの時刻を一定時間ずらせる便利なタイミング調整機能が備わっています。この機能のおかげで、「タイミング良くスペースキーを押しているのに、実際の字幕ワイプが微妙に遅いなぁ」と感じたら、この数値をマイナス方向に調整してからタイムタグを打つことで、ぴったりの字幕ワイプを実現できます。

しかしこの数値を設定してある環境でも、曲自体のテンポや、あるいは自分の体調等によって、普段より字幕ワイプタイミングが全体的に遅かったり早かったりする場合があります。

AtOffsetそのような場合は、@Offset タグを使うことにより、全体のワイプタイミングを「事後」に調整できます。

[ツール→@ タグオプション]メニューをクリックし、「その他の @ タグ」の欄に、「@Offset=-100」のような形式で @Offset タグを入力します。

単位はミリ秒です。マイナスの場合はワイプタイミングが早くなり、符号無し(プラス)の場合はワイプタイミングが遅くなります。

@ タグを入力しても、RhythmicaLyrics 上ではタイミングの変更は反映されません。[ファイル→出力→ルビ拡張規格でタイムタグ出力→実行]メニューで歌詞ファイルを出力し、ニコカラメーカーに読み込ませると、ニコカラメーカーがタイミングを調整します。

(補足)
RhythmicaLyrics は Ver 5.2 現在、@ タグを入力・変更しただけではドキュメントが更新されたと見なされず、@ タグ入力直前に保存をしていると、上書き保存ができない状態になっています。
ダミーのワイプタイミングの白い三角を一時的に挿入→削除するなどして、更新状態にしてから上書き保存しましょう。

行頭だけワイプタイミングを早める

歌詞のワイプタイミングは、「ぴったり」ないしは「ほんの気持ち早めのワイプ」が歌いやすいですが、行頭に限っては、それよりも少し「早め」にワイプを始めると歌いやすくなります。

特に歌い慣れていない曲の場合、歌い出しのタイミングが分からず、歌詞のワイプが始まるのを見て「あっ」と思って歌い始める場合がありますが、行頭が「ぴったり」ワイプすると、歌い手がワイプを認識して発声する頃にはタイミングが遅れています。行頭を「早め」にワイプすることにより、歌い手が歌うタイミングと実際の楽曲のタイミングが合わせられるようになります。

行頭以外は、歌い手も正規のタイミングが掴めている状態なので、「早め」だとタイミングが狂ってしまいますので、「ぴったり」(ないしは「ほんの気持ち早め」)のほうが歌いやすいです。

AtHeadOffset行頭だけタイミングを早めるには、@HeadOffset タグを使います。

[ツール→@ タグオプション]メニューをクリックし、「その他の @ タグ」の欄に、「@HeadOffset=-100」のような形式で @HeadOffset タグを入力します。

単位はミリ秒で、マイナスの数値を入れることにより行頭のワイプタイミングが早くなります。

楽曲のテンポや好みにもよりますが、-100~-120 程度が歌いやすい場合が多いのではないでしょうか。

直前の行の行末のタイムタグが無い場合は、行末のワイプタイミングも @HeadOffset に合わせて早められます。@HeadOffset であまりにもタイミングを早めてしまうと、直前行末が一瞬でワイプするなどの弊害が出ますので注意して下さい。

@HeadOffset タグも @Offset タグ同様、RhythmicaLyrics 上ではタイミングは反映されず、ニコカラメーカーでタイミングが反映されます。

マシンベンチマークまとめ(メインマシン:Radiant 3700X)

新しい Ryzen 7 3700X マシン(詳細スペックはこちら)のストレージ性能を CrystalDiskMark で見てみた。

C ドライブ(NVMe SSD)

Western Digital WD BlackWD Black SN750 WDS500G3X0C は NVMe SSD の中でも比較的高速な部類の SSD で、CrystalDiskMark の成績も良い。

シーケンシャルリード 3475MB/s とカタログスペック(3470MB/s)通りの性能が出ている。

シーケンシャルライトは 2585MB/s とカタログスペック(2600MB/s)に僅かに及ばないが十分な性能。

ランダムリードは 50MB/s 越え。

ランダムライトはなんと 200MB/s 越えで、HDD のシーケンシャルライトより速いのではないか。

D ドライブ(SATA SSD No.1)

Micron12TB では激安の Micron 1300 MTFDDAK2T0TDL-1AW1ZABYY。他のが少なくとも 25,000 円以上する中で、これだけ 20,000 円で買える。

SATA SSD としては十分な性能(というか SATA 規格の限界でこれ以上の性能が出ない)で、シーケンシャルリード・シーケンシャルライト共に 530MB/s 越え。カタログスペックは 530MB/s と 520MB/s なので、シーケンシャルライトはカタログスペックを上回っている。

ランダムリードは約 40MB/s と、SATA SSD としては最速クラスではないだろうか。

E ドライブ(SATA SSD No.2)

Micron2同じく Micron 1300。

当然ながら、性能は D ドライブと同等。

当初はシーケンシャルリードが約 400MB/s と微妙に遅かったが、これはどうやら SATA ケーブルが古かったのが悪さをしていたようだ。新しいケーブルと交換したことで、本来の性能を発揮できるようになった。

F ドライブ(外付け HDD)

WD_HDD_7USB 3.0 接続の外付け RAID HDD ユニット、Western Digital My Book Duo WDBLWE0080JCH-JESN。


HDD ということで途端に性能が悪くなっている。加えて、4 年越しの使い古し品であることも悪条件。


新品の時に測定したデータと比べると、シーケンシャルは約 2/3、ランダムは約半分に性能が落ち込んでいる。


ポータブル 2.5 インチ HDD

WD_HDD_PortableUSB 3.0 接続のポータブル外付け 2.5 インチ HDD、Western Digital My Passport。

2.5 インチなのでさらに性能が低い。

補足

ウィルス対策ソフトはインストールしただけでもストレージ性能下がるかなと思っていたが、実際はそうでもなかった。

インストール前と、インストール後に保護停止にした状態でそれぞれ SSD の性能を測定したが、有意な差は見られなかった。

なお、ウィルス対策ソフトは Kaspersky を使用している。
カウンター


カンパのお願い
Amazon でお買い物の際は、下記で検索して頂けたら幸いです。
記事検索
最新コメント
  • ライブドアブログ