这个是之前写的添加暂停功能的文章
https://blog.csdn.net/Lj2_jOker/article/details/121970262?spm=1001.2014.3001.5502
既然实现了暂停,为什么不把进度条实现呢
解码部分代码
status = VideoProcess::__running;
emit f->statusChanged();
decode->old_dts_ms = 0;
qDebug() << QThread::currentThreadId() << "start play stream";
while (status > VideoProcess::__stop)
{
// 暂停视频
if( status == VideoProcess::__pause )
{
// 视频暂停状态更新
emit f->statusChanged();
qDebug() << "stream puase";
std::unique_lock<std::mutex> lock(mutex);
condition.wait(lock);
lock.unlock();
// 恢复播放状态更新
emit f->statusChanged();
}
read_stream_mutex.lock();
res = av_read_frame(decode->fmtCnt, &decode->packet);
if( res < 0 )
{
read_stream_mutex.unlock();
status = VideoProcess::__stop;
decode->current_time = decode->total_time;
emit f->frame(img);
qDebug() << "read stream finished";
emit f->statusChanged();
break;
}
if( decode->packet.stream_index == decode->video_index )
{
res = avcodec_send_packet(decode->codecCnt, &decode->packet);
if( res < 0 ) {
read_stream_mutex.unlock();
continue;
}
res = avcodec_receive_frame(decode->codecCnt, decode->frame);
if( res < 0 ) {
read_stream_mutex.unlock();
continue;
}
int64_t cur_dts = decode->packet.dts;
decode->cur_dts_ms = cur_dts * av_q2d(decode->stream->time_base) * 1000;
// 当前的播放时间, 单位秒
decode->current_time = cur_dts * av_q2d(decode->stream->time_base);
sws_scale(decode->sws,
decode->frame->data, decode->frame->linesize, 0, decode->frame->height,
decode->rgbFrame->data, decode->rgbFrame->linesize);
emit f->frame(img);
int wait_ms = decode->cur_dts_ms - decode->old_dts_ms;
// 帧间隔延时
if( wait_ms > 0 ) {
std::this_thread::sleep_for(std::chrono::milliseconds(wait_ms));
}
decode->old_dts_ms = decode->cur_dts_ms;
}
read_stream_mutex.unlock();
}
read_stream_mutex 是QMutex不是std::mutex
使用std::mutex的效果不知道为什么有问题
对比之前的代码,修改了帧间隔等待的代码
快进快退代码
void seek(const int &msec)
{
if( !decode && status > VideoProcess::__stop ) {
return;
}
read_stream_mutex.lock();
int64_t usec = msec * 1000;
int ret = av_seek_frame(decode->fmtCnt, -1, usec, AVSEEK_FLAG_BACKWARD);
if( ret >= 0 ) {
decode->old_dts_ms = usec / 1000;
avcodec_flush_buffers(decode->codecCnt);
}
read_stream_mutex.unlock();
}
视频总时间获取
// fmtCnt 为 AVFormatContext
decode->total_time = decode->fmtCnt->duration / 1000000.0;
进度条算法
进度条的进度 = 当前播放时间 / 总时间 * 进度条宽度