具体代码请看:NDKPractice项目的ffmpeg87
1.调整音乐播放器项目架构
解码的流程 Video 和 Audio 很多相同的,所以抽离出来了公共类: Media.cpp
音频和视频单独处理成:Audio.cpp 和 Video.cpp,都继承自Media,cpp
遇到的问题:下面这个方法的env 不能使用 pJniCall->jniEnv
1 | void Video::setSurface(JNIEnv *env, jobject surface) { |
2. 视音频的同步
- pts:显示时间戳,用来告诉播放器该在什么时候显示这一帧数据。单位是不确定,所以使用时间基来获取单位
- time_base:时间度量单位(时间基)。
有三种办法:
- 参考一个外部时钟,将音频与视频同步至此时间。
- 以视频为基准,音频去同步视频的时间。
- 以音频为基准,视频去同步音频的时间。
由于某些生物学的原理,人对声音的变化比较敏感,但是对视觉变化不太敏感。所以采用方案 3
static inline double av_q2d(AVRational a)
:使用时间基获取单位timeBase = pFormatContext->streams[streamIndex]->time_base;
:获取时间基duration = pFormatContext->duration;
:获取音视频时长(单位微秒
)double times = av_frame_get_best_effort_timestamp(pFrame) * av_q2d(timeBase);
: 获取当前时间double times = pPacket->pts * av_q2d(timeBase);
: 获取当前时间av_usleep(frameSleepTime * 1000000);
:休眠(单位毫秒
)
1 | // 播放之前判断一下要休眠多久 |
还差:暂停,停止,回调,倍速播放,硬解码