android获取视频关键帧时间,Android 播放视频并获取指定时间的帧画面

[摘要:比来做的项目请求既能播放视频(近似于视频播放器),又能每隔1s摆布猎取一帧视频绘里,然后对图片举行处置惩罚,观察了一周,也被熬煎了一周,总算找到了大抵相符请求的方式。起首对]

最近做的项目要求既能播放视频(类似于视频播放器),又能每隔1s左右获取一帧视频画面,然后对图片进行处理,调查了一周,也被折磨了一周,总算找到了大致符合要求的方法。首先对调查过程中涉及到的方法进行简单介绍,再重点介绍最终所采用的方法,话不多说,进入正题。

一.MediaMetadataRetriever

播放视频并取得画面的一帧,大家最先想到应该都是这个,我同样也最先对它进行了测试,这里使用MediaPlayer进行播放,视频播放界面使用SurfaceView来实现。

public class PlayerMainActivity extends Activity implements OnClickListener,

SurfaceHolder.Callback, Runnable {

private static final String TAG = "Movie";

private MediaPlayer mediaPlayer;

private SurfaceView surfaceView;

private SurfaceHolder surfaceHolder;

private Button play_btn;private int currentPosition = 0;

private Bitmap bitmap = null;

private String dataPath = Environment.getExternalStorageDirectory() + "/Video/Test_movie.AVI";

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

surfaceView = (SurfaceView) findViewById(R.id.surfaceView);

play_btn = (Button) findViewById(R.id.play_btn);

play_btn.setOnClickListener(this);

screen_cut_btn.setOnClickListener(this);

surfaceHolder = surfaceView.getHolder();

surfaceHolder.addCallback(this);

}

@Override

public void run() {

mediaPlayer = new MediaPlayer();

mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

mediaPlayer.setDisplay(surfaceHolder);

try {

mediaPlayer.setDataSource(dataPath);

mediaPlayer.prepare();

MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();

mediaMetadataRetriever.setDataSource(dataPath);

int millis = mediaPlayer.getDuration();

Log.i(TAG, "millis: " + millis/1000);

for (int i = 10000*1000; i < 20*1000*1000; i+=500*1000) {

bitmap = mediaMetadataRetriever.getFrameAtTime(i, MediaMetadataRetriever.OPTION_CLOSEST);

String path = Environment.getExternalStorageDirectory() + "/bitmap/" + i + ".png";

FileOutputStream fileOutputStream = null;

try {

fileOutputStream = new FileOutputStream(path);

bitmap.compress(CompressFormat.PNG, 100, fileOutputStream);

Log.i(TAG, "i: " + i/1000/1000);

} catch (Exception e) {

Log.i(TAG, "Error: " + i/1000/1000);

e.printStackTrace();

}

finally {

if (fileOutputStream != null) {

fileOutputStream.close();

}

}

bitmap.recycle();

}

} catch (Exception e) {

e.printStackTrace();

}

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

Thread t = new Thread(this);

t.start();

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

}

@Override

public void onClick(View view) {

switch (view.getId()) {

case R.id.play_btn:

if (mediaPlayer.isPlaying()) {

mediaPlayer.pause();

play_btn.setText(getResources().getText(R.string.play));

} else {

mediaPlayer.start();

play_btn.setText(getResources().getText(R.string.pause));

}

break;default:

break;

}

}

@Override

protected void onDestroy() {

super.onDestroy();

if (mediaPlayer.isPlaying()) {

mediaPlayer.stop();

}

mediaPlayer.release();

}

}

获取一帧的关键代码为:

Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(timeMs * 1000, MediaMetadataRetriever.OPTION_CLOSEST);

public Bitmap getFrameAtTime(long timeUs, int option)

第一个参数是传入时间,只能是us(微秒)

第二个参数:

OPTION_CLOSEST    在给定的时间,检索最近一个帧,这个帧不一定是关键帧。

OPTION_CLOSEST_SYNC   在给定的时间,检索最近一个同步与数据源相关联的的帧(关键帧)。

OPTION_NEXT_SYNC 在给定时间之后检索一个同步与数据源相关联的关键帧。

OPTION_PREVIOUS_SYNC  顾名思义,

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值