dポイントプレゼントキャンペーン実施中!

Flashでの動画ファイルの扱いに関して質問させていただきます。
外部にあるflvファイルをFlashのステージ上で表示させる方法として、
以下2点を試しています。


・FLVPlaybackコンポーネントを使用して、スクリプトで制御する方法
(パラメータに相当する部分をスクリプト制御)
例:FLVPlaybackインスタンス名.contentPath = "●●●.flv";

・Videoオブジェクトをステージに配置し、スクリプトで制御する方法
(NetConnection,NetStreamを使用)
例:Videoオブジェクトインスタンス名.attachVideo(NetStreamオブジェクト名);


ここでCuePointに関してですが、上記FLVPlaybackを使用した際はCuePointを追加して、
再生ヘッドが特定のCuePointに到達したら任意の処理を実行という動作を確認しました。


このCuePointの仕組みと同様の処理をVideoオブジェクトの際は
NetStreamオブジェクト.time で
現在の再生ヘッドの場所(再生時間?)が取得できる?ので
CuePointの追加スクリプトは書かなくてよいのでしょうか?
というか、VideoオブジェクトにCuePointの追加ってできるのか?


あと、FlVPlaybackの方は
FLVPlaybackインスタンス名.volume で
動画の音量調整ができますが、
Videoオブジェクトの方は動画の音量調整をどのようにすればよいのでしょうか?
NetStreamオブジェクト名.volume や
NetStreamオブジェクト名.setVolume
Videoオブジェクトインスタンス名.volume(setVolume)等
試してみましたが、反応なしでした。


最後にFlashで動画ファイルを扱う際FlVPlaybackを使用するのと、
VideoオブジェクトでNetConnection,NetStreamを使用するのと
どちらが適している(一般的)なのでしょうか?
わかる範囲でご回答いただければ幸いです。

A 回答 (3件)

FLV のキューポイントには、埋め込み式とスクリプトで後で追加するものの、2種類があります。




埋め込み式のキューポイントは、その名の通り FLV の中に書き込んでおくキューポイントです。
Flash に付属の Video Encoder では、FLV に変換する際にキューポイントを定義できます。単にしおりのようなポイントを作成するだけでなく、何かの値を同時に記録しておくこともできます。
既に出来上がっている FLV に後からキューポイントを追加できるフリーウェアや編集ツールもあるようです。

埋め込んだキューポイントは FLV ファイルの中に情報が書き込まれ、再生ヘッドがこのポイントを再生するとイベントとしてシステムに通知されます。
この通知は、ActionScript 2.0 であれば NetStream クラスの onCuePoint というイベントハンドラを使って拾うことができます。( 3.0 でも、Flash Media Server との互換のために onCuePoint は残っているそうですが)
埋め込み式のキューポイントは FLV 自体が持っている機能を使うようなもので、精度が高く正確です。


FLV の制御には本来、スクリプトによるキューポイントという概念は存在しません。
ですから、NetStream クラスにも Video クラスにも、スクリプトでキューポイントを定義するメソッドはありません。
次項で説明しますけれど、FLVPlayback コンポーネントはスクリプトを工夫してキューポイントのようなものを実現しているだけです。

********************************

FLVPlayback コンポーネントでは埋め込み式のキューポイントの他に、スクリプトによるキューポイントも利用できます。
これは FLVPlayback コンポーネントの機能として Adobe が作成してくれたクラスによるもの、つまりスクリプトで擬似的に実現しているキューポイントです。
このキューポイントの特長は何といっても、FLV ファイルを加工しなくても、スクリプトや「プロパティ」パネルでいくらでもキューポイントを追加・削除・編集ができる柔軟性です。

ただし、スクリプトで定義したキューポイントは、短い間隔で再生ヘッドの位置を定期的に監視して定義されているポイントの付近に達した時に通知するという、あくまでも擬似的なものです。
そのため、精度は埋め込みキューポイントより劣り、指定したキューポイントからごくわずかながらズレるといった微妙なズレが生じる場合があります。

ご質問文にある”再生ヘッドの位置を取得してキューポイントを実現する”という発想で作られたのが、まさしく、FLVPlayback コンポーネントに実装されているスクリプト式のキューポイントです。
ただ、再生ヘッドがあるポイントに来たかどうかを検出するためには、再生ヘッドの位置を監視するスクリプトを一定間隔で実行しなければなりません。
細かい話になりますが、例えば setInterval で一定間隔で呼び出した場合、1回目の呼び出しから2回目の呼び出しまでの間がどうしても空いてしまいます。
この空いている間にキューポイントの部分が再生されてしまったら、そのポイントの情報を拾うことができません。
FLVPlayback コンポーネントではこのあたりの調整が内部で行われており、キューポイントを見逃すようなことはありませんが、間隔の隙間にあったキューポイントは”その近辺の位置”であればキューポイントと見なされる場合があります。

