您的位置:首页 > 理论基础 > 计算机网络

在电视端网络视频播放加载一个视频预览的方法(电视基于安卓系统)

2015-10-26 15:42 801 查看
前提条件:

在pc上播放网络视频的时候,有一个视频预览,当鼠标移动到某个点的时候,会显示当前视频帧的图片,在Android设备上,安装第三方网络应用,通过自己写的apk来进行视频预览,因为受限于网络抽帧等限制,暂时只能抽取某几个时间点的帧进行预览:

步骤:

1、首先写一个广播来接受按键显示视频预览,悬浮在视频apk的上面,界面必须是透明的,不然会影响视频的播放,广播来接受按键或者当视频启动的时候接受从am发送过来的广播; if(action.equals("TV_LongPressDownKey")){

Log.d(TAG, "videopreivew  onkey");

Intent in = new Intent(context, VideoPreviewService.class);

in.putExtra("cmd", "onkey");

ComponentName cn = context.startService(in);

Log.d(TAG, "cn-----" + cn.getPackageName());

Log.d(TAG, "videopreivew start service");

}

if(action.equals("com.changhong.online.videopreview.start")){

Log.d(TAG, "videopreivew  start");

Intent in = new Intent(context, VideoPreviewService.class);

in.putExtra("cmd", "start");

ComponentName cn = context.startService(in);

Log.d(TAG, "cn-----" + cn.getPackageName());

Log.d(TAG, "videopreivew start service online");

}

通过广播启动service,第一次启动service的时候,会执行service的oncreate方法,再执行onstart方法,后面的启动service都是只执行onstart方法,可以通过在onstart方法里面接受Intent来获取传递的值,如果中间service停止运行,会再次启动,public void onStart(Intent intent, int startId) ,这个intent可能为空,需要加上判断;

2.通过jni调用来获取底层的mediaplayer的接口,获取当前时间,总时长,已经到了某个点seekto();totalTime = jniGetDuration();
currentTime = jniGetCurrentPosition();
url = jniGetUrl();
int resolution = jniGetResolution();

static {
System.loadLibrary("playercontrol");
}

public native int jniSeekTo(int msec);

public native int jniGetDuration();

public native int jniGetCurrentPosition();

3.通过ffmpeg来抽帧:

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
Map<String, String> headers = new HashMap<String, String>();
headers.put("X-tv-Retriever-Player", "USE_FFMPEG");
retriever.setDataSource(url, headers);
new MyTask().execute(url);

class MyTask extends AsyncTask<String, Void, ArrayList<Bitmap>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}

@Override
protected ArrayList<Bitmap> doInBackground(String... params) {
Log.d(TAG, "AsyncTask ------");
FileOutputStream fos = null;
try {
bm1 = retriever.getFrameAtTime(totalTime / 6 * 1000L);
fos = new FileOutputStream(previewImageOne);
bm1.compress(CompressFormat.JPEG, 80, fos);
fos.close();

bm2 = retriever.getFrameAtTime(2 * totalTime / 6 * 1000L);
fos = new FileOutputStream(previewImageTwo);
bm2.compress(CompressFormat.JPEG, 80, fos);
fos.close();

bm3 = retriever.getFrameAtTime(3 * totalTime / 6 * 1000L);
fos = new FileOutputStream(previewImageThree);
bm3.compress(CompressFormat.JPEG, 80, fos);
fos.close();

bm4 = retriever.getFrameAtTime(4 * totalTime / 6 * 1000L);
fos = new FileOutputStream(previewImageFour);
bm4.compress(CompressFormat.JPEG, 80, fos);
fos.close();

bm5 = retriever.getFrameAtTime(5 * totalTime / 6 * 1000L);
fos = new FileOutputStream(previewImageFive);
bm5.compress(CompressFormat.JPEG, 80, fos);
fos.close();

Log.d(TAG, "AsyncTask ---doInBackground end ---");

mHandler.sendEmptyMessage(SHOW_IMAGE);
} catch (Exception e) {
e.printStackTrace();
}
return bmList;
}

@Override
protected void onPostExecute(ArrayList<Bitmap> result) {
super.onPostExecute(result);
}
}

4.在WindowManager上显示图片

WindowManager mWM = (WindowManager) mcontext.getSystemService(Context.WINDOW_SERVICE);

WindowManager.LayoutParams mLP = new WindowManager.LayoutParams();
mLP.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
mLP.width = WindowManager.LayoutParams.MATCH_PARENT;
mLP.height = WindowManager.LayoutParams.MATCH_PARENT;
mLP.format = PixelFormat.RGBA_8888;
mLP.dimAmount = 0;
mLP.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND;
mWM.addView(mVpView, mLP);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: