【Qt】之音视频编程2:QtAV的使用篇

QtAV 基本播放控制功能实现(C++ & QML)

QtAV 提供了完整的播放控制 API,支持 播放、暂停、停止、快进快退、截屏 等功能。以下是具体实现方法:


1. C++ 控制方式

基本播放控制

cpp 复制代码
#include <QtAV>
#include <QtAV/AVPlayer.h>

// 初始化播放器
QtAV::AVPlayer player;

// 设置播放文件
player.setFile("video.mp4");  

// 播放
player.play();

// 暂停
player.pause();

// 继续播放(从暂停状态恢复)
player.play();  // 重新播放 或 player.togglePause(); 从播放位置继续播放

// 停止(重置状态)
player.stop();

快进/快退(跳转进度)

cpp 复制代码
// 快进 10 秒
qint64 currentPos = player.position();
player.seek(currentPos + 10000);  // 单位:毫秒

// 快退 5 秒
player.seek(currentPos - 5000); // 重载形式1 直接设置毫秒

// 跳转到 50% 进度
player.seek(0.5); // 重载形式2 直接设置进度

总时长 player.duration()

截屏(保存当前帧)

cpp 复制代码
// 截屏并保存为 PNG
QtAV::VideoOutput *videoOutput = new QtAV::VideoOutput;
player.setRenderer(videoOutput);

// 捕获当前帧
QImage image = videoOutput->frame();
image.save("screenshot.png");

2. QML 控制方式

基本播放控制

qml 复制代码
import QtQuick 2.0
import QtAV 1.7

Item {
    width: 800
    height: 600

    AVPlayer {
        id: avPlayer
        source: "video.mp4"
    }

    VideoOutput {
        source: avPlayer
        anchors.fill: parent
    }

    // 播放/暂停按钮
    Button {
        text: avPlayer.isPlaying ? "暂停" : "播放"
        onClicked: avPlayer.isPlaying ? avPlayer.pause() : avPlayer.play()
    }

    // 停止按钮
    Button {
        text: "停止"
        onClicked: avPlayer.stop()
    }
}

快进/快退

qml 复制代码
// 快进 10 秒
Button {
    text: "快进"
    onClicked: avPlayer.seek(avPlayer.position + 10000)
}

// 快退 5 秒
Button {
    text: "快退"
    onClicked: avPlayer.seek(avPlayer.position - 5000)
}

截屏

qml 复制代码
Button {
    text: "截屏"
    onClicked: {
        const image = videoOutput.captureFrame()
        image.save("screenshot.png")
    }
}

3. 进阶功能

播放速度控制

cpp 复制代码
// 2 倍速播放
player.setSpeed(2.0);

// 0.5 倍慢放
player.setSpeed(0.5);

音量控制

cpp 复制代码
player.audio()->setVolume(0.5);  // 0~1.0

获取播放信息

cpp 复制代码
qint64 totalTime = player.duration();  // 总时长(毫秒) play播放后才能获取到
qint64 currentTime = player.position(); // 当前进度
bool isPlaying = player.isPlaying();

4. 信号与槽(监听状态)

cpp 复制代码
// 监听播放状态变化
connect(&player, &AVPlayer::stateChanged, [](QtAV::AVPlayer::State state) {
    if (state == QtAV::AVPlayer::PlayingState) {
        qDebug() << "开始播放";
    } else if (state == QtAV::AVPlayer::PausedState) {
        qDebug() << "已暂停";
    }
});

// 监听进度变化
connect(&player, &AVPlayer::positionChanged, [](qint64 pos) {
    qDebug() << "当前进度:" << pos;
});

5. 完整示例(C++ 播放器)

cpp 复制代码
#include <QApplication>
#include <QtAV>
#include <QtAV/AVPlayer.h>
#include <QtAV/VideoOutput.h>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    QtAV::AVPlayer player;
    QtAV::VideoOutput output;
    output.setRenderer(&player);

    player.setFile("video.mp4");
    player.play();

    // 窗口显示
    output.widget()->show();

    return a.exec();
}

总结

功能 C++ 方法 QML 属性/方法
播放 player.play() avPlayer.play()
暂停 player.pause() avPlayer.pause()
停止 player.stop() avPlayer.stop()
快进/快退 player.seek(pos + 10000) avPlayer.seek(pos + 10000)
截屏 videoOutput->frame().save() videoOutput.captureFrame()
倍速播放 player.setSpeed(2.0) avPlayer.playbackRate = 2.0

将 QtAV 播放窗口集成到自定义界面(C++ & QML)

你可以通过 Qt Widgets(C++)QML 方式将 QtAV 的播放窗口嵌入到自己的 UI 中,并在下方添加控制按钮。以下是两种实现方法:


1. C++ 方式(Qt Widgets)

目标布局

复制代码
+-----------------------+
|      QtAV 播放窗口      |
+-----------------------+
| [播放] [暂停] [停止] ... |
+-----------------------+

代码实现