-----------------------------------------------------------

当方は解説できるほど ActionScript 3.0 に詳しくないので、以下は 2.0 として話を進めます。


ActionScript 2.0 では、FLV の音声は出力するムービークリップを指定し、このムービークリップの音声を制御する Sound オブジェクトを作成して制御します。

FLV の映像を画面に表示する時、ビデオオブジェクトを作って

 Videoインスタンス名.attachVideo( NetStreamオブジェクト名 );

と指定し、そのビデオオブジェクトで映像を出力します。
音声もこれと似ていて、

 MovieClipインスタンス名.attachAudio( NetStreamオブジェクト名 );

とすると、この NetStream オブジェクトが再生している FLV の音声が指定のムービークリップから出力されるようになります。
あとは、このムービークリップの音声を制御する Sound オブジェクトを

 snd = new Sound( MovieClipインスタンス名 );

というように作成し、Sound クラスの機能を利用して音量の設定等を行います。
音量・パンの制御は普通のサウンドの制御と全く同じです。

********************************

参考までに、先の埋め込み式のキューポイントの情報を取得して表示し、FLV の音声をミュートにするスクリプト(バージョンは 2.0 )の作例をご紹介します。


NetStream クラスはスクリプトによるキューポイントに対応していないため、キューポイントを編集するメソッドがそもそもありません。
onCuePoint イベントハンドラで検出できるのも、 FLV に埋め込まれているキューポイントだけです。

Video Encoder でキューポイントを作成するか、キューポイントを編集できるツール等で埋め込みキューポイントをいくつか作成した、音声のある FLV をご用意ください。
( Video Encoder でキューポイントを埋め込む方法は、 Video Encoder のヘルプの「ビデオエンコード設定のカスタマイズ」→「キューポイントの定義と埋め込み」の項目をご参照ください)


ステージにビデオオブジェクトの” video_disp ”と、ミュートボタンに使うムービークリップのインスタンス” mute_btn ”があるとします。
ミュートボタンは必ず”ムービークリップ”で作成してください。
このスクリプトは、メインのタイムラインのフレームに設定してください。

(↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください)


/*******************************************************/


 //------ FLV再生に関する処理 -----

 //FLVのURL
 flv_url = "○○○.flv";


 //ローカル接続を確立
 connector = new NetConnection();
 connector.connect( null );
 stream_obj = new NetStream( connector );

 //埋め込みキューポイントに到達した時の処理
 stream_obj.onCuePoint = function( cue_info:Object )
 {
  //キューポイントの情報を出力
  trace( "-------------------------------" );
  trace( "キュー名 = " + cue_info.name );
  trace( "時  間 = " + cue_info.time );
  trace( "種  類 = " + cue_info.type );

  //キューポイントに値が設定されていれば、それを表示
  if( cue_info.parameters != undefined )
  {
   trace( "パラメータ:" );

   for( p_name in cue_info.parameters )
   {
    trace( " 名前 = " + p_name + " " + "値 = " + cue_info.parameters[ p_name ] );
   }
  }

  trace( "-------------------------------" );
 };

 //FLVを再生
 video_disp.attachVideo( stream_obj );
 stream_obj.play( flv_url );


 //------ ミュートボタンに関する処理 -----

 //FLVの音声をミュートボタンのムービークリップから出力
 mute_btn.attachAudio( stream_obj );

 //最大音量
 max_vol = 100;

 //Soundオブジェクトの作成
 snd = new Sound( mute_btn );

 //音量の初期値を設定
 snd.setVolume( max_vol );

 //ミュートボタンの動作を定義
 //クリックする度に音量を0またはmax_volに切り替える
 mute_btn.onRelease = function()
 {
  snd.setVolume( max_vol - snd.getVolume() );
 };


/*******************************************************/


冒頭にある変数 flv_url に FLV ファイルのパスを記述して、「ムービープレビュー」で動作を確認してみてください。
1件の埋め込みキューポイントに到達するたびに、「出力」パネルに

 -------------------------------
 キュー名 = ○○○
 時  間 = △△.△△△
 種  類 = event または navigation
 パラメータ:
  名前 = □□□ 値 = *****
 -------------------------------

このような形でキューポイントに関する情報が出力されます。
また、ミュートボタンをクリックすると消音になり、もう1度クリックすると解除されます。


