如标题所示这一篇主要实现简单的实现视屏流,视屏流,视屏流的播放实现,而不是“视屏播放“,所以不会涉及到“音频流“,或者“字幕流“的播放。放张图简单说明一下:
如上图标注的地方“Stream 0“——视屏流,“Stream 1“——音频流。实际视屏文件中可能还会有“字幕流“,但这又涉及到“内置字幕/硬字幕“和“外挂字幕“的相关知识,这些不在本文讨论范围内(上图特意找了一个有字幕但没有“字幕流“的视屏截图,也是为了说明这种情况——“硬字幕“直接内嵌在视屏流当中,没有单独的“字幕流“)。
如果对这样的说法有些不理解,个人推荐一篇博客《[总结]视音频编解码技术零基础学习方法》
另外其实雷神其他相关音视频方面的博客也都强烈推荐,相信看完他的文章你会收益更多。
本篇文章是基于我的上一篇Android 使用 FFmpeg (一)——编译生成.so文件来写的但在项目目录结构上有所改动,所以有需要的话可以去看一下。
一,项目结构
如上图
FFmpegNativeUtil类只是简单加载动态库,和声明一个native方法如下
public class FFmpegNativeUtil {
static {
System.loadLibrary("avcodec-57");
System.loadLibrary("avdevice-57");
System.loadLibrary("avfilter-6");
System.loadLibrary("avformat-57");
System.loadLibrary("avutil-55");
System.loadLibrary("postproc-54");
System.loadLibrary("swresample-2");
System.loadLibrary("swscale-4");
System.loadLibrary("native-lib");
}
/**
* 播放视频流
* @param videoPath(本地)视频文件路径
* @param surface
*/
public native void videoStreamPlay(String videoPath, Surface surface);
}
MyVideoView类继承SurfaceView 用来绘制视频图像。
public class MyVideoView extends SurfaceView {
FFmpegNativeUtil util;
Surface surface;
public MyVideoView(Context context) {
this(context,null);
}
public MyVideoView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public MyVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}