Qt笔记_音视频播放

音视频播放


Qt Multimedia模块提供了丰富的接口,分别提供了一组QML类型和一组C++类,这里只讨论C++类

多媒体功能及相关C++类

功能示例C++类
播放音效QSoundEffect
播放低延迟音频audioinput,spectrumQAudioOutput
播放编码音频(MP3、AAC等)playerQMediaPlayer
访问原始音频输入数据spectrum,audioinputQAudioInput
录制编码音频数据audiorecorderQAudioRecorder
发现原始音频设备audiodevicesQAudioDeviceInfo
播放视频playerQMediaPlayer、QVideoWidget、QGraphicsVideoItem
处理视频QMediaPlayer、QAbstractVideoSurface、QVideoFrame
收听录音机QRadioTuner、QRadioData
访问相机取景器cameraQCamera、QVideoWidget、QGraphicsVideoItem
处理取景器QCamera、QAbstractVideoSurface、QVideoFrame
拍摄照片cameraQCamera、QCameraImageCapture
拍摄视频cameraQCamera、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 <QMediaPlayer>
#include <QVideoWidget>

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 <QApplication>
#include <QMediaPlayer>
#include <QGraphicsVideoItem>
#include <QGraphicsView>
#include <QGraphicsScene>

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 <QMovie>

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 <QMediaPlaylist>

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);
    }
}
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于Linux的Qt FFmpeg音视频播放是一种使用Qt框架和FFmpeg库在Linux操作系统上实现音视频播放的方法。 Qt是一种跨平台的应用程序开发框架,它提供了丰富的图形用户界面(GUI)组件和功能,便于开发人员创建各种类型的应用程序。而FFmpeg是一个开源的音视频处理库,它提供了处理音视频文件、编解码和转换等功能。 在基于Linux的Qt FFmpeg音视频播放中,首先需要使用Qt提供的界面设计工具创建一个用户界面,可以包含播放按钮、进度条、音量控制等控件。然后,通过Qt的信号与槽机制将这些控件与相应的函数连接起来。 接下来,需要使用FFmpeg库来解码和播放音视频文件。通过FFmpeg提供的API,可以打开音视频文件并获取其音频和视频流。然后,使用FFmpeg的解码功能将音频和视频流解码为原始的音频和视频数据。最后,使用Qt的音频和视频播放功能,将解码后的数据进行播放。 同时,基于Linux的Qt FFmpeg音视频播放还可以实现其他功能,比如暂停、快进、快退等操作。这些功能可以通过控制音频和视频的时间戳来实现。 总之,基于Linux的Qt FFmpeg音视频播放提供了一种灵活、可定制的方式来实现音视频播放功能。它可以适用于各种需求,比如嵌入式设备上的音视频播放、音频编辑和处理等。同时,Qt的跨平台特性也使得这种方法可以在其他操作系统上实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值