介绍

QtAV 是一个基于 Qt 和 FFmpeg 的跨平台、高性能多媒体播放框架,能够帮助你轻而易举地编写出一个播放器。
【Qt 开源音视频框架模块QtAV】01:介绍、编译以及简单使用

因为网上使用QTAV的使用方法还比较少,所以下面做了一些整理。
参考例程:海天鹰媒体播放器_QtAV版

程序功能效果展示

程序功能:本地视频播放、url播放、播放速度调节、音量调节、窗口旋转、截图、剧情连拍、音轨选择、播放直播源等功能在这里插入图片描述

初始化播放器

下面提到的player是AVPlayer这个类的实例化对象 videoItem是GraphicsItemRenderer这个类的实例化对象

    player = new AVPlayer(this);
    videoItem = new GraphicsItemRenderer;
    QGraphicsScene *scene = new QGraphicsScene(this);
    scene->addItem(videoItem);
    ui->graphicsView->setScene(scene);
    player->setRenderer(videoItem);

GraphicsItemRenderer与VideoOutput 区别

GraphicsItemRenderer

#define GraphicsWidget QGraphicsWidget
#else
#define GraphicsWidget QGraphicsObject
#endif

class Q_AVWIDGETS_EXPORT GraphicsItemRenderer : public GraphicsWidget, public QPainterRenderer
class Q_AV_EXPORT QPainterRenderer : public VideoRenderer

VideoOutput

VideoOutput : public QObject, public VideoRenderer

参看这两个类的父类不难发现 他们都继承与VideoRenderer
结论:
他们都是渲染器
如果你需要用到 QGraphics时 用GraphicsItemRenderer,需要QWidget时用 VideoOutput

播放器播放视频

player->play(path);
path 可以时url地址 也可以是本地地址 

播放器暂停视频

player->stop();

播放器暂停或继续播放

player->pause(true);  //暂停
player->pause(false); //继续播放

设置播放位置

player->setPosition(v);

修改播放音量

音量范围 0-1
player->audio()->setVolume(v/100.0);

旋转角度

  videoItem->setOrientation(videoItem->orientation()+90);

获取视频信息

 "媒体地址:" + player->statistics().url 
 "视频解码:" + player->statistics().video.decoder_detail 
 "音频解码:" + player->statistics().audio.decoder_detail 
 "分辨率:width" + QString::number(player->statistics().video_only.width) 
 "分辨率:height" + QString::number(player->statistics().video_only.height) 
 "文件大小:" + QFileInfo(player->statistics().url).size();  单位byte

修改播放器窗口大小

videoItem->resizeRenderer(ui->graphicsView->size());

调整播放速度

player->setSpeed(player->speed() + 0.1)//加速
player->setSpeed( player->speed() - 0.1 ); //减速

获取音轨数量

player->audioStreamCount()

修改音频源

player->setAudioStream(action->data().toInt());

获取预览图

// 预览图
VideoPreviewWidget *m_preview;    
void MainWindow::preview(int value)
{    
    int w = 100;
    int h = 70;
    m_preview->setFile(player->file());
    m_preview->setTimestamp(value);
    m_preview->preview();
    //m_preview->setWindowFlags(m_preview->windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    m_preview->setWindowFlags(m_preview->windowFlags() | Qt::WindowStaysOnTopHint);
    m_preview->resize(w,h);
    m_preview->move(cursor().pos().x()-w/2 , cursor().pos().y()-h-20);
    m_preview->show();
}

截图播放器当前图片

player->videoCapture()->setAutoSave(true);
//自动保存在 /home/用户名/Pictures ,不需要手动保存。
player->videoCapture()->capture();

在这里插入图片描述
player->videoCapture() 还可以设置截图质量 截图保存位置 名称 文件格式等

播放器信号

//开始播放信号
connect(player, SIGNAL(started()), SLOT(durationChange()));
//播放位置
connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(positionChange(qint64)));
//音频音量改变
connect(player->audio(), SIGNAL(volumeChanged(qreal)), this, SLOT(volumeChange(qreal)));
//视频图片抓取成功信号
connect(player->videoCapture(), SIGNAL(imageCaptured(QImage)), SLOT(saveImage(QImage)));
//播放错误
connect(player, SIGNAL(error(QtAV::AVError)), this, SLOT(handleError(QtAV::AVError)));
//播放状态改变
connect(player,SIGNAL(stateChanged(QtAV::AVPlayer::State)),this,SLOT(stateChange(QtAV::AVPlayer::State)));

剧情连拍功能,核心代码

在这里插入图片描述

