在电视端网络视频播放加载一个视频预览的方法(电视基于安卓系统)
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);
在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);
相关文章推荐
- 一种在本地搭载一个服务器的工具和方法,Android开发测试网络视频可以用
- ImageLoader下载图片
- Toast 数据加载,内容加载,网络图片加载提示
- JVM通过代理服务器连接网络的参数设置
- php模拟HTTP响应
- http和socket之长连接和短连接区别
- 网络编程 笔记(十)多播与广播
- 七层网络协议
- win7下AdHoc网络设置共享外网上网
- http长轮询&短轮询
- 网络爬虫讲解(附Java实现的实例)
- 网络传输中的三张表,MAC地址表、ARP缓存表以及路由表
- 解决eclipse安装maven的问题:Unable to update index for central|http://repo1.maven.org/maven2
- 网络发送同步请求——(开发中一般不会使用,但是还是了解的好)
- 6.网络编程
- HTTP 请求未经客户端身份验证方案“Anonymous”授权。
- mvc4 http错误403.14 forbidden
- http头部缓存设置
- socket网络编程复习笔记(一):套接字基本原理(上)
- Windows五个网络IO模型(服务器用)