Qt笔记_音视频播放

音视频播放

Qt Multimedia模块提供了丰富的接口,分别提供了一组QML类型和一组C++类,这里只讨论C++类
多媒体功能及相关C++类

功能 示例 C++类
播放音效 QSoundEffect
播放低延迟音频 audioinput,spectrum QAudioOutput
播放编码音频(MP3、AAC等) player QMediaPlayer
访问原始音频输入数据 spectrum,audioinput QAudioInput
录制编码音频数据 audiorecorder QAudioRecorder
发现原始音频设备 audiodevices QAudioDeviceInfo
播放视频 player QMediaPlayer、QVideoWidget、QGraphicsVideoItem
处理视频 QMediaPlayer、QAbstractVideoSurface、QVideoFrame
收听录音机 QRadioTuner、QRadioData
访问相机取景器 camera QCamera、QVideoWidget、QGraphicsVideoItem
处理取景器 QCamera、QAbstractVideoSurface、QVideoFrame
拍摄照片 camera QCamera、QCameraImageCapture
拍摄视频 camera QCamera、QMediaRecorder

Qt的多媒体接口建立在底层平台的多媒体框架之上。意味着对于各种编解码器的支持依赖于使用的平台。平台相关参考Multimedia Backend Development文档。

播放音频

最简单的有QApplication::beep()。
或者播放文件

    player =new QMediaPlayer;
    player->setMedia(QUrl::fromLocalFile("/hhh.mp3"));
    player->play();

QSoundEffect类可以使用一种低延迟方式来播放未压缩的音频文件,如WAV文件。适合用于提示音。
.pro文件中添加

QT + = core gui multimedia ;

头文件中添加前置声明
添加头文件< QSoundEffect >

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    effect = new QSoundEffect(this);
    effect->setSource(QUrl::fromLocalFile("../mysoundeffect/sound.wav"));
    effect->setVolume(0.25f);

}
MainWindow::~MainWindow()
{
    delete ui;
}
// 播放按钮
void MainWindow::on_pushButton_clicked()
{
    effect->play();
}
// 停止按钮
void MainWindow::on_pushButton_2_clicked()
{
    effect->stop();
}
void MainWindow::on_spinBox_valueChanged(int arg1)
{
    effect->setLoopCount(arg1);
}

设置为无限次播放,需要设置QSoundEffect::Infinite;

视频播放

播放视频文件

视频文件可以通过QMediaPlayer进行播放,通常配合QVideoWidget或者QGraphicsVideoItem类使用。
使用QVideoWidget可以设置视频的亮度、对比度、色相和饱和度、全屏设置等。
.pro文件添加

multimedia multimediawidgets

头文件中添加

class QMediaPlayer
class QVideoWidget

#include "widget.h"
#include "ui_widget.h"
#include 
#include 

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    player = new QMediaPlayer(this);
    videoWidget = new QVideoWidget(this);
    videoWidget->resize(600, 300);
    player->setVideoOutput(videoWidget);
    player->setMedia(QUrl::fromLocalFile("../myvideowidget/video.wmv"));
    player->play();

    // 亮度
    ui->brightnessSlider->setValue(videoWidget->brightness());
    connect(ui->brightnessSlider, &QSlider::sliderMoved,
            videoWidget, &QVideoWidget::setBrightness);
    connect(videoWidget, &QVideoWidget::brightnessChanged,
            ui->brightnessSlider, &QSlider::setValue);
    // 对比度
    ui->contrastSlider->setValue(videoWidget->contrast());
    connect(ui->contrastSlider, &QSlider::sliderMoved,
            videoWidget, &QVideoWidget::setContrast);
    connect(videoWidget, &QVideoWidget::contrastChanged,
            ui->contrastSlider, &QSlider::setValue);
    // 色相
    ui->hueSlider->setValue(videoWidget->hue());
    connect(ui->hueSlider, &QSlider::sliderMoved,
            videoWidget, &QVideoWidget::setHue);
    connect(videoWidget, &QVideoWidget::hueChanged,
            ui->hueSlider, &QSlider::setValue);
    // 饱和度
    ui->saturationSlider->setValue(videoWidget->saturation());
    connect(ui->saturationSlider, &QSlider::sliderMoved,
            videoWidget, &QVideoWidget::setSaturation);
    connect(videoWidget, &QVideoWidget::saturationChanged,
            ui->saturationSlider, &QSlider::setValue);
}