付属の Video Encoder を使用した場合、「設定」ボタン→「キューポイント」タブでの設定は、trace アクションで出力される内容と次のように対応しています。

 ・キュー名:「名前」の項目に記述した文字列
 ・時  間:「タイム」に表示される時間
 ・種  類:「タイプ」のリストで選んだ種類
 ・パラメータ:
   名前:「パラメータ」の”名前”の項目に記述した文字列
   値 :「パラメータ」の”値”の項目に記述した文字列

「パラメータ」は作成した数だけ取り出されますが、for in の性質上、下のものほど先に表示されます。
パラメータを定義しなかったキューポイントの場合は、「パラメータ:」の部分が表示されません。


onCuePoint イベントハンドラに設定した関数は、キューポイントに達するたびに実行されます。
この時、1件のキューポイントの情報が Object 型の変数にまとめられて渡されてきます。
上記の例では仮引数の名前は” cue_info ”です。キューポイントの情報である cue_info の構成は次のようになっています。

 cue_info
  ┣ name
  ┣ time
  ┣ type
  ┗ parameters
    ├パラメータの名前
    │   :
    └(パラメータの数だけ作られる)

上記のスクリプトでは仮引数で渡されたキューポイントの情報を単純に trace アクションで表示しているだけですが、パラメータを活用すると、FLV の画面とシンクロしたアニメやナビゲーションなど面白い作品が作れるかもしれません。

********************************

ミュートボタン自体の処理は、今回は本題ではありませんので詳しくは触れませんが。
クリックするごとに最大音量から現在の音量を減算したものを新たな音量に設定することで、0 と変数 max_vol で指定した音量に切り替えています。

音声の操作では、

 //FLVの音声をミュートボタンのムービークリップから出力
 mute_btn.attachAudio( stream_obj );

↑この部分に着目してください。

Flash でのサウンドは水を流すように、水路に相当するもの(チャンネルといいます)を通して出力します。
ActionScript 2.0 までは、FLV の音声に限らず普通のサウンドでもムービークリップがチャンネルの役割を果たしており、この水路に設けられた水門を操作するのが Sound クラスの役目でした。

NetStream クラスは FLV を読み込んだり再生するだけ、Video クラスも FLV の映像に関する仕事だけを請け負うクラスで、音声の制御はまた別のクラスの仕事になります。
上記の例では attachAudio で FLV の音声を流すチャンネルをムービークリップ” mute_btn ”に指定し、このチャンネルの水門の操作役である Sound クラスの snd オブジェクトが流す量(音量)を調整しています。

FLVPlayback コンポーネントは単体で映像も音声も制御できるように作られていますが、内部では複数のクラスが分業して様々な機能を実現しています。
面倒な内情は内部に隠し、再生から映像・音声の処理まで1つのクラスでできるように機能を集約し、簡単な命令1つで制御できるようにしてくれているだけなのです。


もっとも、音声に関するこのような制御は ActionScript 2.0 までの話です。
3.0 からは、サウンドを流すチャンネルはムービークリップから SoundChannel クラスの管轄に変わり、音量やパンの設定(音声出力に関する制御)も SoundTransform というクラスの担当と、サウンドに関する処理が細分化されました。
NetStream クラスにも SoundTransform クラスのオブジェクトの” soundTransform ”(大文字・小文字の違いにご注意ください)というプロパティがあるので、これを使って FLV の音声出力を NetStream クラスで直接制御できるようになったのだと思います。
ちなみに、音量やパンは 2.0 までは 0 ~ 100 で表していましたが、3.0 からは 0 ~ 1 に変わったそうです。

-----------------------------------------------------------

FLV は、NetConnection で接続を確立し NetStream クラスで再生に関する制御を行うのが基本です。
FLVPlayback コンポーネントでも、この2つのクラスを使用して FLV を再生しています。

FLV を扱う基本的なスクリプトを知っていれば、自分だけのプレイヤーやコンポーネントを作ることも可能です。
ネットなどで配布されている FLV プレイヤーの Flash 素材も、基本的には NetConnection と NetStream クラスで FLV を再生し、それに制作者のアイデアやスクリプトの技能で様々な機能を追加したものです。

FLV に限らず、そもそもコンポーネントは、ムービーの制作でよく使われる素材を簡単に作品に組み込めるようにとの目的から作られたものです。
中にはスクリプトの知識がないとまるで役に立たないコンポーネントもありますが、FLVPlayback コンポーネントに関しては、何の知識もなくても、再生するファイルさえ指定すれば FLV を使った Flash ムービーの出来上がりです。
ただし、コンポーネントは所詮は既製品です。デザインや機能に不満があっても、ある程度は妥協しなければなりません。
それが嫌なら、NetStream クラス等を駆使して納得のいくプレイヤーを自作することです。


