Qt音视频开发26-ffmpeg播放器
一、前言
用ffmpeg来实现自己的播放器,这是一直以来的一个目标,之前的难点卡在音视频同步以及如何播放声音这两点(尽管之前已经进行过不少的尝试和探索,但是问题还是挺多,比如音视频同步不完美,有些文件正常而有些文件不准,声音播放采用的sdl总感觉多了个依赖怪怪的,而且很多初学者也反映希望采用Qt自身的类来播放),近期正好把这两个难点一一攻破了,音视频同步采用的外部时钟同步,声音播放采用的Qt自带的QAudioOutput(并没有采用sdl,省去学习sdl开源库的成本),播放器的demo如期进行。有时候做项目,如果将各个难点击破以后,接下来都是顺理成章水到渠成的事情,速度会非常快,这也是我经常用的策略。
最简单基本播放器具备的功能:
- 播放、关闭、暂停、继续。
- 音量调节、静音设置。
- 进度调节、定位播放。
- 总时长、已播放时长。
- 音频、视频、本地文件、视频流。
前面几篇文章写了音视频同步、音频播放、音量设置、静音设置,这里就差一个进度调节、定位播放的处理了,ffmpeg内置了av_seek_frame函数负责定位播放帧,总共4个参数,含义分别如下:
- 参数1 AVFormatContext *s 表示处理媒体对象的上下文。
- 参数2 int stream_index 表示流的索引,填-1表示自动默认流索引。
- 参数3 int64_t timestamp 表示要定位的时间,单位是微妙,如果传入的是秒则需要 * AV_TIME_BASE。
- 参数4 int flags 表示如何定位和查找使用的策略,建议选择AVSEEK_FLAG_BACKWARD,其余参数容易花屏。
- 返回值 >= 0 表示成功。
二、功能特点
- 多线程实时播放视频流+本地视频+USB摄像头等。
- 支持windows+linux+mac,支持ffmpeg3和ffmpeg4,支持32位和64位。
- 多线程显示图像,不卡主界面。
- 自动重连网络摄像头。
- 可设置边框大小即偏移量和边框颜色。
- 可设置是否绘制OSD标签即标签文本或图片和标签位置。
- 可设置两种OSD位置和风格。
- 可设置是否保存到文件以及文件名。
- 可直接拖曳文件到ffmpegwidget控件播放。
- 支持h265视频流+rtmp等常见视频流。
- 可暂停播放和继续播放。
- 支持存储单个视频文件和定时存储视频文件。
- 自定义顶部悬浮条,发送单击信号通知,可设置是否启用。
- 可设置画面拉伸填充或者等比例填充。
- 可设置解码是速度优先、质量优先、均衡处理。
- 可对视频进行截图(原始图片)和截屏。
- 录像文件存储支持裸流和MP4文件。
- 音视频完美同步,采用外部时钟同步策略。
- 支持seek定位播放位置。
- 支持qsv、dxva2、d3d11va等硬解码。
- 支持opengl绘制视频数据,极低CPU占用。
- 支持安卓和嵌入式linux,交叉编译即可。
三、效果图