Widget::~Widget()
{
    delete ui;
}

另一种实现:

#include 
#include 
#include 
#include 
#include 

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

    QGraphicsScene scene;
    QGraphicsView view(&scene);
    view.resize(600, 320);
    QGraphicsVideoItem item;
    scene.addItem(&item);
    item.setSize(QSizeF(500, 300));
    QMediaPlayer player;
    player.setVideoOutput(&item);
    player.setMedia(QUrl::fromLocalFile("../myvideoitem/video.wmv"));
    player.play();
    view.show();

    return a.exec();
}

使用QMovie播放GIF文件

可以参考Movie Example示例

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 设置标签的对齐方式为居中对齐、自动填充背景为暗色
    ui->label->setAlignment(Qt::AlignCenter);
    ui->label->setBackgroundRole(QPalette::Dark);
    ui->label->setAutoFillBackground(true);
    movie = new QMovie(this);
    movie->setFileName("../mymovie/movie.gif");
    // 设置缓存模式
    movie->setCacheMode(QMovie::CacheAll);
    // 设置动画大小为标签的大小
    QSize size = ui->label->size();
    movie->setScaledSize(size);
    ui->label->setMovie(movie);
    // 设置水平滑块的最大最小值,当动画播放时自动更改滑块的值
    ui->horizontalSlider->setMinimum(0);
    ui->horizontalSlider->setMaximum(movie->frameCount());
    connect(movie, &QMovie::frameChanged,
            ui->horizontalSlider, &QSlider::setValue);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_horizontalSlider_valueChanged(int value)
{// 播放进度
    movie->jumpToFrame(value);
}

void MainWindow::on_pushButton_clicked()
{// 开始按钮
    movie->start();
}

void MainWindow::on_pushButton_2_toggled(bool checked)
{// 暂停按钮
    movie->setPaused(checked);
}

void MainWindow::on_pushButton_3_clicked()
{// 停止按钮
    movie->stop();
}

void MainWindow::on_pushButton_4_clicked()
{// 截屏按钮
    int id = movie->currentFrameNumber();
    QPixmap pix = movie->currentPixmap();
    pix.save(QString("../mymovie/%1.png").arg(id));
}

void MainWindow::on_spinBox_valueChanged(int arg1)
{// 播放速度
    movie->setSpeed(arg1);
}

QMediaPlayer

用法类似

播放状态

当QMediaPlayer使用setMedia()设置了媒体后,setMedia()函数会直接返回,并不等待媒体加载完成,也不会检查可能存在的错误。

  • 当媒体的状况发生改变时播放器会发射mediaStatusChanged()信号,有9种不同的状况,由QMediaPlayer::MediaStatus枚举类型定义。
  • 播放器发生错误时会发射error()信号,有6种情况,由QMediaPlayer::Error枚举定义。
  • 播放时有3种状态,由QMediaPlayer::State枚举定义。

可以使用QMediaPlayer的metaData()函数来获取媒体的元数据。元数据可用时都会发射metaDataAvailableChanged()信号,可以关联该信号来获取当前媒体相关信息。

QMediaPlayer可以通过setPlaylist()来设置一个播放列表。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    player = new QMediaPlayer(this);
//    player->setMedia(QUrl::fromLocalFile("E:/src/13/13-5/myplayer/music.mp3"));
    connect(player, &QMediaPlayer::positionChanged,
            this, &MainWindow::updatePosition);

    connect(player, &QMediaPlayer::stateChanged, this, &MainWindow::stateChanged);
    connect(player, &QMediaPlayer::mediaStatusChanged,
            this, &MainWindow::mediaStatusChanged);
    connect(player, static_cast<void(QMediaPlayer::*)(QMediaPlayer::Error)>
            (&QMediaPlayer::error), this, &MainWindow::showError);

    connect(player, &QMediaPlayer::metaDataAvailableChanged,
            this, &MainWindow::metaDataAvailableChanged);


    playlist = new QMediaPlaylist;
    playlist->addMedia(QUrl::fromLocalFile("E:/src/13/13-5/myplayer/music.mp3"));
    playlist->addMedia(QUrl::fromLocalFile("E:/src/13/13-5/myplayer/music2.mp3"));
    playlist->addMedia(QUrl::fromLocalFile("E:/src/13/13-5/myplayer/music3.mp3"));
    playlist->setCurrentIndex(0);
    playlist->setPlaybackMode(QMediaPlaylist::Loop);
    player->setPlaylist(playlist);
}


MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{ // 播放
    player->play();
}

void MainWindow::on_pushButton_2_clicked()
{ // 暂停
    player->pause();
}

void MainWindow::on_pushButton_3_clicked()
{ // 停止
    player->stop();
}


void MainWindow::on_horizontalSlider_sliderMoved(int position)
{ // 设置播放进度
    player->setPosition(position * 1000);
}

void MainWindow::updatePosition(qint64 position)
{ // 更新滑块显示
    ui->horizontalSlider->setMaximum(player->duration() / 1000);
    ui->horizontalSlider->setValue(position / 1000);
}

void MainWindow::mediaStatusChanged(QMediaPlayer::MediaStatus status)
{
    switch (status) {
    case QMediaPlayer::UnknownMediaStatus:
        ui->label->setText(tr("媒体未知状况!"));
        break;
    case QMediaPlayer::NoMedia:
        ui->label->setText(tr("没有媒体文件!"));
        break;
    case QMediaPlayer::BufferingMedia:
        ui->label->setText(tr("正在缓冲媒体文件!"));
        break;
    case QMediaPlayer::BufferedMedia:
        ui->label->setText(tr("媒体文件缓冲完成!"));
        break;
    case QMediaPlayer::LoadingMedia:
        ui->label->setText(tr("正在加载媒体!"));
        break;
    case QMediaPlayer::StalledMedia:
        ui->label->setText(tr("播放停滞!"));
        break;
    case QMediaPlayer::EndOfMedia:
        ui->label->setText(tr("播放结束!"));
        break;
    case QMediaPlayer::LoadedMedia:
        ui->label->setText(tr("媒体加载完成!"));
        break;
    case QMediaPlayer::InvalidMedia:
        ui->label->setText(tr("不可用的媒体文件!"));
        break;
    default: break;
    }
}

void MainWindow::stateChanged(QMediaPlayer::State state)
{
    switch (state) {
    case QMediaPlayer::StoppedState:
        ui->label_2->setText(tr("停止状态!"));
        break;
    case QMediaPlayer::PlayingState:
        ui->label_2->setText(tr("播放状态!"));
        break;
    case QMediaPlayer::PausedState:
        ui->label_2->setText(tr("暂停状态!"));
        break;
    default: break;
    }
}

void MainWindow::showError(QMediaPlayer::Error error)
{
    switch (error) {
    case QMediaPlayer::NoError:
        ui->label_3->setText(tr("没有错误!"));
        break;
    case QMediaPlayer::ResourceError:
        ui->label_3->setText(tr("媒体资源无法被解析!"));
        break;
    case QMediaPlayer::FormatError:
        ui->label_3->setText(tr("不支持该媒体格式!"));
        break;
    case QMediaPlayer::NetworkError:
        ui->label_3->setText(tr("发生了一个网络错误!"));
        break;
    case QMediaPlayer::AccessDeniedError:
        ui->label_3->setText(tr("没有播放权限!"));
        break;
    case QMediaPlayer::ServiceMissingError:
        ui->label_3->setText(tr("没有发现有效的播放服务!"));
        break;
    default: break;
    }
}

// 获取元数据
void MainWindow::metaDataAvailableChanged(bool available)
{
    if(available) {
        QString title = player->metaData("Title").toString();
        QString author = player->metaData("Author").toString();
        setWindowTitle(title + "-" + author);
    }
}

你可能感兴趣的:(Qt)