在前面的文章中,我们已经能够加载 YUV 帧并显示了,那是把一张图片转换成 YUV 帧得到的素材。
如果是一个 YUV 视频文件的话,那就是很多 YUV 帧连续在一起,既然能展示一帧,那肯定可以连续展示多帧。
接下来就要这样的操作。
YUV 视频文件素材
还是要准备一下 YUV 视频素材,不用网上到处去下载,用 FFmpeg 命令将 mp4
文件转换成 yuv
文件就好了。
ffmpeg -i file_name.mp4 filename.yuv
命令很简单,其中 file_name
是文件的名称,使用时记得替换。
由于生成的 yuv 文件是未经过压缩的,文件过大不方便传 Github ,所以在程序运行前要自己去生成一下文件。
同样,也可以用 ffplay
验证一下 yuv 文件转换是否正确。
ffplay -f rawvideo -video_size 100x100 yuv_filename.yuv
以上命令会打开一个窗口去播放视频内容,如果播放的和原来 mp4 文件内容一致,说明转换是成功的,YUV 文件可用。
代码实践
接下来就是代码实践环节,很多地方和前一篇文章加载 YUV 文件并显示 是类似的。
// 打开文件 和 创建纹理 的代码和前一篇一样,不在放上来了
if (texture != nullptr){
SDL_Event windowEvent;
while (true){
if (SDL_PollEvent(&windowEvent)){
if (SDL_QUIT == windowEvent.type){
break;
}
}
// 读取内容
if (fread(yuv_data,1,frameSize,pFile) != frameSize){
// 读取内容小于 frameSize ,seek 到 0 ,重新读取,类似于重播
fseek(pFile,0,SEEK_SET);
fread(yuv_data,1,frameSize,pFile);
}
//
SDL_UpdateTexture(texture, nullptr,yuv_data,width);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer,texture, nullptr, nullptr);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_Quit();
}
打开文件和创建纹理代码内容和前面的一致,就不重新贴出来了。
YUV 内容转纹理以及渲染纹理上屏的操作也是一样的。
不同的是,读取 buffer 的操作放在了 while 里面。
如果对 SDL 的消息循环和事件响应还记得的话,就能明白每当 SDL_PollEvent 从消息队列中取出一个消息,只要不是退出事件,就会从 YUV 文件中读取 Buffer 并把它转成纹理渲染上屏。
如果读取的 Buffer 内容小于一帧 YUV 文件的大小,就会 Seek 到文件开头的位置,重新读取,类似于重播了。当然你也可以不重播,直接退出。
以下就是实际的运行效果:
以上的代码还是存在问题的,比如 YUV 视频播放的很快,比原来的 mp4 播放快多了。
这是因为播放的速率控制完全是根据 SDL_PollEvent 事件响应的速度来的,而不是根据 mp4 的帧率来播放。
可以通过自定义 SDL 事件,然后根据帧率控制自定义事件的发送速率,实现控制播放速度的目的。
另外,这里有很多参数都是事先知道的,比如视频宽高数据,在后面我们将通过 FFmpeg 来得到这些数据,实在真正的解码播放。
总结
以上就是音视频基础学习连载的 006
篇。
在实现加载 YUV 帧并显示的基础上,很容易就实现播放 YUV 视频文件了。
本文具体代码见仓库:
本篇文章对应的提交 tag
为 av-beginner-004
,可切换至对应源码查看。
能力有限,文中有不对之处,欢迎加我微信 ezglumes 进行交流~~
知识星球
公众号音视频开发进阶对应的知识星球,一个编程开发领域的专业圈子,贩卖知识和技巧! ※ 入群须知:了解该星球能提供的价值和帮助,在提问时务必阐述好背景,附带相关的信息。 iOS 用户可以加我微信 ezglumes 邀请你进星球,有疑问也可以加我微信咨询。 ※ 星球内容: 基础教程: 在知识星球连载的干货教程,可以在专栏中找到,随着时间的推移,教程也会越来越多: - 音视频基础概念 - WebRTC 入门教程及源码实践 - 播放器教程及源码实践 - OpenGL 和特效开发教程 - Vulkan 入门教程 部分内容可以在博客 https://glumes.com 中检索到,后面会在星球里持续更新. 干货分享: 涵盖了移动开发和音视频工程领域的绝大部分,从项目实战角度出发,提升能力,包括但不限于以下领域: - Android/iOS 移动开发 - Camera 开发 - 短视频编辑 SDK 项目实践 - 在线直播和推流 - WebRTC 开发 - 播放器基础和提高 - OpenGL 图像渲染及特效开发 - C++ 基础和提高 - FFmpeg 使用和分析 - 干货资源和书籍分享 不止于技术方面的,各种 IT 新闻、茶余饭后、生活趣事也欢迎大家分享!!! 技术答疑解惑: 针对上述基础教程和干货分享的答疑,另外还有音视频和 IT 开发中的各种交流讨论。 - 基础知识点答疑 - 工业项目实践答疑 - 问题排查思路分析 一个 BUG 排查很久,不如来星球里提个问题,效率提升百倍。 求职和面试辅导: 一站式职场服务,每份工作都值得用心对待!!! - 面试题和面试经验分享 - 简历修改和模拟面试 - 大厂内推和信息同步 - 职场经验分享 - 职业规划和发展分析 ※ 星主和合伙人介绍 星主是公众号音视频开发进阶的作者,也是网站 https://glumes.com 的作者,曾参与过抖音、剪映等头部音视频 APP 底层 SDK 的开发。 合伙人也是在头条、快手从事音视频架构师的职位,具有多年的音视频开发经验,能力圈覆盖了音视频的绝大多数领域,资深音视频从业人员为你保驾护航。
微信公众号
扫描下面的二维码关注我的微信公众号《音视频开发进阶》,推送更多精彩内容!
添加我的微信 ezglumes 拉你入音视频与图形图像技术群一起交流学习~

原创文章,转载请注明来源: 【音视频连载-006】基础学习篇-SDL 播放 YUV 视频文件