首先进度条采用Qslider,设置进度条主要有两点,一是当前视频总时长,二是当前播放时长,需要通过FFmpeg转码成mp4文件才能获取相应的时长数据;
往期回顾:
【Qt+FFmpeg】视频转码详细流程_logani的博客-CSDN博客_qt+ffmpeg视频流
【Qt+FFmpeg】编码视频详细流程_logani的博客-CSDN博客_qt 视频编码
【Qt+FFmpeg】解码播放本地视频(一)_logani的博客-CSDN博客_ffmpeg 打开本地视频
1.获取视频总时长
视频时长就封装在 AVFormatContext *formatContext 编解码上下文环境结构体的 duration 结构体成员中 ;AVFormatContext 中提取的 duration获取总视频总时长,单位是微秒;
2.获取当前时长:
AVFrame 结构体中封装的 best_effort_timestamp 元素值,就是当前视频帧的相对播放时间,其单位是AVRational,需要转换成秒,可以用视频流中提供的时间基
3.进行拖动跳转
在知道如何做之前,我们要先了解Qslider的几个信号,我们拖动时就需要用到点击、滑动和释放信号:
1.移动滑动条时发出的信号
void sliderMove(int value);
2.点击滑动条时所发出的信号
void sliderPressed();
3.释放时所发出的信号
void sliderReleased();
拖动跳转主要用到滑动信号和释放信号;
调用av_seek_frame函数查找进度条点击或拖动位置的帧数并跳转到该帧开始播放 ;
由于上述的播放时间已转成了秒为单位,所以这边将传入的秒转为微秒
av_seek_frame ( ) 函数原型 : 查找第 stream_index 个媒体流的 timestamp 微秒附近的关键帧 , 并跳转到该帧开始播放 ;
① AVFormatContext **ps 参数 : 封装了文件格式相关信息的结构体 , 如视频宽高 , 音频采样率等信息 ; 该参数是 二级指针 , 意味着在方法中会修改该指针的指向 , 该参数的实际作用是当做返回值用的 ;
② int stream_index 参数 : 音视频流索引 , 如果设置 -1 , 说明是所有的媒体流同时跳转 ;
③ int64_t timestamp 参数 : 要跳转的目的时间戳 , 之后要在该时间附近查找关键帧 ;
④ int flags 参数 : 设置跳转模式 ;
⑤ int 返回值 : 返回值大于等于 0 , 代表打开成功 , 否则失败 ;
为了在用户拖动过程中不修改slider的值,这边采用定时器在拖动时暂停修改进度条,释放进度条时再开启定时器;
/*****************************************************************
* 函数名称::sliderMoveSlot()
* 功能描述:拖动进度条,停止定时器
* 参数说明: 无
* 返回值: 无
******************************************************************/
void playbackVideowin::sliderMoveSlot()
{
//暂时停止计时器,在用户拖动过程中不修改slider的值
timer->stop();
}
/*****************************************************************
* 函数名称::sliderReleaseSlot()
* 功能描述:释放进度条,重启定时器,修改视频当前位置
* 参数说明: 无
* 返回值: 无
******************************************************************/
void playbackVideowin::sliderReleaseSlot()
{
timer->start(40);
int currentValue=playProgressBar->value();
pDeCoding->changeCurrentValue(currentValue);
}
4.进行点击跳转,重写一个进度条类
因为系统自带的进度条点击时只能移动一小段,不能实现点哪就移动到哪,所以我们要自己重写一个进度条类
void newqslider::mousePressEvent(QMouseEvent *ev)
{
//先调用父类的鼠标点击处理事件,这样可以不影响拖动的情况
QSlider::mousePressEvent(ev);
//获取鼠标的位置,这里并不能直接从ev中取值(因为如果是拖动的话,鼠标开始点击的位置没有意义了)
double pos = ev->pos().x() / (double)width();
setValue(pos * (maximum() - minimum()) + minimum());
//发送自定义的鼠标单击信号
emit costomSliderClicked();
}
进度条点击槽函数
/*****************************************************************
* 函数名称::sliderClickedSlot()
* 功能描述:点击进度条
* 参数说明: 无
* 返回值: 无
******************************************************************/
void playbackVideowin::sliderClickedSlot()
{
int currentValue=playProgressBar->value();
pDeCoding->changeCurrentValue(currentValue);
}
信号槽连接
本文借鉴了
【Android FFMPEG 开发】FFMPEG 视频播放进度控制 ( 显示播放进度 | 拖动进度条播放 )_韩曙亮的博客-CSDN博客_安卓开发 ffmpeg如何获取视频当前播放进度
感谢观看!!!!
以上就是全部内容,如果对您有帮助,欢迎点赞评论,或者发现有哪里写错的,欢迎指正!