void MainWindow::on_action_capture16_triggered()
{
    cn = 16;
    cnn = 0;
    player->pause(false);
    player->audio()->setMute(true);
    player->videoCapture()->setAutoSave(false);
    QImage imageDS = QImage(1280+50,960+80+40,QImage::Format_RGB32);
    imageDS.fill(Qt::white);
    int k = 0;
    QPainter painter(&imageDS);
    painter.drawPixmap(20,10,QPixmap("icon.png").scaled(60,60));
    painter.drawText(300,30,"文件名称:" + QFileInfo(filename).fileName());
    painter.drawText(300,60,"文件大小:" + SB(QFileInfo(filename).size()));
    painter.drawText(500,60,"视频尺寸:" + QString::number(player->statistics().video_only.width) + " X " + QString::number(player->statistics().video_only.height));
    QTime t(0,0,0);
    t = t.addMSecs(player->duration());
    QString STimeTotal = t.toString("hh:mm:ss");
    painter.drawText(700,60,"视频时长:" + STimeTotal);
    for( qint64 i = player->duration()/16; i < player->duration(); i += player->duration()/16 ) {
        player->setPosition(i);
        player->videoCapture()->capture();  //截图成功后保存图片到容器 connect(player->videoCapture(), SIGNAL(imageCaptured(QImage)), SLOT(saveImage(QImage)));
        QEventLoop eventloop;
        QTimer::singleShot(1000, &eventloop, SLOT(quit()));
        eventloop.exec();
    }
    for(int y=0; y<4; y++ ) {
        for(int x=0; x<4; x++){
            //QImage imgtemp=imagec[k].scaled(320,240);
            painter.drawImage(x*(320+10)+10,y*(240+10)+80,imagec[k]);
            k++;
        }
    }
    QFont font("Arial",20,QFont::Normal,false);
    painter.setFont(font);
    painter.drawText(100,50,"海天鹰播放器");
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
    QString filepath = QDesktopServices::openUrl(QDesktopServices::storageLocation(QDesktopServices::PicturesLocation))+ "/Summary_"+QFileInfo(filename).baseName()+".jpg";
#else
    QString filepath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/Summary_" + QFileInfo(filename).baseName()+".jpg";
#endif
    imageDS.save(filepath,0,100);
    player->audio()->setMute(false);
    labelTL->setText("剧情连拍 " + filepath);
    labelTL->adjustSize();
    labelTL->show();
    QTimer::singleShot(3000,this,SLOT(timeoutTL()));
}

播放直播源,核心代码

void MainWindow::playTV(int row,int column)
{
    Q_UNUSED(column);
    labelTL->hide();
    mode = "live";
    QString surl = ui->tableWidget->item(row,1)->text();
    QString realurl = "";
    if(surl.contains("http://vdn.live.cntv.cn/api2/live.do?channel=")){
        qDebug() << "analyze(" << surl << ")";
        QUrl url = QString(surl);
        QNetworkAccessManager *NAM = new QNetworkAccessManager;
        QNetworkRequest request(url);
        QNetworkReply *reply = NAM->get(request);
        QEventLoop loop;
        connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
        loop.exec();
        QByteArray responseText = reply->readAll();
        QJsonDocument json = QJsonDocument::fromJson(responseText);
        QString hls_url = json.object().value("hls_url").toObject().value("hls4").toString();
        //qDebug() << "play(" << hls_url << ")";
        //player->play(hls_url);
        realurl = hls_url;
    }else if(surl.contains("http://apiv1.starschina.com/cms/v1.0/stream?")){
        qDebug() << "analyze(" << surl << ")";
        QUrl url = QString(surl);
        QNetworkAccessManager *NAM = new QNetworkAccessManager;
        QNetworkRequest request(url);
        QNetworkReply *reply = NAM->get(request);
        QEventLoop loop;
        connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
        loop.exec();
        QByteArray responseText = reply->readAll();
        QJsonDocument json = QJsonDocument::fromJson(responseText);
        QJsonArray play_urls = json.object().value("data").toObject().value("play_urls").toArray();
        QString urls = play_urls.last().toObject().value("urls").toArray()[0].toString();
        //qDebug() << "play(" << urls << ")";
        //player->play(urls);
        realurl = urls;
    }else if(surl.contains("http://live.api.hunantv.com/pc/getById?")){
        qDebug() << "analyze(" << surl << ")";
        QUrl url = QString(surl);
        QNetworkAccessManager *NAM = new QNetworkAccessManager;
        QNetworkRequest request(url);
        QNetworkReply *reply = NAM->get(request);
        QEventLoop loop;
        connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
        loop.exec();
        QByteArray responseText = reply->readAll();
        QJsonDocument json = QJsonDocument::fromJson(responseText);
        QJsonArray html5Sources = json.object().value("data").toObject().value("html5Sources").toArray();
        QString urls = html5Sources.last().toObject().value("url").toString();
        //qDebug() << "play(" << urls << ")";
        //player->play(urls);
        realurl = urls;
    }else{
        //qDebug() << "play(" << surl << ")";
        //player->play(surl);
        realurl = surl;
    }
    qDebug() << "play(" << realurl << ")";
    player->play(realurl);
    addHistory(realurl);
    setWindowTitle(ui->tableWidget->item(row,0)->text());
    setFocus();
}

【Qt 开源音视频框架模块QtAV】01:介绍、编译以及简单使用
【Qt 开源音视频框架模块QtAV】02:QTAV自带的DEMO
【Qt 开源音视频框架模块QtAV】03:QTAV主要接口展示以及播放器源码分享

Logo

为开发者提供按需使用的算力基础设施。

更多推荐