◆PROCESSING 逆引きリファレンス
カテゴリー:動画・アニメーション
動画の再生位置を変更するには
【解説】
PROCESSINGで 動画を扱うには、公式サイト 様に公開されている動画専用のライブラリ(Videoライブラリ)を使うのが便利です。
Videoライブラリが持つMovieクラスを使うと、動画の読み込みや再生を行うことができます。
例えば Movieクラスの play() メソッドは、動画を頭から再生します。
では動画を頭からではなく、好きな位置から再生するにはどうしたら良いでしょうか?。
Movieクラスには動画の再生位置を変更するjump()命令があります。このメソッドを利用すると、動画の再生位置を指定した場所に変更できます。
動画の再生位置を変更するとなると、自ずと動画の長さ(総再生時間)や、現在の再生位置が知りたくなります。
動画の総再生時間は、 Movieクラスの duration()命令で取得可能です。また現在の再生位置は time() 命令で取得できます。
【構文】
●総再生時間を知る
float len = movie . duration( ) ;
len :総再生時間が秒数で戻されます。
●現在の再生位置を知る
float tm = movie . time( ) ;
tm :現在の再生位置が秒数で戻されます。
●動画が再生中か否かを知る
boolean isp = bin2 . isPlaying( );
isp:再生中なら Trueが、そうでないなら False が戻されます。
●再生位置を変更する
void movie . jump( float where ) ;
where:ジャンプする位置を先頭からの秒数で与えます。
※movieはMovieクラスのインスタンス変数です。
※bin2はPlayBin2クラスのインスタンス変数です。
【注意】
総再生時間を知る
動画の総再生時間は duration() メソッドで取得可能です。戻される値は秒数です。
得られる値はfloat型でミリセカンド単位の精度を持っていますが、1/100秒以下は誤差だと思ったほうが良いでしょう。
また duration() メソッドは動画の再生中にのみ有効な値を戻します。動作再生前や停止中(stop中)は、0 が戻される事に注意してください。
ただし pause() で一時停止している場合は、有効な値を戻してくれます。
現在の再生位置を知る
動画先頭から見た現在の再生位置を得るには time() メソッドを使います。time()メソッドは、動画先頭から経過した秒数を戻します。
duration() と同じく得られる値はfloat型でミリセカンド単位の精度を持っていますが、1/100秒以下は誤差だと思ったほうが良いでしょう。
また time() メソッドも動画の再生中にのみ有効な値を戻します。動作再生前や停止中(stop中)は、負の値が戻される事に注意してください。
ただし pause() で一時停止している場合は、有効な値を戻してくれます。
動画が再生中か否かを知る
残念ながら Movieクラスが持つメソッドだけでは、動画が再生中か否かを知る事ができません。
動作再生中か否かを知るには、Movieクラスの playbinプロパティに格納されているPlayBin2クラスのインスタンス変数を取り出し、PlayBin2クラスの isPlaying() メソッドを利用する必要があります。
動作再生中ならTrueが、再生前や、一時停止中(pause中)、停止中(stop中)なら False が戻されます。
PlayBin2クラスについては「動画の音量を変更するには」記事でも少しだけ触れています。興味がある方は参照してみてください。
再生位置を変更する
jump()メソッドで動画の再生位置を変更可能です。jump() には、動画先頭からの経過時間を秒数で与えます。
例えば総再生時間が 12.6秒 ある動画に、jump( 6.3 ) ; とすると、ちょうど半分いった所を新しい再生位置にします。
与える値は、0から総再生時間までです。0を与えると動画の再生位置を先頭に、総再生時間を与えると最後尾に変更します。
0より小さい値を与えた場合は、0を与えたものとして処理されます。また総再生時間より大きな値を与えた場合は、総再生時間を与えたものとして処理されます。
jump()命令も、動画を再生する前や停止中(stop中)は機能しません。ただし一時停止中(pause中)であれば機能します。
【関連記事】
サンプルプログラム
再生中か調べる例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
import processing.video.*; import org.gstreamer.elements.*; Movie movie; //Movieインスタンス PlayBin2 bin2; //PlayBin2インスタンス void setup(){ size(640, 380); //動画を読み込む movie = new Movie( this, "マルコメ 料亭の味 即席生みそ汁 単身赴任篇 90秒.mp4"); //PlayBin2インスタンスを取り出す bin2 = movie.playbin; frameRate(60); //文字の表示位置指定 textSize(16); textAlign(LEFT,TOP); //再生開始 movie.play(); } void draw(){ background( 0 ); //動画を表示する image( movie, 0, 0, width, 360 ); //状態を表示する String msg; if( bin2.isPlaying() ){ //再生中 msg = "PLAY"; } else { //停止または一時停止中 msg="STOP or PAUSE"; } fill(255); text(msg, 0, 362 ); } //映像フレーム毎に自動呼び出しされるイベント void movieEvent( Movie m ) { //カレント位置の画像を取得 m.read(); } void mouseClicked(){ //範囲外がクリックされたら何もしない if( mouseX < 0 || mouseX > width || mouseY < 0 || mouseY > height ){ return; } //一時停止する movie.pause(); } |
動画の下部に再生中なら「PLAY」、そうでないなら「STOP or PAUSE」と表示します。
再生位置を変更する例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
import processing.video.*; Movie movie; //Movieインスタンス PImage forward, backward; //ボタン画像 boolean doPlay; //再生指示FLG boolean isPlay; //再生中FLG void setup(){ size(640, 408); //画像を読み込む forward = loadImage( "forward.png" ); backward = loadImage( "backward.png" ); //動画を読み込む movie = new Movie( this, "マルコメ 料亭の味 即席生みそ汁 単身赴任篇 90秒.mp4"); doPlay = false; isPlay = false; frameRate(60); //文字の表示位置指定 textSize(16); textAlign(LEFT,TOP); } void draw(){ background( 0 ); //動画を表示する image( movie, 0, 0, width, 360 ); //ボタンを表示する image( backward, 0, 360); image( forward, width - forward.width, 360 ); //再生位置をバーで表示する fill(color(128,128,128)); rect( 50, 368, 540, 24 ); //再生指示済みなら再生位置を表示する //再生実行後でしか time()とduration()が有効な値を戻さない対策 if( doPlay ){ float nowDur = movie.time(); float maxDur = movie.duration(); fill(color(100,100,255)); rect( 50, 368, map(nowDur,0,maxDur,0,540),24 ); //再生位置を文字で表示する fill(255); String msg = nfs(nowDur,3,2) + "/" +nfs(maxDur,3,2); text( msg, (width - textWidth(msg))/2, 368 ); //最後まで再生したら一時停止する if( floor(nowDur*100) == floor(maxDur*100) ){ movie.pause(); isPlay = false; } } } //映像フレーム毎に自動呼び出しされるイベント void movieEvent( Movie m ) { //カレント位置の画像を取得 m.read(); } void mouseClicked(){ //範囲外がクリックされたら何もしない if( mouseY < 0 || mouseY > height || mouseX < 0 || mouseX > width ){ return; } //動画がクリックされたら再生と停止を行う if( mouseY < 360 ){ if( isPlay ){ //一時停止 movie.pause(); isPlay = false; //停止中 } else { //再生(再開) movie.play(); doPlay = true; //動画再生指示済み isPlay = true; //再生中 } return; } //現在の再生位置を取得 float nowDur = movie.time(); //一時停止させ、位置を変更し、続きを再生する //こうしないと jump()した位置からうまく再生 //できない・・・ if( isPlay ){ //再生中なら一端、一時停止する movie.pause(); } if( mouseX < backward.width ){ //巻き戻し movie.jump(nowDur-4) ; } else if( mouseX > (width - forward.width) ){ //早送り movie.jump(nowDur+4); } if( isPlay ){ //再生中なら、再開する movie.play(); } } |
動画の場所をクリックすると再生が始まります。
早送り・巻き戻しボタンを押すと、現在の再生位置から4秒先(または前)に移動します。
<出力サンプル>
ボタン画像は illust-AC 様:Layu さんの画像を拝借しています。
またすべての動画映像は、味噌や発酵食品で有名なマルコメ株式会社 様のテレビCMの1コマです。私も似たような経験がある内容で、懐かしくも暖かな気持ちになりました(笑)。
今回動画の掲載に関し、マルコメ株式会社 様より寛大なご許可を得ることができました。謹んでお礼申し上げます。
なお当サイトから動画を流用する行為は禁止とさせて頂いております。悪しからずご了承ください。
下記はサンプルプログラムと同じ動きになるように、 P5.js+P5.dom で書き直したものです。動作イメージを確認できます。※
※ブラウザーによっては下記サンプルが表示されない事があります。動画が表示されない場合は IE11、FireFox、Chrome、Edge などでお試しください。
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。