しかし、既製品を使うのも別に間違いではありません。
動画のプレイヤーにある主な機能が一通り揃っているので、全くのゼロから作るよりもはるかに簡単に FLV を利用できます。
現に、FLVPlayback でなくても、ネットや素材集で頒布されているいろいろなプレイヤーを利用している人はたくさんいます。

どちらを使うかは、用途やスクリプトのスキルなどによって異なります。
例えば、単純に FLV を再生したいだけの場合は NetStream クラス等だけでも充分で、容量や処理の重いコンポーネントをわざわざ使うのはかえってムダです。
自分でスクリプトを組んで何とかできるのならそれで構いませんし、FLVPlayback や他のプレイヤー素材で気に入ったものを見付けたのならそちらを使えばいいのです。
どちらが一般的とか適しているとは、一概には言えません。

この回答への補足

>DPE殿
毎度毎度、懇切丁寧な回答ありがとうございます。
AS3.0については全くのド素人の小生にも今後間違いなく役に立つ
2.0から3.0の違いの部分も説明してくださりとても勉強になります。


私が今実験している一例として、
FLVPlaybackのインスタンス名に「ukezara」という名前をつけて
---------------------------------------
ukezara.addASCuePoint(10,"mikan");
---------------------------------------
あるいは
---------------------------------------
var kyu:Object = new Object();
kyu.time = 5;
kyu.name = "ringo";
kyu.type = "actionscript";
ukezara.addASCuePoint(kyu);
---------------------------------------
として、ASによってキューポイントを追加しています。
そして
---------------------------------------
var renraku = new Object();
renraku.cuePoint = function(jyouhou) {
if (jyouhou.info.name == "ringo") {
trace("5秒経過");
buttai._visible = true;
} else if (jyouhou.info.name == "mikan") {
trace("10秒経過");
buttai._visible = false;
}
};
ukezara.addEventListener("cuePoint",renraku);
---------------------------------------
として、任意のキューポイント到達時に処理を分けています。

このaddASCuePointとはFLVPlaybackに対して有効で、
NetStreamクラスには使用できないという認識でよろしいですか?
要はNetStreamクラスにASでキューポイントを追加できない?


もうひとつ。
FLVの音量調節のところで、
---------------------------------------
MovieClipインスタンス名.attachAudio( NetStreamオブジェクト名 );
---------------------------------------
ですが、
---------------------------------------
MovieClipインスタンス名.attachSound( NetStreamオブジェクト名 );
---------------------------------------
でも同様の結果が得られましたが
このattachAudioとattachSoundの違いって何なんでしょうか?

補足日時:2009/04/30 17:18
    • good
    • 0

#1、2です。




音を出力するチャンネルとして使うムービークリップは、ムービークリップであれば何でもよく、絵のあり・なしは関係ありません。
#1ではミュートボタンの例ということで、絵のあるムービークリップを配置し、ついでに FLV の音声を出力するチャンネルもこのムービークリップを借りましたが、例えば#1の作例で attachAudio の部分を


 //チャンネル用の空のムービークリップを作成し、
 //ここからFLVの音声を出力する
 this.createEmptyMovieClip( "ch_clip" , 0 );
 ch_clip.attachAudio( stream_obj );

 //Soundオブジェクトの作成
 snd = new Sound( ch_clip );


↑このように変更し、スクリプトで空っぽのムービークリップを作ってチャンネルにすることもできます。

ステージに他のムービークリップがあれば、そちらを借りても同じように動作します。
ただし、そのムービークリップのタイムラインで音を鳴らしている場合はその音量も変化してしまいますので、ご注意ください。

----------------------------------------------------------

#2にも書きましたが、FLV の音声しか扱わない場合や、FLV とともに他の音も変化していいのであれば、new Sound に何も指定せずムービー全体の音を管理する Sound オブジェクトを作り、マスターボリュームを操作しても構いません。
この場合はチャンネルにするムービークリップも、attachAudio も不要です。


Flash では1つのチャンネル=ムービークリップで何種類も音を同時に流すことができるのですが、パン(スピーカーの出力位置)と音量の設定は1つのチャンネルにつき1つずつしか設定できません。
つまり、同じチャンネルから出力される音の音量とパンはどれも同じになります。
そのため、複数の音を設定を変えて同時に出力したい場合は、音を出力するチャンネルになるムービークリップを分けて指定しなければなりません。
ActionScript 2.0 までの音の制御とチャンネル・ムービークリップの関係は、複数の音(例えば BGM と効果音など)を同時に鳴らし、どちらか一方だけ音量を変更するといったスクリプトを作ってみると理解しやすいと思います。

