動画拡張に関する基本的な情報
複数動画拡張時の制限
Androidでは、同時にインスタンス化できる動画拡張オブジェクトの数に制限があります。動画拡張オブジェクトが作成されるたびにそのオブジェクト用のMediaPlayerが作成され、メモリが割り当てられます。したがって、同時に4つ以上の動画拡張オブジェクトを作成することはできません。
デバイスに応じて適切なモードが自動的に検出されます。
サポートされている動画コーデックとホスティングサービス
すべてのプラットフォームをサポートするには、H.264でエンコードされた最大解像度720p(1280x720ピクセル)の動画を使用してください。
H.264ではいくつかのプロファイルが定義されています。必ず以下のいずれかを使用してください。
- ベースライン
- 拡張
- メイン
Androidデバイスでプロファイルの異なるビデオを再生すると、間違いなく誤動作が起こります(再生できないか、完全にクラッシュします)。
動画ホスティングサービスからのURLはH.264エンコードされた動画を直接指している必要があります。この理由のため、標準的なYouTubeやVimeoのURL(http://www.youtube.com/watch?v=bX98XNv8VL4のような形式)は機能しません。
YouTubeに動画をアップロードし、それをデバイスで全画面再生する場合は、ポスターや再生ボタンをなどを拡張するAR.ImageDrawable
を使用するのではなく、YouTube動画のURLをonClick
トリガーに追加してください。同様のことをクライアント認識サンプルで行っています。
基本的な動画の拡張方法
対応するサンプルタイトル名「Simple Video」
Wikitude SDKでは、画像、テキスト、HTMLコンテンツに加えて動画も拡張することができます。AR.VideoDrawable
を、AR.ImageTrackable
を使用した画像認識型AR、または、AR.GeoObject
を使用したロケーションベース型ARの両方で拡張できます。他の拡張オブジェクトと同様に、配置、スケーリング、回転、不透明度を変更できます。
サンプルの確認には、このページにある画像を使用できます。
以下のサンプルは、基本的な動画の拡張方法と、再生の制御方法、動画拡張オブジェクトの固定表示、透過動画の拡張方法について示します。
このサンプルで使用する動画は"video.mp4"です。すべてのリソースと同様に、動画はアプリケーションにバンドルされたローカルリソースからロードすることも、サーバーからリモートでロードすることもできます。このサンプルでは、動画はすでにアプリケーションにバンドルされています。
サンプルの確認には、このページにある画像を使用できます。
アプリケーションにバンドルされた動画へのURLを使用して、拡張オブジェクトを以下のように作成します。
// Create video drawable
var video = new AR.VideoDrawable("assets/video.mp4", 0.5, {
translate: {
x: 0.2,
y: 0.2
}
});
新しいAR.VideoDrawable
を作成するとき、URLとサイズは必須です。オプションで、translate.x
パラメーターとtranslate.y
パラメーターを使用してターゲット上での動画の配置を設定できます。オフセットの値はSDU単位です(SDUの概念の詳細についてはこのセクションを参照してください)。
動画をターゲットに拡張する方法は、他の拡張オブジェクトをターゲットに追加する方法とほとんど同じです。
var pageOne = new AR.ImageTrackable(this.tracker, "*", {
drawables: {
cam: [video]
},
onImageRecognized: function onImageRecognizedFn() {
if (this.hasVideoStarted) {
video.resume();
}
else {
this.hasVideoStarted = true;
video.play(-1);
}
World.removeLoadingBar();
},
onImageLost: function onImageLostFn() {
video.pause();
},
...
ターゲットが認識された後ただちに動画を再生するためには、onImageRecognized
トリガー内でplay
メソッドを呼び出します。play
メソッドに-1
を指定すると、動画が無限にループ再生されます。正の数を指定すると、その回数だけ再生が繰り返されます。
ターゲット名としてワイルドカード*
を使用していることに注意してください。これは、指定したターゲットコレクションに含まれるすべてのターゲットがマッチングされることを示します。
動画再生の制御方法
対応するサンプルタイトル名「Playback States」
AR.VideoDrawable
クラスには、動画再生を制御するために関数とトリガーが用意されています。以下のサンプルでは、関数とトリガーを使用してターゲットの前面に再生ボタンの画像を表示しています。ユーザーが再生ボタンをクリックすると、動画の再生が始まります。また、カメラビューからターゲットが外れたときに動画を見逃さないようにするため、動画を一時停止し、再度カメラビューに入ったときに動画を再開します。
サンプルの確認には、このページにある画像を使用できます。
// Create video drawable
var video = new AR.VideoDrawable("assets/video.mp4", 0.5, {
translate: {
x: 0.2,
y: 0.2
},
onLoaded: function videoLoaded() {
playButton.enabled = true;
},
onPlaybackStarted: function videoPlaying () {
playButton.enabled = false;
video.enabled = true;
},
onFinishedPlaying: function videoFinished () {
playButton.enabled = true;
video.playing = false;
video.enabled = false;
},
onClick: function videoClicked () {
if (video.playing) {
video.pause();
video.playing = false;
playButton.enabled = true;
} else {
video.resume();
video.playing = true;
playButton.enabled = true;
}
}
});
すでに述べたように、動画はtranslate.x
プロパティとtranslate.y
プロパティを使用してターゲット上に配置されています。また、onLoaded
、onPlaybackStarted
、onFinishedPlaying
の各トリガーに関数が割り当てられています。onLoaded
トリガーは動画の再生準備ができたときに1回発生し、playButton
を有効にします。playButton
はAR.ImageDrawable
で、以下のように定義されています。
// Create play button
var playButtonImg = new AR.ImageResource("assets/playButton.png");
var playButton = new AR.ImageDrawable(playButtonImg, 0.2, {
enabled: false,
onClick: function playButtonClicked() {
video.play(1);
video.playing = true;
},
translate: {
x: video.translate.x,
y: video.translate.y
}
});
ユーザーが再生ボタンをクリックすると、動画が1回再生されます(video.play(1)
)。再生が始まるとonPlaybackStarted
トリガーが発生し、このサンプルではplayButton
が非表示になります。再生が終わるとonFinishedPlaying
トリガーが呼び出され、playButton
が再び表示されます。
ユーザーが動画を一時停止できるようにするため、AR.VideoDrawable
のonClickトリガーを使用しています。再生中にユーザーが動画をクリックした場合、pause()
関数が呼び出されて再生が一時停止します。もう一度動画をクリックすると再生が再開されます。
ユーザーが動画をクリックしたときと同様に、カメラビューからターゲットが外れたときに再生を一時停止し、再度カメラビューに入ったときに動画を再開します。これを実現するため、AR.ImageTrackable
のonImageRecognized
トリガーとonExitFieldOfVision
トリガーを使用しています。
var pageOne = new AR.c(this.tracker, "*", {
drawables: {
cam: [video, playButton]
},
onImageRecognized: function onImageRecognizedFn() {
if (video.playing) {
video.resume();
}
World.removeLoadingBar();
},
onImageLost: function onImageLostFn() {
if (video.playing) {
video.pause();
}
},
...
AR.VideoDrawable
の再生を制御する方法を示すサンプルはこれで終わりです。各関数とトリガーの詳細については、APIリファレンスを参照してください。
動画拡張オブジェクトの固定表示
対応するサンプルタイトル名「Snapping Video」
前のサンプルでは、カメラビューからターゲットが外れたときに動画を見逃さないようにするため、動画を一時停止し、再度カメラビューに入ったときに動画を再開しました。このサンプルではこのアプローチをもう少し前進させて、動画の再生を一時停止/再開する代わりに動画をカメラビューに固定表示させ、ターゲットがカメラビューから外れたときにも動画が引き続き再生されるようにします。これを可能にするため、 AR.ImageTrackable
にはいくつかのsnapToScreen
設定が用意されています。このサンプルでは、snapToScreen.enabledOnExitFieldOfVision
プロパティを使用して、onImageLost
イベントが発生したときにすべての拡張オブジェクトを自動的にカメラビューに固定表示します。ターゲットが再びカメラビューに入ったときに固定表示を無効にするため、onEnterFieldOfVision
イベントでsnapToScreen.enabled
プロパティをfalse
に設定します。これにより、すべての拡張オブジェクトが再びターゲット画像上に表示されます。
this.pageOne = new AR.ImageTrackable(this.tracker, "*", {
drawables: {
cam: [this.video, playButton]
},
onEnterFieldOfVision: function onEnterFieldOfVision() {
World.pageOne.snapToScreen.enabled = false;
},
snapToScreen: {
enabledOnExitFieldOfVision: true,
snapContainer: document.getElementById('snapContainer')
}
});
固定表示する位置はHTMLソースのdiv
要素によって定義します。div
のサイズと位置は、固定表示状態にあるすべての拡張オブジェクトに影響します。拡張オブジェクトが期待どおりに表示されるようにするには、縦向きと横向きの両方を考慮してdiv
を変更することが重要です。このサンプルでは、CSSを使用して、デバイスの向きに合わせてdiv
要素を変更しています。
透過動画の拡張方法
対応するサンプルタイトル名「Bonus: Transparent Video」
このサンプルは、透過動画を拡張する方法を示します。透過動画を拡張するには準備作業が必要です。
透過動画を使用するために必要なステップを以下に示します。
- グリーンバック動画を撮影します。
- 標準の動画処理ソフトウェアを使用して動画を編集し、グリーンバックを除去します。アルファチャネル情報を処理できるファイル形式(例: Apple PreRes 4444)に結果をエクスポートします。
- ダウンロードしたSDKファイルにあるToolsフォルダーのスクリプトを使用して、ステップ2でエクスポートした動画を変換します。
- 動画をターゲットに拡張します。
透過動画を作成するときは通常、撮影用のグリーンバックを使用します。これはクロマキーと呼ばれる手法で、緑の背景を透明に置き換えます。
動画のアルファチャネルをサポートするコーデックは複数存在し、それらのほとんどが素材として使用できます。Wikitude SDKの開発時にApple ProRes 4444コーデックのテストを広範に実施しましたが、結果は満足のいくものでした。
Wikitude SDKで拡張できるのはH.264でエンコードされた動画だけですが、このコーデックは実際にはアルファチャネルをサポートしていません。ここではその解決策として、アルファチャネルをビデオの別の可視部分に追加しています。最終的な動画はカラーチャネルとアルファチャネルが上下に配置され、これが縦に分割されます。
画像の上半分は動画のカラー情報を示し、下半分にはアルファレイヤのグレースケール表現が含まれます。白の領域は完全に不透明になり、黒の領域は完全に透明になります。Photoshopでいうと、下半分はマスクに相当します。動画は最終的には、高さが入力動画のちょうど2倍になります。
この動画をSDKで使用可能な動画に変換するため、動画を再エンコードし、アルファマスクを自動的に作成する必要があります。以下のスクリプトはffmpeg
を使用してこれを実行し、さらに必要なコマンドをラップしています。以下の手順に従ってください。
MacOS X
- ターミナルアプリケーションを開きます。
cd <SDK>/tools/video/MacOSX
と入力します。<SDK>
はSDKフォルダーのパスに置き換えてください。sh convert.sh <input video> <output video>
を実行します。<input video>
は透過動画のパスに置き換え、<output video>
は保存する出力動画のパスに置き換えてください。
Windows
- コマンドラインを開きます。
cd <SDK>\tools\video\Windows
と入力します。<SDK>
はSDKフォルダーのパスに置き換えてください。convert.bat <input video> <output video>
を実行します。<input video>
は透過動画のパスに置き換え、<output video>
は保存する出力動画のパスに置き換えてください。
これにより、カラーチャネルとアルファチャネルが上下に分割された動画が作成されます。
H.264にエンコードした透過動画をターゲットに拡張する方法は、他の動画を拡張する方法とほぼ同じです。ただし、AR.VideoDrawable
のisTransparent
プロパティをtrue
に設定します。
サンプルの確認には、このページにある画像を使用できます。
// Create a transparent video drawable
var video = new AR.VideoDrawable("assets/transparentVideo.mp4", 0.7, {
translate: {
x: -0.2,
y: -0.12
},
isTransparent: true
});