◆PROCESSING 逆引きリファレンス
カテゴリー:動画・アニメーション
動画の早送り・巻き戻しをするには
【解説】
PROCESSINGで 動画を扱うには、公式サイト 様に公開されている動画専用のライブラリ(Videoライブラリ)を使うのが便利です。
Videoライブラリが持つMovieクラスを使うと、動画の読み込みや再生を行うことができます。
「動画の再生位置を変更するには」では動画の再生位置を jump() 命令で変更し、擬似的に早送りや巻き戻しっぽい事を行いました。
ところで実際の「早送り、巻き戻し」では、いきなり再生位置が変わる(ジャンプする)のではなく、映像が高速で再生(あるいは逆再生)されながら送られるイメージがありませんか?。
おじさまなどは古い人間ですので(汗)、早送りや巻き戻しというと、ビデオデッキやテープレコーダーがキュルキュルと音を立てながら、高速に映像を再生する印象があります。
Videoライブラリで、これと同じことをする(要するに再生、逆再生のスピードを変更する)には、どうすればよいでしょうか?。
Videoライブラリが持つMovieクラスの speed() メソッドを利用すると、動画の再生速度を変更することが可能です。
【構文】
void movie . speed( float irate ) ;
irate:再生スピード。1.0が通常速度。負の値は逆再生速度。
※movieはMovieクラスのインスタンス変数です。
【注意】
speed() メソッドを利用すると、動作の再生速度をコントロールする事が可能です。
1.0なら通常速度での再生になります。0.5なら半分の速度での再生(スロー再生)になります。
再生速度に負の値を与えると、逆再生を行うことが可能です。-1.0なら通常速度での逆再生。-2.0なら2倍速での逆再生です。
再生速度を大きく(あるいは小さく)しすぎると、動画再生が乱れることがあります。PCの処理能力にも依存すると思いますが、(あくまで感覚論的には)-3から+3くらいの範囲で使うのが適切だと感じました。
なおspeed() メソッドの引数(再生速度)に0を与えてはいけません。0を与えるとGStreamer-CRITICAL 例外が発生します。ここは注意してください。
再生速度が変わったかどうかを視覚的に確認するためには、 play()メソッドで再生を開始しstop() メソッドで停止するまでの間に、speed() メソッドを利用する必要があります。
speed()メソッドで指定した再生速度は、動画再生中か否かにかかわらず、常にVideoライブラリの内で保持され続ける事に注意してください。
このため、以下のような処理を行っても期待通りには動作しません。
movie . play() ; //<–A
movie. speed( 3 ) ; //<–B
movie. stop() ; //<–C
movie. play() ; //<–D
movie. speed( 3 ); //<–E
この処理では、まずAのplay()メソッドで動画の再生が始まります。
続いてBのspeed()メソッドで、動画の再生速度が3倍になります。
そしてCのstop()メソッドで、動画の再生が停止します。ここまでは想定通りです。
しかしなぜか、その後発行するDのplay()メソッドでは、動画は3倍速ではなく通常速度で再生されます(汗)。
そこでEのspeed()メソッドで再生速度をBの速度と同じにしたい・・・と思うのですが、このままでは期待通りには動作しません。
なぜならVideoライブラリ内部では、Bで指定された速度を覚えているからです。そのためEでspeed()メソッドを発行した時に与えた値が、内部で覚えている値(Bで与えた値)と同じであると判断され、無視されてしまうのです。
EでBと同じ速度に戻したい場合は、Bの直後からEの直前までの間に、Bとは異なる速度に変更しておく必要があります。
例えば以下のような感じです。
movie . play() ; //<–A
movie. speed( 3 ) ; //<–B
movie. stop() ; //<–C
movie. speed( 1 ); //<–★
movie. play() ; //<–D
movie. speed( 3 ); //<–E
この例ではstop() 直後(★)に、Bとは異なるspeed()値に変更しています。
【関連記事】
サンプルプログラム
再生スピードを変更する例:
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 |
import processing.video.*; Movie movie; //Movieインスタンス boolean isPlay; //動画再生中FLG int iSpeed; //再生速度 float getFrameTime; //フレーム読み取り時間 void setup(){ size(640, 390); //動画を読み込む movie = new Movie( this, "マルコメ 料亭の味 カップみそ汁 夜食篇 90秒.mp4"); isPlay = false; //再生中じゃない iSpeed = 0; getFrameTime = 0; //フレームは未読み取り frameRate(60); //文字の表示位置指定 textSize(24); textAlign(LEFT,TOP); } void draw(){ background( 0 ); //動画を表示する image( movie, 0, 0, width, 360 ); if( isPlay ){ float getDrawFrame = frameCount ; //ビデオフレームが2秒以上更新されていなければ //停止とみなす if( (getDrawFrame - getFrameTime)> 120 ){ isPlay = false; movie.stop(); getFrameTime = 0; iSpeed = 0; movie.speed( 1 ); } } fill( 255 ); if( isPlay ){ text("PLAY" + "/ SPEED=" + iSpeed,0,360 ); } else { text("STOP" + "/ SPEED=" + iSpeed,0,360 ); } } //映像フレーム毎に自動呼び出しされるイベント void movieEvent( Movie m ) { //カレント位置の画像を取得 m.read(); //フレーム読み取り時間更新 getFrameTime = frameCount ; } void mouseClicked( MouseEvent e ){ //範囲外がクリックされたら何もしない if( mouseY < 0 || mouseY > height || mouseX < 0 || mouseX > width ){ return; } //スピードを制御 if( e.getButton() == LEFT ){ //左クリックなら加速 iSpeed++; } else { //右クリックなら減速 iSpeed--; } if( iSpeed != 0 ){ //再生速度変更 movie.speed( iSpeed ); } if( iSpeed == 0 ){ //SPEEDが0なら一時停止 movie.pause(); isPlay = false; //停止中 } else { //再生開始 movie.play(); isPlay = true; //再生中 //フレーム読み取り時間更新 getFrameTime = frameCount ; } } |
動画を右クリックすると再生速度が加速します。左クリックなら減速します。
最初は停止状態から始まり、右クリックで加速する(速度が1になる)事で、再生が始まります。
動画の早送り・巻き戻しで映像が停止した事を検知するため、フレーム時間を利用しています。
動画映像は、味噌や発酵食品で有名なマルコメ株式会社 様のテレビCMの1コマです。年頃の娘と父の家族愛を伝える素敵な動画です。
今回動画の掲載に関し、マルコメ株式会社 様より寛大なご許可を得ることができました。謹んでお礼申し上げます。
なお当サイトから動画を流用する行為は禁止とさせて頂いております。悪しからずご了承ください。
下記はサンプルプログラムと同じ動きになるように、 P5.js+P5.dom で書き直したものです。動作イメージを確認できます。※
※ブラウザーによっては下記サンプルが表示されない事があります。また逆再生は多くのブラウザーで未サポートです。逆再生サポート:Chrome:✕ FireFox:✕ IE11:✕ Edge:△
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。