四、相关站点
- 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
- 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
- 个人主页:https://blog.csdn.net/feiyangqingyun
- 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
- 体验地址:https://blog.csdn.net/feiyangqingyun/article/details/97565652
五、核心代码
uint FFmpegThread::getLength()
{
return duration * 1000;
}
uint FFmpegThread::getPosition()
{
return 0;
}
void FFmpegThread::setPosition(int position)
{
if (this->isRunning() && !isRtsp && !isUsbCamera) {
pause();
QThread::msleep(100);
videoSync->clear();
audioSync->clear();
int64_t timestamp = ((double)position / 1000.0) * AV_TIME_BASE;
av_seek_frame(formatCtx, -1, timestamp, AVSEEK_FLAG_BACKWARD);
next();
}
}
void FFmpegThread::play()
{
//通过标志位让线程执行初始化
isPlay = true;
isPause = false;
}
void FFmpegThread::pause()
{
//只对本地文件起作用
playAudio = false;
if (!isRtsp && !isUsbCamera && !isPause) {
isPause = true;
}
}
void FFmpegThread::next()
{
//只对本地文件起作用
playAudio = true;
if (!isRtsp && !isUsbCamera && isPause) {
isPause = false;
videoSync->reset();
audioSync->reset();
}
}
void FFmpegThread::stop()
{
//通过标志位让线程停止
stopped = true;
}
void FFmpegThread::snap()
{
//通过标志位来截图 句柄模式才需要
if (!callback) {
isSnap = true;
}
}
Qt音视频开发26-ffmpeg播放器的更多相关文章
- 【秒懂音视频开发】12_播放WAV
对于WAV文件来说,可以直接使用ffplay命令播放,而且不用像PCM那样增加额外的参数.因为WAV的文件头中已经包含了相关的音频参数信息. ffplay in.wav 接下来演示一下如何使用SDL播 ...
- 【秒懂音视频开发】02_Windows开发环境搭建
音视频开发库的选择 每个主流平台基本都有自己的音视频开发库(API),用以处理音视频数据,比如: iOS:AVFoundation.AudioUnit等 Android:MediaPlayer.Med ...
- Android 音视频开发(一):PCM 格式音频的播放与采集
什么是 PCM 格式 声音从模拟信号转化为数字信号的技术,经过采样.量化.编码三个过程将模拟信号数字化. 采样 顾名思义,对模拟信号采集样本,该过程是从时间上对信号进行数字化,例如每秒采集 44100 ...
- 音视频开发-FFmpeg
音视频开发是个非常复杂的,庞大的开发话题,初涉其中,先看一下结合 OEIP(开源项目) 新增例子. 可以打开flv,mp4类型文件,以及rtmp协议音视频数据,声音的播放使用SDL. 把采集的麦/声卡 ...
- WebRTC 音视频开发
WebRTC 音视频开发 webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译 ...
- Android 音视频开发学习思路
Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...
- 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)
随笔分类 - webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...
- ffmpeg播放器实现详解 - 视频显示
ffplay是ffmpeg源码中一个自带的开源播放器实例,同时支持本地视频文件的播放以及在线流媒体播放,功能非常强大. FFplay: FFplay is a very simple and port ...
- ffmpeg播放器实现详解 - 框架搭建
ffplay是ffmpeg源码中一个自带的开源播放器实例,同时支持本地视频文件的播放以及在线流媒体播放,功能非常强大. FFplay: FFplay is a very simple and port ...
- Android音视频开发(1):H264 基本原理
前言 H264 视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的.随着 x264/openh264 以及 ffmpeg 等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大 ...
随机推荐
- Cut the Sequence(单调队列DP+set)
题面 大意:一段长度为n的序列,分成若干段,每段值的总和不能超过m,求各段中最大值加起来的最小值. 其实最朴素的DP还是很好想的,以f[i]表示i及i以前已经分好所需的最小值,a[i]表示i点的值,那 ...
- KubeSphere Helm 应用仓库源码分析
作者:蔡锡生,LStack 平台研发工程师,近期专注于基于 OAM 的应用托管平台落地. 背景介绍 KubeSphere 应用商店简介 作为一个开源的.以应用为中心的容器平台,KubeSphere 在 ...
- 会话层技术-session
会话层技术-session session技术拿下! 一.先整理学习过程中的几个疑惑 cookie和session分别都是怎么创建的? 首先cookie是一个类,它需要java后端开发人员手动创建. ...
- RecyclerView刷新方式
RecyclerView刷新方式 刷新全部item notifyDataSetChanged() student.setValue(new Student("二狗")); stud ...
- 【速记】C++ STL自定义排序
因为是"速记",难免会有不完善的地方.这篇笔记咱日后应该还会进行补充. 关于sort的比较函数 void sort( RandomIt first, RandomIt last, ...
- Win11右键默认显示更多设置
以管理员方式运行CMD,运行: reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2} ...
- spring下 -spring整体架构,JdbcTemplate笔记
2,搭建Java Maven项目 我的idea是2024.1.1版本,创建普通Maven项目如下图: 用的jdk8,项目名可以自己改,Archetype选图中的第一个就行,之后点 create. 创建 ...
- C240817C. 团队协作:二分答案+贪心
C240817C. 团队协作 二分显然,但是被check难住了. 以为只能把运动员按速度分成两类,然后二分图找最大匹配,但显然做不动. 然后考场上就被卡住了--- 看了题解突然勾起了对一道题远古的记忆 ...
- Java里快如闪电的线程间通讯
这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...
- Spring 开发 Swing GUI 简介
依赖注入和富客户机 Chad Woolley (thewoolleyman@gmail.com), 软件开发人员, Ionami 简介: 本教程介绍了 Spring 框架以及依赖注入的概念(也称为反 ...