使用ffmepg,opengl es2.0,opensl播放视频

最近在看ffmpeg相关的知识,于是想使用ffmpeg实现最基本的视频解码播放的功能,查看了许多资料,于是有了一个基本思路:

  1. 使用ffmpeg解码视频获得音频数据和视频数据。
  2. 使用opengl绘制视频帧数据。
  3. 使用opensl播放音频数据。

下面是实现的截图

使用ffmepg,opengl es2.0,opensl播放视频_第1张图片
Screenshot_2017-04-24-15-15-12-699_com.example.tenny.myapplication1.png

下面具体实现,详细的代码 https://github.com/tenny1225/ffmpeg_android_video_player/tree/master

下面将需要注意的问题简单说一下。

ffmpeg的编译和引入

对于ffmpeg的编译,可以看一下http://blog.csdn.net/leixiaohua1020/article/details/47008825/ 这篇文章,可以生成一些列so文件,在我这个例子中,我使用了cmake方式引入so库,详情可以查看根目录下的CMakeLists.txt文件。

ffmpeg获取视频帧数据

在这个例子中,使用bool readFrame(FrameInfor &infor)方法循环获取视频帧数据,因为不同的视频每毫秒播放的帧数是不同的,所以这里需要控制一下播放速度。

class VideoThread :public Thread{
public:
    virtual void run() override {



        JNIEnv *en;
        time_t timep1 =GetUtcCaressing();//获取播放开始时的时间戳

        while(true){

            ffVideoReader.readFrame(p);//p是获取的FrameInfor数据
            if(p._data==0){
                break;
            }
           /**
           p._timeBase是单位秒,p._pts是该帧播放的时间,d这里是微秒
          **/
            double d = p._timeBase*p._pts*1000*1000;
         
           /**刷新glsurfaceview**/
            g_jvm->AttachCurrentThread(&en, NULL);
            jclass clazz = en->GetObjectClass(g_obj);
            jmethodID mid =en->GetMethodID(clazz,"refresh","()V");
            en->CallObjectMethod(g_obj,mid);
            g_jvm->DetachCurrentThread();

            time_t timep2=GetUtcCaressing();//获取获取视频帧后的时间戳

           
            double temp = timep2-timep1;//获取帧数据消耗的时间
            double sleeps = d-temp;//sleeps是需要等待的微秒数
            if(sleeps>1){
                usleep(sleeps);
            }

        }
    }
};

你可能感兴趣的:(使用ffmepg,opengl es2.0,opensl播放视频)