QML与ffmpeg实现简单视频播放(无音频处理)

1 篇文章 0 订阅

QML绘制参考链接:https://blog.csdn.net/cxc233/article/details/80382696

ffmpeg参考链接:http://blog.yundiantech.com/?log=blog&id=11

 

视频绘制类

继承QQuickPaintedItem可以使用QPainter接口将一帧解码QImage绘制到Qml上面。(XVideo是QQuickPaintedItem的子类)当接收到一帧(QImage)的时候直接调用update()更新 

 

视频解码类

ffmpeg解码的代码网上很多例子,可参考开头给出的链接,这里主要讲一下视频同步的问题。

视频同步

参考的链接中给出的同步方案有一种是通过对音频时间的记录音频的时间来显示视频达到同步的效果,因工作中得到的视频文件中没有音频,所以此方法不适用。另一种方法是通过记录播放时的主时钟时间与视频数据中的时间比较来达到视频同步,本文章就采用这种方法。

这里简单贴一段代码:

int64_t start_time = av_gettime();
while (1)
{
    if (av_read_frame(pFormatCtx, packet) < 0)
    {
        break; //这里认为视频读取完了
    }

    int64_t realTime = av_gettime() - start_time; //主时钟时间

    while(pts > realTime)
    {
        msleep(10);
        realTime = av_gettime() - start_time; //主时钟时间
    }

    if (packet->stream_index == videoStream)
    {
        ...
        ...
        pts = packet->dts;
        pts *= 1000000 * av_q2d(mVideoState.video_st->time_base);
        ...
        ...
        if(got_picture)
        {
            ...
            emit sig_GetOneFrame(image);
        }
    }

    ...
}

视频暂停/播放,停止功能

因为视频的同步播放是基于系统主时钟实现的,所以暂停和播放功能必须对记录的start_time作调整,否则暂停后播放就会有一种"追赶"的现象。

下面贴出关键代码:

int64_t start_time = av_gettime();
while (1)
{
    if( mPlayerState == Pause ) {
        emit sig_GetOneFrame(QImage());  //发送信号
        break;
    }
    if( mPlayerState == Stop ) {
        b_hasStopped = true;
        msleep(10);
        continue;
    }

    //暂停重新开启,重置启动时间
    if( b_hasStopped ) {
        start_time = av_gettime() - pts;
    }

    if (av_read_frame(pFormatCtx, packet) < 0)
    {
        break; //这里认为视频读取完了
    }
    
    ...    
    if(git_picture)
    {
        ...
        emit sig_GetOneFrame(image);  //发送信号
        b_hasStopped = false;
    }
}

这里在暂停再次播放后,将start_time重新设置,其中pts为视频已播放的时间。

 

播放界面

界面做的很粗糙,进度条的跳转功能还未完成。

 

代码下载地址:https://download.csdn.net/download/w54a3teg64c7bd/10686106

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值