ActionScript 3.0 では音の出力に使われるものがムービークリップではなくなりましたが、”チャンネル”という考え方は変わっていません。
音量とパンはチャンネルに対して設定し、2.0 と同じく、1つのチャンネルにつき1つしか指定できないようになっています。
    • good
    • 0
この回答へのお礼

>DPEさん

ご回答ありがとうございました。
今回もすごく勉強になりました。

お礼日時:2009/05/13 09:03

#1です。




#1のキューポイントの説明は回りくどく分かりにくくなってしまったようで、失礼いたしました。
要するに、おっしゃる通り、

 > このaddASCuePointとはFLVPlaybackに対して有効で、
 > NetStreamクラスには使用できないという認識でよろしいですか?
 > 要はNetStreamクラスにASでキューポイントを追加できない?

ということです。
NetStream クラスを拡張して、FLVPlayback コンポーネントのようなキューポイント関連の機能を追加したクラスを作るなどすれば話はまた別ですけれど、NetStream クラスそのものにスクリプトによるキューポイントの操作を行うメソッドはありません。

------------------------------------------------------------

attachSound は MovieClip クラスではなく Sound クラスのメソッドで、主にライブラリにあるサウンドシンボルを Sound オブジェクトで再生する時に使います。
一方、attachAudioは MovieClip クラスのメソッドです。NetStream クラスで再生している FLV の音声のほか、マイクで入力された音声も扱うことができます。
両者は役割はもちろんクラスも違いますから、#1のスクリプトの attachAudio の部分を attachSound に変えても、MovieClip クラスにはない未定義メソッドで無効になるため、同じ結果にはならない(音量の操作に失敗する)はずですが。


Sound クラスのオブジェクトを作る際に、

 snd = new Sound();



 snd = new Sound( this );

のように、_root (メインのタイムライン)を制御する Sound オブジェクトを作成していませんか?
もしくは、ムービークリップのターゲットパスや名前の誤りが原因で、存在しないムービークリップが指定されていませんでしょうか?

new Sound の引数にムービークリップの名前またはターゲットパスを指定すると、そのムービークリップの音を管理する Sound オブジェクトが作られます。
指定しなかった場合や存在しないムービークリップを指定した場合は、ムービー全体の音を管理する Sound オブジェクトになります。

ムービー全体の音を管理する Sound オブジェクトはマスターボリュームのようなもので、ムービー全体の音声出力に影響を及ぼします。
つまり、MovieClipインスタンス名.attachSound が無効になってチャンネルとするムービークリップの指定に失敗していても、全体の音を管理する Sound オブジェクトであれば FLV の音量を制御することができます。

ムービー内で扱う音声が FLV だけなら、マスターボリュームを操作しても問題はありません。
しかし、例えばミュートボタンをクリックした時に効果音を鳴らしたい場合、マスターボリュームを操作すると FLV の音声とともに効果音もミュートになってしまいます。
逆に、FLV の音声をあるムービークリップから出力して個別に音量を制御していても、他にムービー全体の音を管理する Sound オブジェクトがあってそちらで音量を変更した場合は、FLV の音声もその影響を受けることになります。


ActionScript 2.0 まではこの通り、音声出力を個別に設定する方法が分かりにくい設計だったので、3.0 ではチャンネルを管理するクラスが用意されたのだと思います。

この回答への補足

お返事遅くなり申し訳ありません。
attachSoundで同様の結果というのは小生の勘違いでした。
すみません。

attachAudioで、音量調節が可能になったのを確認して、
attachSoundに変えて再生したところ、音が鳴ったので
あ、attachSoundでもいけるんだと早とちりをしてしまいました。
(単純にVideoオブジェクトから再生されてるだけ=音量調節はできてなかった。)


又、自分はステージ上に「oto」というインスタンス名の
空のムービークリップを配置して
-----------------------------------------
var my_sound:Sound = new Sound(oto);
oto.attachAudio(stream_obj);
my_sound.setVolume(50);
-----------------------------------------
としていましたが「oto」ムービークリップは
ステージに配置しなくても(目に見える形としてなくても)
動作しましたが「oto」のように新規でムービークリップを作る必要は
ないのでしょうか?
(DPEさんのサンプルでいうと「mute_btn」の部分。特にボタンをクリックして音量を調整等する必要がない場合は、
インスタンス名「mute_btn」のムービークリップをステージに配置しなくても良い?)

補足日時:2009/05/07 13:15
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!