cpp 复制代码
#include <QApplication>
#include <QtAV>
#include <QtAV/AVPlayer.h>
#include <QtAV/VideoOutput.h>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 主窗口
    QWidget mainWindow;
    mainWindow.setWindowTitle("自定义播放器");
    mainWindow.resize(800, 600);

    // 垂直布局
    QVBoxLayout *layout = new QVBoxLayout(&mainWindow);

    // 1. 添加 QtAV 播放窗口
    QtAV::AVPlayer *player = new QtAV::AVPlayer;
    QtAV::VideoOutput *videoOutput = new QtAV::VideoOutput;
    player->setRenderer(videoOutput);
    player->setFile("video.mp4");

    // 将 VideoOutput 的 QWidget 添加到布局
    layout->addWidget(videoOutput->widget());

    // 2. 添加控制按钮
    QHBoxLayout *buttonLayout = new QHBoxLayout;

    QPushButton *playButton = new QPushButton("播放");
    QPushButton *pauseButton = new QPushButton("暂停");
    QPushButton *stopButton = new QPushButton("停止");
    QPushButton *screenshotButton = new QPushButton("截屏");

    buttonLayout->addWidget(playButton);
    buttonLayout->addWidget(pauseButton);
    buttonLayout->addWidget(stopButton);
    buttonLayout->addWidget(screenshotButton);

    layout->addLayout(buttonLayout);

    // 按钮信号槽连接
    QObject::connect(playButton, &QPushButton::clicked, [player]() {
        player->play();
    });
    QObject::connect(pauseButton, &QPushButton::clicked, [player]() {
        player->pause();
    });
    QObject::connect(stopButton, &QPushButton::clicked, [player]() {
        player->stop();
    });
    QObject::connect(screenshotButton, &QPushButton::clicked, [videoOutput]() {
        QImage image = videoOutput->frame();
        image.save("screenshot.png");
        qDebug() << "截图已保存!";
    });

    mainWindow.show();
    return app.exec();
}

关键点

  1. VideoOutput::widget()
    将 QtAV 的视频渲染器转换为 QWidget,嵌入到你的布局中。
  2. 使用 QVBoxLayout + QHBoxLayout
    垂直排列播放窗口和按钮栏,水平排列按钮。
  3. 信号槽控制播放器
    通过按钮的 clicked 信号调用 AVPlayer 的对应方法。

2. QML 方式(更简洁的 UI 设计)

目标布局

qml 复制代码
ColumnLayout {
    VideoOutput { /* 播放窗口 */ }
    RowLayout { /* 按钮行 */ }
}

代码实现

qml 复制代码
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtAV 1.7

ApplicationWindow {
    width: 800
    height: 600
    visible: true
    title: "QML 自定义播放器"

    ColumnLayout {
        anchors.fill: parent

        // 1. 播放窗口
        VideoOutput {
            id: videoOutput
            Layout.fillWidth: true
            Layout.fillHeight: true
            source: avPlayer
        }

        // 2. 按钮控制栏
        RowLayout {
            Layout.alignment: Qt.AlignHCenter

            Button {
                text: avPlayer.isPlaying ? "暂停" : "播放"
                onClicked: avPlayer.isPlaying ? avPlayer.pause() : avPlayer.play()
            }
            Button {
                text: "停止"
                onClicked: avPlayer.stop()
            }
            Button {
                text: "快进+10s"
                onClicked: avPlayer.seek(avPlayer.position + 10000)
            }
            Button {
                text: "截屏"
                onClicked: {
                    const image = videoOutput.captureFrame()
                    image.save("screenshot.png")
                    console.log("截图已保存!")
                }
            }
        }
    }

    // 播放器实例
    AVPlayer {
        id: avPlayer
        source: "video.mp4"
    }
}

关键点

  1. VideoOutput 绑定 AVPlayer
    通过 source: avPlayer 关联播放器和渲染窗口。
  2. 动态按钮文本
    avPlayer.isPlaying 控制"播放/暂停"按钮的文本切换。
  3. captureFrame() 截屏
    直接调用 VideoOutput 的接口保存当前帧。

3. 进阶优化

(1) 进度条控制(C++ 示例)

cpp 复制代码
// 添加 QSlider 到布局
QSlider *progressSlider = new QSlider(Qt::Horizontal);
layout->addWidget(progressSlider);

// 更新进度条
QObject::connect(player, &QtAV::AVPlayer::positionChanged, [=](qint64 pos) {
    progressSlider->setValue(pos);
});
QObject::connect(progressSlider, &QSlider::sliderMoved, [=](int value) {
    player->seek(value);
});

(2) 音量控制(QML 示例)

qml 复制代码
Slider {
    from: 0
    to: 100
    value: 50
    onMoved: avPlayer.audio.volume = value
}
相关推荐
macken99997 分钟前
音频分类的学习
人工智能·深度学习·学习·计算机视觉·音视频
水水沝淼㵘24 分钟前
嵌入式开发学习日志(数据结构--单链表)Day20
c语言·开发语言·数据结构·学习·算法
举一个梨子zz25 分钟前
Java—— 可变参数、集合工具类、集合嵌套、不可变集合
java·开发语言·intellij-idea·需求分析
iangyu29 分钟前
【windows server脚本每天从网络盘复制到本地】
开发语言·windows·php
程序员拂雨36 分钟前
Python知识框架
开发语言·python
泽020243 分钟前
C++类和对象之相关特性
java·开发语言·c++
敲键盘的小夜猫1 小时前
深入理解Python逻辑判断、循环与推导式(附实战案例)
开发语言·python
feiyangqingyun1 小时前
Qt/C++开发监控GB28181系统/录像文件查询/录像回放/倍速播放/录像文件下载
c++·qt·gb28181·录像回放·录像文件下载
为自己_带盐2 小时前
浅聊一下数据库的索引优化
开发语言·数据库·php
明月看潮生2 小时前
青少年编程与数学 02-019 Rust 编程基础 12课题、所有权系统
开发语言·青少年编程·rust·编程与数学