2011年11月30日水曜日

[Android][Help]動画のコマ送り・コマ戻しの方法(注:できてないです)

Androidで動画のコマ送り・コマ戻しがしたいのですが、
 数日調べて分からなかったので調査結果だけをメモします。

 ・Androidではフレームごとのデータを取得する方法がAPIでは用意されていない。
  (VideoView や MediaPlayerではそのようなAPIがないということ。)

 ・MediaMetadataRetriever を使えば、指定の時間の画像を取得できそうだが、
試してみると先頭 / 先頭+1のフレームしか取れない。 http://developer.android.com/reference/android/media/MediaMetadataRetriever.html

 MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(getApplicationContext(), uri); int time = 1500; // 取得したい時間(ms)
 Bitmap bitmap = mmr.getFrameAtTime(time);
 //mmr.getFrameAtTime(time, MediaMetadataRetriever.OPTION_NEXT_SYNC); // 先頭の次のフレーム取得する
 //mmr.getFrameAtTime(time, MediaMetadataRetriever.OPTION_PREVIOUS_SYNC); // 先頭フレーム取得する
//mmr.getFrameAtTime(time, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
if(bitmap != null) {
 imageView.setImageBitmap(bitmap);
 } 

・VideoView / MediaPlayer のseekTo()で指定秒数に飛ばしてすぐにpause()すると、
映像が更新されない。
 // ボタン押したら、コマ送り
 button.setOnClickListener(new OnClickListener() {
 @Override
 public void onClick(View v) {
 int pos = mMediaPlayer.getCurrentPosition();
 // mMediaPlayer.start();       // 絵が更新されないので、再生してみる(→更新されない)
 mMediaPlayer.seekTo(pos + 150); // 150ms加算してコマ送り
 mMediaPlayer.start();       // 絵が更新されないので、再生してみる(→更新されない)
 videoView.invalidate();     // 強制的に描画(→更新されない)
 mMediaPlayer.pause();
 }
 } 

・MediaPlayer でシーク完了(setOnSeekCompleteListener)したときに処理しても、映像が更新されない
// ボタン押したら、コマ送り
 button.setOnClickListener(
new OnClickListener() {
 @Override
 public void onClick(View v) { 
int pos = mMediaPlayer.getCurrentPosition();
 mMediaPlayer.seekTo(pos + 150); // 150ms加算してコマ送り
 }
 }

 // button押下後、イベントはきている
mMediaPlayer.setOnSeekCompleteListener(new OnSeekCompleteListener() {
 @Override
 public void onSeekComplete(MediaPlayer mp) {
 if(isSeek) {
 int time = mp.getCurrentPosition();
 mp.start();
 mp.pause();
 }
 }
 });

 なぜなぜ分析してみる
 ・getFrameAtTime()で先頭フレームしか取得できないのはなぜ?
  パラメータの設定の仕方が悪いの? 

・pause中のseekTo()で画像が更新されないのは理解できるとして、
  pause -> start()したときに画像が更新されないのはなぜ?
 だれかヘルプm(__)m

 できたこと、わかったこと
・seekTo()とかgetFrameAtTime()使わずに、コマ送り(風)な処理はできました
 mMediaPlayer.start();  // 再生して、
try {
 Thread.sleep(33);      // 指定秒数スリープしたあとに、
 } catch (InterruptedException e) { }
mMediaPlayer.pause();        // 一時停止する

 ただこの方法だとコマ戻しができないのです。
コマ戻しするには秒数指定するしかないですよね。
困った。どうしましょう

2 件のコメント:

  1. 突然のコメント失礼します。
    getFrameAtTimeの時間はミリセカンドではなくマイクロセカンドだと思います。
    もしよければお試しください。

    返信削除
  2. コメントありがとうございます。
    マイクロセカンドなのですね。。

    試したところ、できました!!
    ありがとうございます。

    返信削除