ADOBE® MEDIA SERVER 5.0.3
デベロッパーズガイド
![]() ![]() ![]() |
翻訳:株式会社サムライズ |
---|
注意
Adobe Media Server® バージョン 5についての本ドキュメントは第三者によって翻訳されたものであり、Adobe Systems Incorporated(アドビ システムズ社)は本翻訳物の正確性や完全性を査閲していません。
ライブビデオへのDVR機能の追加
Flash Media Server 3.5
注意:Adobe Media Server Standard は DVR 機能をサポートしていません。
DVR(デジタルビデオレコーダー)を使用すると、ビューアでライブビデオを一時停止したり、一時停止の地点から再生を再開したりすることができます。また、ビューアではライブイベントの巻き戻し、記録されたセクションの再生およびライブセクションの再検出も可能です。数行のコードを記入するだけで、ビデオ Playerを DVRのように動作させることができます。DVRアプリケーションの例には、即時再生および「追いかけ」サービスがあります。
注意:FLVPlayback コンポーネントのバージョン 2.5 では、DVR をサポートしています。このコンポーネントを、Adobe Media Server ツールからダウンロードします。
Flash Media Server 4.0、Flash Player 10.1
動的ストリーミングアプリケーションで DVRを使用するには、サーバーで絶対時間コードを有効にします。絶対時間コードにより DVR対応のマルチビットレートストリームはサーバーで同期し続けます。
エンコーダーは、絶対時間コードを使用する必要があります。Flash Media Live Encoder は、絶対時間コードをサポートしますが、Flash Player はサポートしません。サードパーティのエンコーダーも絶対時間コードを使用します。お手持ちのエンコーダーで絶対時間コードを有効にする方法については、エンコーダーのベンダーに問い合わせてください。
重要:ストリームは同期する必要がありますが、サーバーはストリームを同期しません。絶対時間コードは、エンコーダーの同期されているストリームを同期し続けるのに必要なすべての情報をサーバーに必ずキャプチャーさせます。
絶対時間コードの有効化
Application.xml 設定ファイル内の絶対時間コードをアプリケーションレベルで有効にします。有効になると、サーバーは、着信ライブストリームには、エンコーダーの入力ソース内に含まれる SMPTE 時間信号といった絶対時刻ベースのタイムスタンプがあるとみなします。デフォルト値は false です。
1 新しいテキストまたは XML ファイルを作成して、アプリケーションのフォルダー (「Application.xml」) に保存します。
注意:アプリケーションレベルの Application.xml ファイルの一例として、rootinstall/applications/vod/Application.xml をテキストエディターで開きます。
2 次を XML をファイルに追加します。
<Application>
<StreamManager>
<Live>
<AssumeAbsoluteTime>true</AssumeAbsoluteTime>
</Live>
</StreamManager>
</Application>
3 ファイルを保存します。
設定ファイルの操作の詳細については、「単一アプリケーションの設定」を参照してください。
動的ストリーミングでの DVR 向けストリームのパブリッシュと記録
DVRストリームを動的ストリーミングでパブリッシュして記録するには、appendWithGapを NetStream.publish()またはStream.record()メソッドに渡します。ストリームを appendWithGapモードでパブリッシュまたは記録するとき、記録されるストリームには、ストリームの停止および再開時に作成されたギャップが保持されます。appendモードでは、サーバーはギャップを除去するため、ストリームの同期が失われる可能性があります。ギャップは、エンコーダーがオフラインになってオンラインに戻るときに発生します。ギャップは、記録されたファイルの再生時にクライアントから表示可能です。
DVR ビデオ Player 用のストリームをクライアントからパブリッシュするには、次の例のように「record」フラグまたは「append」フラグを使用します。
NetStream.publish("myvideo", "record")
NetStream.publish("myvideo", "append")
DVR ビデオ Player 用のストリームをサーバーからパブリッシュするには、Stream.record() を呼び出します。 Stream.record() メソッドには、ストリームの最大長とファイルサイズが指定可能な maxDuration と maxSize の 2 つの新規パラメーターがあります。次のコードは、最大記録長 10 分(600 秒)およびファイルサイズ無制限でストリームをパブリッシュします。
Stream.record("record", 600, -1)
DVRビデオ Player用にパブリッシュされたストリームをクライアントが再生する場合、クライアントはライブストリームは再生せず、記録されたストリームを再生します。クライアントがストリームを「ライブ」で表示する場合、記録された直後に記録ストリームを実際に表示しています。
DVR ビデオ Player 用にパブリッシュされたストリームをサブスクライブするには、次のコードを使用します。 NetStream.play("myvideo", 0, -1)
前記のコードを使用すると、イベントに遅れて参加したビューアでも、ストリームを最初から表示できます。
いつでもストリームの最初に戻るには、次のコードを呼び出します。
NetStream.seek(0)
イベントの途中で記録を開始するには、サーバーサイド ActionScriptの Stream.record()メソッドを呼び出します。このメソッドを呼び出すことで、いつでも記録の開始や停止が可能になります。
(「ライブ」と見なされる)記録の使用可能な最新の部分をシークするボタンを作成するには、ストリームの再生時間(サーバー上で記録されたデータの長さ)から NetStream.bufferTimeの値を引いた位置をシークします。瞬間的な位置にできるだけ近い位置で再生するには、bufferTimeを引き算します。Flash Playerは、バッファーがいっぱいになるまで再開されません。
ストリームの再生時間を計算するには、onMetaData コールバック関数にタイムスタンプを設定します。
public function onMetaData(info:Object):void{
trace("metadata:duration=" + info.duration);
duration = info.duration;
trace("stamp: " + stamp);
stamp = getTimer();
}
seek()メソッドに渡す値を計算するには、現在の再生時間を計算し、念のために bufferTimeから 2秒をさらに引きます。
private function getSeekToLiveValue():uint{
currentDuration = Number((getTimer()-stamp)/1000) + duration;
trace("currentDuration: " + currentDuration);
seekVal = (currentDuration - nsPlayer.bufferLength) - 2;
return seekVal;
}
「ライブ」をシークするには、再生 NetStream オブジェクトで getSeekToLiveValue() 関数を呼び出します。
private function onClick(event:MouseEvent):void {
switch(event.currentTarget){
case rewindBtn:
nsPlayer.seek(nsPlayer.time - 5);
break;
case seekBtn:
trace("seekToEndValue " + getSeekToEndValue());
nsPlayer.seek(getSeekToLiveValue());
break;
}
}
注意:上述のコードは、サーバー上の rootinstall/documentation/samples/dvr フォルダー内にある DVR サンプルにあります。
Flash Media Live Encoder を使用した DVR 再生用ビデオのキャプチャ
Flash Media Live Encoder 3 を使用して、DVR 再生用のビデオをキャプチャすることができます。Flash Media Live Encoder の以前のバージョンは、サーバーへの記録をサポートしていません。詳細については、www.adobe.com/jp/products/flashmediaserver/flashmediaencoder/ を参照してください。
この例では、クライアントアプリケーションは以下の動作を行います。
• ビデオをキャプチャしエンコードします。
• キャプチャした状態でビデオを表示します。
• ビデオをクライアントから Adobe Media Server にストリーミングします。
• 逆にビデオをAdobe Media Server からクライアントにストリーミングします。
• サーバーからストリーミングされたビデオを、ライブビデオの巻き戻しと一時停止が可能な Playerに表示します。
注意:このコードをテストするには、サーバーに RootInstall/applications/dvr フォルダーを作成します。次に、RootInstall/documentation/samples/dvr/DVR.swf ファイルを開いてアプリケーションに接続します。
1 Adobe Media Server に、RootInstall/applications/dvr フォルダーを作成します。
2 Flash で、ActionScript ファイルを作成し、DVR.as という名前で保存します。
3 次のコードを Script ウィンドウにコピーアンドペーストします。
package {
import flash.display.MovieClip;
import flash.utils.getTimer;
import flash.net.NetConnection;
import flash.events.*;
import flash.net.NetStream;
import flash.media.Video;
import flash.media.Camera;
import flash.media.Microphone;
import fl.controls.Button;
public class DVR extends MovieClip
{
private var nc:NetConnection;
private var ns:NetStream;
private var nsPlayer:NetStream;
private var vid:Video;
private var vidPlayer:Video;
private var cam:Camera;
private var mic:Microphone;
private var pauseBtn:Button;
private var rewindBtn:Button;
private var playBtn:Button;
private var seekBtn:Button;
private var dvrFlag:Boolean;
private var stamp:uint;
private var duration:uint;
private var currentDuration:uint;
private var seekVal;uint;
public function DVR()
{
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
nc.connect("rtmp://localhost/dvr");
setupButtons();
dvrFlag = true;
}
private function onNetStatus(event:NetStatusEvent):void{
trace(event.info.code);
switch(event.info.code){
case "NetConnection.Connect.Success":
publishCamera();
displayPublishingVideo();
displayPlaybackVideo();
break;
case "NetStream.Play.Start":
trace("dvrFlag " + dvrFlag);
if(dvrFlag){
nsPlayer.seek(getSeekToLiveValue());
dvrFlag = false;
}
break;
}
}
private function onAsyncError(event:AsyncErrorEvent):void{
trace(event.text);
}
private function onClick(event:MouseEvent):void {
switch(event.currentTarget){
case rewindBtn:
nsPlayer.seek(nsPlayer.time - 5);
break;
case pauseBtn:
nsPlayer.pause();
break;
case playBtn:
nsPlayer.resume();
break;
case seekBtn:
nsPlayer.seek(getSeekToLiveValue());
break;
}
}
private function publishCamera() {
cam = Camera.getCamera();
mic = Microphone.getMicrophone();
ns = new NetStream(nc);
ns.client = this;
ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
ns.attachCamera(cam);
ns.attachAudio(mic);
ns.publish("video", "record");
}
private function displayPublishingVideo():void {
vid = new Video(cam.width, cam.height);
vid.x = 10;
vid.y = 10;
vid.attachCamera(cam);
addChild(vid);
}
private function displayPlaybackVideo():void{
nsPlayer = new NetStream(nc);
nsPlayer.client = this;
nsPlayer.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
nsPlayer.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
nsPlayer.play("video", 0, -1);
vidPlayer = new Video(cam.width, cam.height);
vidPlayer.x = cam.width + 20;
vidPlayer.y = 10;
vidPlayer.attachNetStream(nsPlayer);
addChild(vidPlayer);
}
private function getSeekToLiveValue():uint{
currentDuration = Number((getTimer()-stamp)/1000) + duration;
trace("currentDuration: " + currentDuration);
seekVal = (currentDuration - nsPlayer.bufferTime) - 2;
trace("seekVal: " + seekVal);
return seekVal;
}
private function setupButtons():void {
rewindBtn = new Button();
pauseBtn = new Button();
playBtn = new Button();
seekBtn = new Button();
rewindBtn.width = 52;
pauseBtn.width = 52;
playBtn.width = 52;
seekBtn.width = 100;
rewindBtn.move(180,150);
pauseBtn.move(235,150);
playBtn.move(290,150);
seekBtn.move(345, 150);
rewindBtn.label = "Rew 5s";
pauseBtn.label = "Pause";
playBtn.label = "Play";
seekBtn.label = "Seek to Live";
rewindBtn.addEventListener(MouseEvent.CLICK, onClick);
pauseBtn.addEventListener(MouseEvent.CLICK, onClick);
playBtn.addEventListener(MouseEvent.CLICK, onClick);
seekBtn.addEventListener(MouseEvent.CLICK, onClick);
addChild(rewindBtn);
addChild(pauseBtn);
addChild(playBtn);
addChild(seekBtn);
}
public function onMetaData(info:Object):void {
trace("metadata:duration = " + info.duration);
stamp = getTimer();
trace("stamp: " + stamp);
duration = info.duration;
}
}
}
4 DVR.as ファイルを保存します。
5 File / New / Flash File(ActionScript 3.0)を選択し、「OK」をクリックします。
6 ファイルを DVR.as ファイルと同じフォルダーに DVR.flaという名前で保存します。
7 コンポーネントパネルを開き、Buttonをステージまでドラッグして削除します。
この操作により、ボタンがライブラリに追加されます。ボタンは実行時にアプリケーションに追加されます。
8 ファイル/パブリッシュ設定を選択します。「Flash」タブをクリックします。「Script Settings」をクリックし、DVRを Document クラスとして入力します。チェックマークをクリックしてパスを検証します。
9 ファイルを保存し、Control / Test Movie を選択してアプリケーションを実行します。
Application.xml 設定ファイルのパラメーター、サーバーサイド ActionScript および Authorization プラグインを使用して、記録の最大サイズと時間を制限することができます。これらの値を設定してディスクスペースの使い過ぎを防ぎます。
以下は、Application.xml ファイルのパラメーターです。
XML 要素 |
説明 |
Application/StreamManager/Recording/MaxDuration |
秒単位の最大記録時間。デフォルト値は -1 で、最大時間は適用されません。 |
Application/StreamManager/Recording/MaxDurationCap |
秒単位の最大記録キャップ時間。デフォルト値は -1 で、最大時間のキャップは適用されません。 サーバーサイド Stream.record() メソッドはこの値より優先されません。Authorization プラグインはこの値より優先されます。 |
Application/StreamManager/Recording/MaxSize |
キロバイト単位の最大記録サイズ。デフォルト値は -1 で、最大サイズは適用されません。 |
Application/StreamManager/Recording/MaxSizeCap |
キロバイト単位の最大記録キャップサイズ。デフォルト値は -1 で、最大サイズのキャップは適用されません。 サーバーサイド Stream.record() メソッドはこの値より優先されません。Authorization プラグインはこの値より優先されます。 |
Application.xmlファイルでは、最大値の設定に加え、最大キャップ値を設定することもできます。サーバーサイドスクリプトはこれらのキャップより優先されません。CDNはこれらのキャップを使用して、クライアントが優先されない制限を設定することができます。
注意:Authorization プラグインは、Application.xml ファイルに設定されたすべての値より優先されます。
サーバーサイド ActionScript で値を設定するには、Stream.record() を呼び出し、maxDuration および maxSize パラメーターの値を渡します。次のコードは記録を 5 分に制限し、(MaxSizeCap の値まで)無制限の最大ファイルサイズを設定します。
s.record("record", 300, -1);
サーバーは、MaxCapSizeおよび MaxCapDurationを上回る記録を切り捨てます。
関連項目
大規模なアプリケーションを構築するには、サーバーサイド NetConnectionクラスを使用して、複数のサーバーをまとめてチェーン化します。このシナリオでは、クライアントは接続したサーバー上にないストリームを要求することができます。
サーバーサイド ProxyStreamクラスを使用して、サーバーチェーンでストリームを探す検索メカニズムを作成します。
Vhost.xml設定ファイルに値を設定して、ストリームを格納するディスクキャッシュを設定することができます。
XML 要素 |
属性 |
説明 |
VirtualHost/Proxy/CacheDir |
enabled |
ディスクキャッシュが有効かどうかを判断します。 |
|
useAppDir |
アプリケーションでキャッシュのサブディレクトリを分割するか指定します。 |
VirtualHost/Proxy/CacheDir/Path |
|
ディスクキャッシュのルートディレクトリ。 |
VirtualHost/Proxy/CacheDir/MaxSize |
|
ギガバイト単位の最大ディスクサイズ。デフォルト値は 32 です。 値が 0 の場合、ディスクキャッシュが無効になります。値が -1 の場 合、最大値は指定されません。 |
VirtualHost/Proxy/RequestTimeout |
|
上流サーバーからの要求(メタデータではコンテンツなど)に対する応答を待つ、秒単位の最大時間。デフォルト値は 2 秒です。 |
サーバーに複数の仮想ホストがある場合は、仮想ホストをそれぞれのキャッシュディレクトリに指定します。
サーバーが CacheDir への書き込み中に中間またはエッジサーバーでディスクスペースを使い果たすと、ディスクへの書き込みに失敗した各セグメントの core.xx.log に次の警告メッセージが記録されます。I/O Failed on cached stream file C:\Program Files\Adobe\Adobe Media Server 5\cache\streams\00\proxyapp\<IP>\C\Program Files\Adobe\Adobe Media Server 5\applications\primaryapp\streams\_definst_\sample1_1500kbps.f4v\0000000000000000 duringwrite: 28 No space left on device.
DVRビデオ Playerで再生したストリームは、記録されたストリームとして再生されます。これらのストリームは、すべて記録されたストリームとして同じイベントをログファイルに記録します。
関連項目
最終更新日 2013/9/30