找回密码
 立即注册
Qt开源社区 门户 查看内容

QT软件开发-第八章 多媒体开发

2019-4-22 18:52| 发布者: admin| 查看: 4446| 评论: 0

摘要: 点击上方蓝字关注我们8.1 访问系统摄像头在Qt 5中,多媒体由Qt Multimedia模块提供支持。Phonon框架不再是Qt的一部分,但它仍然由Phonon开发人员维护并支持Qt 5。在QT5中,QCamera类为系统摄像头设备提供接口。QCame ...


点击上方蓝字关注我们




8.1 访问系统摄像头


    在Qt 5中,多媒体由Qt Multimedia模块提供支持。Phonon框架不再是Qt的一部分,但它仍然由Phonon开发人员维护并支持Qt 5。

    在QT5中,QCamera类为系统摄像头设备提供接口。

    QCamera可与QCameraViewfinder一起用于取景器显示,QMediaRecorder用于视频录制,QCameraImageCapture用于拍摄图像。你可以使用QCameraInfo列出可用摄像头并选择使用哪一个。

要使用相关的QCamera类,需要在pro工程文件中添加multimedia模块:

Header:#include <QCamera>

qmake:QT += multimedia

8.1.1 获取系统上可用的摄像头信息


QCameraInfo类提供有关摄像机设备的一般信息,允许查询系统当前可用的相机设备。

 静态函数defaultCamera()和availableCameras()提供了所有可用相机的列表。

下列例子打印所有可用相机的名称:

QList<QCameraInfo> cameras = QCameraInfo::availableCameras();

foreach (const QCameraInfo &cameraInfo, cameras)

qDebug() << cameraInfo.deviceName()

QCameraInfo可用于构建QCamera。

以下示例实例化一个QCamera,其相机设备名为'mycamera':

QList<QCameraInfo> cameras = QCameraInfo::availableCameras();

foreach (const QCameraInfo &cameraInfo, cameras)

{

      if (cameraInfo.deviceName() == "mycamera")

          camera = new QCamera(cameraInfo);

  }

你还可以使用QCameraInfo来获取有关相机设备的其他信息,如描述,系统上的物理位置或相机传感器方向等。

QCamera myCamera;

  QCameraInfo cameraInfo(myCamera);

  if (cameraInfo.position() == QCamera::FrontFace)

      qDebug() << "相机位于硬件系统的正面。";

  else if (cameraInfo.position() == QCamera::BackFace)

      qDebug() << "相机位于硬件系统的背面。";

  qDebug() << "相机传感器的方向是" << cameraInfo.orientation() << "度";

 获取系统默认的相机静态函数:

QCameraInfo QCameraInfo::defaultCamera()

返回系统上的默认摄像头。

在使用之前,应该使用isNull()检查返回的对象,以防没有默认相机或根本没有相机。

  • 示例代码:

QList<QCameraInfo> cameras = QCameraInfo::availableCameras();

    if(cameras.count())

    {

        for(int i=0;i<cameras.count();i++)

        {

            qDebug()<<"设备唯一ID:"<<cameras.at(i).deviceName();

            qDebug()<<"设备方向:"<<cameras.at(i).orientation();

        }

    }

    else

    {

        qDebug()<<"系统没有可用相机!";

    }

输出结果:

设备唯一ID:

"@device:pnp:\\\\?\\usb#vid_1908&pid_2310&mi_00#6&4a654b0&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global"

设备方向: 0

设备唯一ID:

"@device:pnp:\\\\?\\usb#vid_0bda&pid_58b9&mi_00#6&217f4020&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global"

设备方向: 0

8.1.2 QCamera类介绍


    1. 设置相机捕获图像的模式

    CaptureModescaptureMode() const

    voidsetCaptureMode(QCamera::CaptureModes mode)

支持的模式如下:

QCamera::CaptureViewfinder

0

取景器模式,只是简单的显示

QCamera::CaptureStillImage

0x1

帧捕获模式,比如:拍照

QCamera::CaptureVideo

0x02

视频捕获模式,比如:录制视频

    2. 启动与停止相机槽函数

void QCamera::start()  启动相机。相机状态QCamera::ActiveState

void QCamera::stop()   停止相机。相机状态QCamera::ActiveState 到 QCamera::LoadedState 改变

    3. 设置取景器显示的位置

void setViewfinder(QVideoWidget *viewfinder);  

设置基于QVideoWidget的相机取景器。

void setViewfinder(QGraphicsVideoItem *viewfinder);

设置QGraphicsVideoItem基于相机取景器。

void setViewfinder(QAbstractVideoSurface *surface);

将一个视频演示设置为相机的取景器。

8.1.3 相机取景器


    QCameraViewfinder类提供了一个相机取景器的小部件。QCameraViewfinder类继承于QVideoWidget类,用于显示多媒体类提供的视频。 (配套代码CH8-1)

  • 使用取景器配合QCamera显示摄像头的图像:

/*1. 获取系统默认的摄像头,创建摄像头对象*/

    QCamera *camera = new QCamera(QCameraInfo::defaultCamera());

    /*2. 创建取景器*/

    QCameraViewfinder *view_finder = new QCameraViewfinder();

    /*3. 将显示的位置加入到自己布局的窗口中*/

    ui->verticalLayout->addWidget(view_finder);

    /*4. 配置摄像头的模式--只是取景显示*/

    camera->setCaptureMode(QCamera::CaptureViewfinder);

    /*5. 设置取景器显示*/

    camera->setViewfinder(view_finder);

   /*6. 启动摄像头*/

  camera->start();



 图 8.1.1 取景器显示样图

8.1.4 捕获图像数据


    QCameraImageCapture类用于记录媒体内容。

    QCameraImageCapture类是高级图像记录类。它不是单独使用,而是用于访问其他媒体对象实现媒体录制功能,如QCamera。

    1. 判断设备是否支持捕获模式

bool QCameraImageCapture::isCaptureDestinationSupported(CaptureDestinations destination) const

如果支持捕捉目标图像,则返回true; 否则返回false。

    2. 设置图像捕获之后存放的位置

CaptureDestinations QCameraImageCapture::captureDestination() const

返回正在使用的图像捕捉模式。

void QCameraImageCapture::setCaptureDestination(CaptureDestinations destination)

设置要使用的捕获模式。

支持的目标模式:

QCameraImageCapture::CaptureToFile

0x01

捕获保存到文件

QCameraImageCapture::CaptureToBuffer

0x02

捕获到缓冲区,等待进一步处理

    3. 设置图像编码格式

void QCameraImageCapture::setEncodingSettings(const QImageEncoderSettings &settings)

设置图像编码格式,如果没有指定某些参数,或者传递了空设置,编码器将选择默认的编码参数。

QImageEncoderSettings QCameraImageCapture::encodingSettings() const

返回正在使用的图像编码器设置。

    QImageEncoderSettings类提供一组图像编码器设置。图像编码器设置对象用于指定QCameraImageCapture使用的图像编码器设置。通过构建QImageEncoderSettings对象,设置所需的属性,然后使用QCameraImageCapture :: setImageSettings()函数将其传递给QCameraImageCapture实例来选择图像编码器设置。

示例:

QImageEncoderSettings imageSettings;

imageSettings.setCodec("image/jpeg");

imageSettings.setResolution(1600, 1200);

imageCapture->setEncodingSettings(imageSettings);

    4. 设置缓冲区图像的格式

QList<QVideoFrame::PixelFormat> QCameraImageCapture::supportedBufferFormats() const

返回支持的缓冲区捕获格式列表。

void QCameraImageCapture::setBufferFormat(const QVideoFrame::PixelFormat format)

设置要使用的缓冲区图像捕捉格式。

QVideoFrame::PixelFormat QCameraImageCapture::bufferFormat() const

返回正在使用的缓冲图像捕捉格式。

支持的格式如下:

QVideoFrame::Format_Invalid

0

该框架无效。

QVideoFrame::Format_ARGB32

1

该帧使用32位ARGB格式(0xAARRGGBB)存储。这相当于QImage :: Format_ARGB32。

QVideoFrame::Format_ARGB32_Premultiplied

2

使用32位ARGB格式(0xAARRGGBB)存储帧。这相当于QImage :: Format_ARGB32_Premultiplied。

QVideoFrame::Format_RGB32

3

The frame stored using a 32-bit RGB format (0xffRRGGBB). This is equivalent to QImage::Format_RGB32

QVideoFrame::Format_RGB24

4

The frame is stored using a 24-bit RGB format (8-8-8). This is equivalent to QImage::Format_RGB888

QVideoFrame::Format_RGB565

5

The frame is stored using a 16-bit RGB format (5-6-5). This is equivalent to QImage::Format_RGB16.

QVideoFrame::Format_RGB555

6

The frame is stored using a 16-bit RGB format (5-5-5). This is equivalent to QImage::Format_RGB555.

QVideoFrame::Format_ARGB8565_Premultiplied

7

The frame is stored using a 24-bit premultiplied ARGB format (8-5-6-5).

QVideoFrame::Format_BGRA32

8

The frame is stored using a 32-bit BGRA format (0xBBGGRRAA).

QVideoFrame::Format_BGRA32_Premultiplied

9

The frame is stored using a premultiplied 32bit BGRA format.

QVideoFrame::Format_BGR32

10

The frame is stored using a 32-bit BGR format (0xBBGGRRff).

QVideoFrame::Format_BGR24

11

The frame is stored using a 24-bit BGR format (0xBBGGRR).

QVideoFrame::Format_BGR565

12

The frame is stored using a 16-bit BGR format (5-6-5).

QVideoFrame::Format_BGR555

13

The frame is stored using a 16-bit BGR format (5-5-5).

QVideoFrame::Format_BGRA5658_Premultiplied

14

The frame is stored using a 24-bit premultiplied BGRA format (5-6-5-8).

QVideoFrame::Format_AYUV444

15

The frame is stored using a packed 32-bit AYUV format (0xAAYYUUVV).

QVideoFrame::Format_AYUV444_Premultiplied

16

The frame is stored using a packed premultiplied 32-bit AYUV format (0xAAYYUUVV).

QVideoFrame::Format_YUV444

17

The frame is stored using a 24-bit packed YUV format (8-8-8).

QVideoFrame::Format_YUV420P

18

The frame is stored using an 8-bit per component planar YUV format with the U and V planes horizontally and vertically sub-sampled, i.e. the height and width of the U and V planes are half that of the Y plane.

QVideoFrame::Format_YV12

19

The frame is stored using an 8-bit per component planar YVU format with the V and U planes horizontally and vertically sub-sampled, i.e. the height and width of the V and U planes are half that of the Y plane.

QVideoFrame::Format_UYVY

20

The frame is stored using an 8-bit per component packed YUV format with the U and V planes horizontally sub-sampled (U-Y-V-Y), i.e. two horizontally adjacent pixels are stored as a 32-bit macropixel which has a Y value for each pixel and common U and V values.

QVideoFrame::Format_YUYV

21

The frame is stored using an 8-bit per component packed YUV format with the U and V planes horizontally sub-sampled (Y-U-Y-V), i.e. two horizontally adjacent pixels are stored as a 32-bit macropixel which has a Y value for each pixel and common U and V values.

QVideoFrame::Format_NV12

22

The frame is stored using an 8-bit per component semi-planar YUV format with a Y plane (Y) followed by a horizontally and vertically sub-sampled, packed UV plane (U-V).

QVideoFrame::Format_NV21

23

The frame is stored using an 8-bit per component semi-planar YUV format with a Y plane (Y) followed by a horizontally and vertically sub-sampled, packed VU plane (V-U).

QVideoFrame::Format_IMC1

24

The frame is stored using an 8-bit per component planar YUV format with the U and V planes horizontally and vertically sub-sampled. This is similar to the Format_YUV420P type, except that the bytes per line of the U and V planes are padded out to the same stride as the Y plane.

QVideoFrame::Format_IMC2

25

The frame is stored using an 8-bit per component planar YUV format with the U and V planes horizontally and vertically sub-sampled. This is similar to the Format_YUV420P type, except that the lines of the U and V planes are interleaved, i.e. each line of U data is followed by a line of V data creating a single line of the same stride as the Y data.

QVideoFrame::Format_IMC3

26

The frame is stored using an 8-bit per component planar YVU format with the V and U planes horizontally and vertically sub-sampled. This is similar to the Format_YV12 type, except that the bytes per line of the V and U planes are padded out to the same stride as the Y plane.

QVideoFrame::Format_IMC4

27

The frame is stored using an 8-bit per component planar YVU format with the V and U planes horizontally and vertically sub-sampled. This is similar to the Format_YV12 type, except that the lines of the V and U planes are interleaved, i.e. each line of V data is followed by a line of U data creating a single line of the same stride as the Y data.

QVideoFrame::Format_Y8

28

The frame is stored using an 8-bit greyscale format.

QVideoFrame::Format_Y16

29

The frame is stored using a 16-bit linear greyscale format. Little endian.

QVideoFrame::Format_Jpeg

30

The frame is stored in compressed Jpeg format.

QVideoFrame::Format_CameraRaw

31

The frame is stored using a device specific camera raw format.

QVideoFrame::Format_AdobeDng

32

The frame is stored using raw Adobe Digital Negative (DNG) format.

QVideoFrame::Format_User

1000

Start value for user defined pixel formats.


    5. 取消未完成的请求

[slot] void QCameraImageCapture::cancelCapture()

取消未完成的拍摄请求,已经捕获并排队处理的图像可能会被丢弃。

    6. 捕获图像并保存到文件

[slot] int QCameraImageCapture::capture(const QString &file = QString())

捕获图像并将其保存到文件。 这种操作在大多数情况下是异步的,需要关联信号进行操作。

如果传递一个空文件,相机后端将采用系统上的照片默认位置和命名方案,如果只指定没有完整路径的文件名,则图像将被保存到默认目录,用imageCaptured()和imageSaved()信号报告完整路径。

QCamera保存所有捕获参数,如曝光设置或图像处理参数,因此调用capture()后对相机参数的更改不会影响先前的捕获请求。

QCameraImageCapture :: capture()返回与ImageExposed(),imageCaptured()和imageSaved()信号一起使用的Capture Id参数。

执行capture函数之后会触发下列一些信号:

QCameraImageCapture::imageExposed()  //带有请求ID的帧被暴露时发出的信号。

QCameraImageCapture::imageCaptured() //发送带有请求标识的帧时发出的信号,但尚未处理和保存

QCameraImageCapture::imageSaved() //当具有请求标识的帧被保存到文件名时发出的信号。

QCameraImageCapture::error() //捕获请求标识失败并显示错误和errorString描述。

  示例:

connect(cameraImageCapture, static_cast<void(QCameraImageCapture::*)(int, QCameraImageCapture::Error, const QString &)>(&QCameraImageCapture::error),

      [=](int id, QCameraImageCapture::Error error, const QString &errorString){ /* ... */ });


完整的信号函数:



[signal] void QCameraImageCapture::imageExposed(int id)

[signal] void QCameraImageCapture::imageCaptured(int id, const QImage &preview)

[signal] void QCameraImageCapture::imageSaved(int id, const QString &fileName)

[signal] void QCameraImageCapture::error(int id, QCameraImageCapture::Error error, const QString &errorString)


8.1.5 捕获图像到文件示例(实现照相机功能)


(配套代码CH8-2)

    1. QCamera.pro文件代码

#-------------------------------------------------

#

# Project created by QtCreator 2018-05-30T18:02:49

#

#-------------------------------------------------

QT       += core gui

QT += multimediawidgets

QT       += xml

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = QCamera

TEMPLATE = app

SOURCES += main.cpp\

        widget.cpp

HEADERS  += widget.h

FORMS    += widget.ui

    2. widget.h文件代码

#ifndef WIDGET_H

#define WIDGET_H

#include <QWidget>

#include <QCameraViewfinder>

#include <QCameraImageCapture>

#include <QCameraInfo>

#include <QCameraImageCapture>

namespace Ui {

class Widget;

}

class Widget : public QWidget

{

    Q_OBJECT

public:

    explicit Widget(QWidget *parent = 0);

    ~Widget();

    QCamera * camera;

    QCameraViewfinder * view_finder; //取景器

    QList<QCameraInfo> cameras;  //存放系统支持的摄像头列表

    QCameraImageCapture* camera_image_capture;

private slots:

    void on_pushButton_GetImage_clicked();

    void save_picture(int id,const QString file);

    void show_picture(int,const QImage);//显示拍照图片的槽函数

private:

    Ui::Widget *ui;

};

#endif // WIDGET_H

    3. widget.cpp文件代码

#include "widget.h"

#include "ui_widget.h"

Widget::Widget(QWidget *parent) :

    QWidget(parent),

    ui(new Ui::Widget)

{

    ui->setupUi(this);

    cameras = QCameraInfo::availableCameras();

    if(cameras.count())

    {

        for(int i=0;i<cameras.count();i++)

        {

            qDebug()<<"设备唯一ID:"<<cameras.at(i).deviceName();

            qDebug()<<"设备方向:"<<cameras.at(i).orientation();

        }

    }

    else

    {

        qDebug()<<"系统没有可用相机!";

    }

    /*创建摄像头对象,根据选择的摄像头打开*/

    camera = new QCamera(cameras.at(0));

    /*构造捕获的对象*/

    camera_image_capture = new QCameraImageCapture(camera);

    /*关联信号槽--显示图片*/

    connect(camera_image_capture,SIGNAL(imageCaptured(int,QImage)),this,SLOT(show_picture(int,QImage)));

    /*关联信号槽--返回保存照片的文件名称*/

    connect(camera_image_capture,SIGNAL(imageSaved(int,const QString)),this,SLOT(save_picture(int,const QString)));

    //信号槽函数关联方式2

    //connect(camera_image_capture,&QCameraImageCapture::imageCaptured,this,&MainWindow_camera::show_picture);

    /*设置捕获的目的地---到文件*/

    camera_image_capture->setCaptureDestination(QCameraImageCapture::CaptureToFile);

    /*创建取景器*/

    view_finder = new QCameraViewfinder();

    /*将显示的位置加入到窗口中*/

    //ui->verticalLayout->addWidget(view_finder);

    ui->horizontalLayout_2->insertWidget(0,view_finder); //插入到第一个位置

    /*配置摄像头捕获模式为帧捕获模式*/

    camera->setCaptureMode(QCamera::CaptureStillImage);

    /*设置取景器显示*/

    camera->setViewfinder(view_finder);

    /*启动摄像头*/

    camera->start();

}

Widget::~Widget()

{

    delete ui;

}

/*返回图片保存的文件名称*/

void Widget::save_picture(int id,const QString file)

{

    qDebug()<<"保存的图片的编号:"<<id;

    qDebug()<<"图片保存的路径:"<<file;

    ui->lineEdit_ShowFileAddr->setText(file); //显示照片的路径

}

/*在标签控件上显示拍照的图片*/

void Widget::show_picture(int id, const QImage image)

{

   qDebug()<<"捕获的图片编号:"<<id;

   /*

    * 显示捕获的照片

    * 可将image显示到指定控件上

  */

 //ui->label_ShowImage->setPixmap(QPixmap::fromImage(image).scaled(image.width()/2,image.height()/2));

   ui->label_ShowImage->setPixmap(QPixmap::fromImage(image));

}

void Widget::on_pushButton_GetImage_clicked()

{

        /*

         * 触发imageCaptured和imageSaved信号

         * 如果capture()不填写文件名系统会自动选择默认的路径

         * */

        camera_image_capture->capture();

}

    4. 运行效果图



图8-1-2

8.2  播放音乐与视频

8.2.1 QMediaPlayer类介绍与基本使用


QMediaPlayer类是高级媒体播放类。它可用于播放歌曲,电影和网络收音机等内容。要播放的内容被指定为QMediaContent对象,QMediaContent类提供对媒体内容相关的资源访问。

QMediaContent在多媒体框架中用作媒体内容的逻辑句柄。QMediaContent对象由一个或多个QMediaResources组成,其中每个资源都提供不同内容编码的URL和格式信息。

非空的QMediaContent将始终通过canonicalUrl()或canonicalResource()方法对提供的内容或规范进行主要引用,但任何资源都是可选的。

或者,QMediaContent可以表示播放列表并包含指向有效QMediaPlaylist对象的指针。在这种情况下,URL是可选的,可以是空的或指向播放列表的URL。

使用媒体播放相关的类需要添加#include <QMediaPlayer>头文件,并且在pro工程文件中引用multimedia模块。

xxx.pro文件添加的引用示例:  QT += multimedia

  • 解码库说明:

Qt在linux下使用gstreamer解码库,Windows下使用directshow解码库,Android下使用MediaPlayer解码库。

Qt本身没有自带解码库,而是对平台相关的播放器框架做了封装,提供了平台无关的API。

所以,要想使用QT正常的播放音乐或者视频需要在对应的平台预先安装对应的解码库。

比如: windows系统安装LAVFilters-0.65.exe软件后即可正常解码。

LAVFilters是一组基于ffmpeg项目中的libavformat/libavcodec库的DirectShow分离器和音视解码器,几乎允许在directShow播放器中播放任何格式。

除了安装LAVFilters软件之外,还可以通过安装K-Lite Codec Pack之类的解码器,就可以扩展支持绝大部分常见的视频格式。

  • 通过QMediaPlayer播放音乐文件示例

/*多媒体对象*/

QMediaPlayer *player = new QMediaPlayer;

/*设置播放的文件*/

player->setMedia(QUrl::fromLocalFile("E:/KuGou/99.mp3"));

/*音量设置*/

player->setVolume(50);

/*开始播放*/

player->play();

  • 通过QMediaPlayer播放视频文件示例

播放视频还需要用到QVideoWidget,要在xxx.pro文件里添加multimediawidgets模块的引用。

#include <QMediaPlayer>

#include <QMediaPlaylist>

#include <QVideoWidget>

/*多媒体对象*/

QMediaPlayer *player = new QMediaPlayer;

QVideoWidget *videoWidget = new QVideoWidget;

player->setVideoOutput(videoWidget);

/*设置播放的文件*/

player->setMedia(QUrl::fromLocalFile("E:/linux-share-dir/QT/MediaPlayer/test_video/1.wmv"));

/*音量设置*/

player->setVolume(50);

/*开始播放*/

     videoWidget->setWindowTitle("视频播放器");

videoWidget->show();

videoWidget->setGeometry(100,100,400,400);

player->play();

8.2.2 QMediaPlayer类相关函数接口介绍


  • 公共函数介绍

    1. 设置正在播放的音频类型

QAudio::Role audioRole() const  //获取当前的音频类型

void setAudioRole(QAudio::Role audioRole) //设置指定的音频类型

QList<QAudio::Role> QMediaPlayer::supportedAudioRoles() const  //获取支持的音频类型,如果不支持设置,则返回空列表。

该属性具有设置媒体播放器播放的音频流作用。

它可以设置正在播放的音频类型,以便系统处理时作出适当的决定。

需要在调用setMedia()之前进行设置。

支持的类型如下:

QAudio::UnknownRole

0

音频类型未知或未定义

QAudio::MusicRole

1

音乐

QAudio::VideoRole

2

电影或视频的原声带

QAudio::VoiceCommunicationRole

3

语音通信,如电话

QAudio::AlarmRole

4

报警

QAudio::NotificationRole

5

通知,例如传入电子邮件或聊天请求

QAudio::RingtoneRole

6

铃声

QAudio::AccessibilityRole

7

用于辅助功能,如使用屏幕阅读器

QAudio::SonificationRole

8

用户界面声音

QAudio::GameRole

9

游戏音频

    2. 设置视频图像输出的位置

void QMediaPlayer::setVideoOutput(QVideoWidget *output)

将QVideoWidget视频输出附加到媒体播放器。如果媒体播放器已经连接了视频输出,它将被替换为新的。

void QMediaPlayer::setVideoOutput(QGraphicsVideoItem *output)

附加一个QGraphicsVideoItem视频输出到媒体播放器。如果媒体播放器已经连接了视频输出,它将被替换为新的。

void QMediaPlayer::setVideoOutput(QAbstractVideoSurface *surface)

将视频Surface设置为媒体播放器的视频输出。如果已经在媒体播放器上设置了视频输出,则新表面将替换它。

    3. 获取媒体的数据源

const QIODevice *QMediaPlayer::mediaStream() const

这只有在媒体数据流已经传递给setMedia()时才有效。

    4. 设置媒体播放的音量

int  volume() const

void  setVolume(int volume)

该属性保存当前播放音量。

播放音量实际上是线性的,数值范围为0 - 100,超出此范围的值将被钳位。

音量发生改变时将发出void volumeChanged(int volume)信号进行通知,指示播放音量已更改为指定音量。

    5. 获取多媒体当前的状态

State state() const

State属性保存媒体播放器的播放状态。

默认情况下,这个属性是QMediaPlayer :: Stopped

当状态发生改变时发出void stateChanged(QMediaPlayer::State state)信号进行通知,指示播放器对象的状态已更改。

 状态列表:



QMediaPlayer::StoppedState

0

媒体播放器没有播放内容,播放将从当前曲目开始播放。

QMediaPlayer::PlayingState

1

媒体播放器正在播放内容。

QMediaPlayer::PausedState

2

媒体播放器暂停播放,当前曲目的播放将从播放器暂停的位置恢复。

    6. 获取当前媒体播放是位置

qint64 position() const

void setPosition(qint64 position)

该属性保存当前媒体的播放位置。

该值是当前播放位置,自播放开始以毫秒为单位表示。 定期更改位置将使用信号positionChanged()进行指示,更新间隔可以使用QMediaObject的方法setNotifyInterval()进行设置。

位置发生改变时,通过

[signal] void QMediaPlayer::positionChanged(qint64 position)信号进行通知。

播放的总时间通过

[signal] void QMediaPlayer::durationChanged(qint64 duration)信号通知。

    7. 设置多媒体播放列表

QMediaPlaylist *playlist() const

void setPlaylist(QMediaPlaylist *playlist)

该属性保存播放器对象正在使用的媒体播放列表。

播放器对象将使用当前播放列表项来选择要播放的内容。

默认情况下,该属性设置为null。

如果媒体播放列表用作源,则QMediaPlayer :: currentMedia将使用当前的播放列表项目进行更新。应使用QMediaPlaylist :: setCurrentIndex(int)而不是QMediaPlayer :: setMedia()选择当前源,否则当前播放列表将被丢弃。

    8. 设置多媒体的播放速度

qreal playbackRate() const

void setPlaybackRate(qreal rate)

该属性保存当前媒体的播放速率。

此值是应用于媒体标准播放速率的乘数。 默认情况下,该值为1.0,表示媒体正在以标准速度播放。高于1.0的值将增加播放的速度。可以设置小于零的值,并指示媒体将以标准速度的倍数后退。

并非所有播放服务都支持更改播放速率。 它是在快进或倒带时对音频和视频的状态和质量进行定义的框架。

播放速率更改之后会以

[signal] void QMediaPlayer::playbackRateChanged(qreal rate)信号进行通知。

    9. 判断视频的可用性状态

bool isVideoAvailable() const

该属性保存当前媒体的视频可用性状态。

如果可用,QVideoWidget类可用于查看视频。由于QMediaPlayer的使用寿命可能比一个QMediaContent的播放时间长,因此此属性可能随时间而改变,videoAvailableChanged信号可用于监视其状态。

当视频内容的可用性已更改,将发出[signal] void QMediaPlayer::videoAvailableChanged(bool videoAvailable)信号进行通知。

    10. 设置媒体的静音状态

bool isMuted() const

void setMuted(bool muted)

该属性拥有当前媒体的静音状态。

如果播放音量静音,则该值为true; 否则为false。

当静音状态发生改变,将通过void mutedChanged(bool muted)信号进行通知。

    11. 判断当前的音频可用状态

bool isAudioAvailable() const

该属性保存当前媒体的音频可用状态。

由于QMediaPlayer的使用寿命可能比一个QMediaContent的播放时间长,因此此属性可能随时间而改变,audioAvailableChanged信号可用于监视其状态。

当状态发生改变时,通过

[signal] void QMediaPlayer::audioAvailableChanged(bool available)信号进行通知。

    12. 获取错误信息

QString errorString() const

Error error() const

    错误枚举值:

常数

数值

描述

QMediaPlayer::NoError

0

没有发生错误

QMediaPlayer::ResourceError

1

媒体资源无法解析。

QMediaPlayer::FormatError

2

没有(完全)支持媒体资源的格式。回放可能仍然是可能的,但没有音频或视频组件。

QMediaPlayer::NetworkError

3

发生网络错误。

QMediaPlayer::AccessDeniedError

4

没有适当的权限来播放媒体资源。

QMediaPlayer::ServiceMissingError

5

没有找到有效的播放服务,播放无法继续。

 出现错误时,也会发出error信号:

[signal] void QMediaPlayer::error(QMediaPlayer::Error error)

关联信号的方式:

connect(mediaPlayer,

static_cast<void(QMediaPlayer::*)(QMediaPlayer::Error)>(&QMediaPlayer::error),

      [=](QMediaPlayer::Error error){ /* ... */ });

    相关的槽函数:


    1. 暂停播放

[slot] void QMediaPlayer::pause()

    2. 继续播放

[slot] void QMediaPlayer::play()

    开始或继续播放当前源。

    3. 设置播放源

[slot] void QMediaPlayer::setMedia(const QMediaContent &media, QIODevice *stream = Q_NULLPTR)

设置当前媒体源。

如果提供了一个流; 媒体数据将从其中读取而不是解析媒体源。在这种情况下,媒体源仍可用于解析有关媒体的其他信息,如MIME类型。

将媒体设置为空QMediaContent将导致播放器放弃与当前媒体源有关的所有信息并停止与该媒体相关的所有I / O操作。

注意:此功能在录制指定的媒体源后立即返回。 它不会等待媒体完成加载,也不会检查错误。 监听mediaStatusChanged()和error()信号,以便在数据加载时以及加载过程中发生错误时进行通知。

    4. 设置远程网络接入点

[slot] void QMediaPlayer::setNetworkConfigurations(const QList<QNetworkConfiguration> &configurations)

设置远程媒体播放的网络接入点。 配置按优先顺序升序包含可用于网络访问的配置列表。

这会使先前配置的选择无效。

    5. 停止播放

[slot] void QMediaPlayer::stop()

停止播放,并将播放位置重置为开头。

    8.2.3 视频播放器示例


(完整代码编号CH8-3)

    1. xxx.pro文件代码示例

#-------------------------------------------------

#

# Project created by QtCreator 2018-06-03T19:56:58

#

#-------------------------------------------------

QT       += core gui

QT += multimedia

QT += multimediawidgets

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = MediaPlayer

TEMPLATE = app

RC_ICONS =images/log.ico

SOURCES += main.cpp\

        widget.cpp

HEADERS  += widget.h

FORMS    += widget.ui

RESOURCES += \

    images/images.qrc

    2. widget.h文件代码

#ifndef WIDGET_H

#define WIDGET_H

#include <QWidget>

#include <QMediaPlayer>

#include <QMediaPlaylist>

#include <QVideoWidget>

#include <QFileDialog>

#include <QListWidgetItem>

#include <QFile>

#include <QDesktopWidget>

namespace Ui {

class Widget;

}

class Widget : public QWidget

{

    Q_OBJECT

public:

    explicit Widget(QWidget *parent = 0);

    ~Widget();

     QMediaPlayer *player;

     QVideoWidget *videoWidget;

     int PlayTime;

     void SetStyle(const QString &qssFile);

private slots:

    void on_pushButton_AddrVideoFile_clicked();

    void on_listWidget_itemDoubleClicked(QListWidgetItem *item);

    void on_pushButton_start_clicked();

    void on_horizontalSlider_value_sliderMoved(int position);

    void on_pushButton_mute_clicked();

    void on_pushButton_pause_clicked();

    void on_comboBox_speed_activated(const QString &arg1);

    void on_pushButton_up_clicked();

    void on_pushButton_down_clicked();

    void player_location(qint64 value);

    void player_Time(qint64 value);

private:

    Ui::Widget *ui;

};

#endif // WIDGET_H


    3. widget.cpp文件代码

#include "widget.h"

#include "ui_widget.h"

/*

 * 设置QT界面的样式

*/

void Widget::SetStyle(const QString &qssFile) {

    QFile file(qssFile);

    if (file.open(QFile::ReadOnly)) {

        QString qss = QLatin1String(file.readAll());

        qApp->setStyleSheet(qss);

        QString PaletteColor = qss.mid(20,7);

        qApp->setPalette(QPalette(QColor(PaletteColor)));

        file.close();

    }

    else

    {

        qApp->setStyleSheet("");

    }

}

Widget::Widget(QWidget *parent) :

    QWidget(parent),

    ui(new Ui::Widget)

{

    ui->setupUi(this);

    this->setWindowTitle("视频播放器");

    this->SetStyle(":/qss/blue.css");     //设置样式表

    this->setWindowIcon(QIcon(":/log.ico")); //设置图标

    /*多媒体类*/

     player = new QMediaPlayer(this);

     /*创建播放视频的窗口*/

     videoWidget = new QVideoWidget(this);

     videoWidget->setWindowTitle("视频播放器");

    QHBoxLayout *layout = new QHBoxLayout;

    videoWidget->setLayout(layout);

    ui->horizontalLayout->insertWidget(0,videoWidget);

    /*设置窗口的位置与大小*/

    QDesktopWidget *pDesk = QApplication::desktop();

    //设置视频窗口的大小

    videoWidget->setMinimumSize(pDesk->width()/4*3,pDesk->height()/4*3);

    /*将播放的视频添加到窗口中*/

     player->setVideoOutput(videoWidget);

     ui->horizontalSlider_value->setMaximum(100); //音量最大值

     ui->horizontalSlider_value->setMinimum(0);   //音量最小值

     ui->horizontalSlider_value->setValue(50);    //默认音量设置

     player->setVolume(50);//默认音量设置

     ui->progressBar->setValue(0); //进度条

     //播放速率

     ui->comboBox_speed->addItem("1.0");

     ui->comboBox_speed->addItem("2.0");

     ui->comboBox_speed->addItem("3.0");

     ui->comboBox_speed->addItem("4.0");

     connect(player, static_cast<void(QMediaPlayer::*)(QMediaPlayer::Error)>(&QMediaPlayer::error),

           [=](QMediaPlayer::Error error)

     {

            if(QMediaPlayer::NoError==error)

            {

                ui->lineEdit_errorinfo->setText("正常解码!");

            }

            else if(QMediaPlayer::ResourceError==error)

            {

                ui->lineEdit_errorinfo->setText("媒体资源无法解析。");

            }

            else if(QMediaPlayer::FormatError==error)

            {

                ui->lineEdit_errorinfo->setText("不支持该媒体资源的格式,没有解码器!");

            }

            else if(QMediaPlayer::NetworkError==error)

            {

                ui->lineEdit_errorinfo->setText("发生网络错误。");

            }

            else if(QMediaPlayer::AccessDeniedError==error)

            {

                ui->lineEdit_errorinfo->setText("没有适当的权限来播放媒体资源。");

            }

            else if(QMediaPlayer::ServiceMissingError==error)

            {

                ui->lineEdit_errorinfo->setText("没有找到有效的播放服务,播放无法继续。");

            }

     });

     //添加播放进度的信号

     connect(player, SIGNAL(positionChanged(qint64)),this, SLOT(player_location(qint64)));

     //添加获取播放总时间的信号

     connect(player, SIGNAL(durationChanged(qint64)),this, SLOT(player_Time(qint64)));

}

Widget::~Widget()

{

    delete ui;

}

//添加视频文件

void Widget::on_pushButton_AddrVideoFile_clicked()

{

    QStringList filenamelist=QFileDialog::getOpenFileNames(this,"选择添加的文件","E:/",tr("*.*"));

    if(filenamelist.count()>0) ui->listWidget->addItems(filenamelist); //添加到列表

}

//双击选中了一个文件

void Widget::on_listWidget_itemDoubleClicked(QListWidgetItem *item)

{

     player->setMedia(QUrl::fromLocalFile(item->text()));

     player->play();

}

//开始播放

void Widget::on_pushButton_start_clicked()

{

    //判断是否选中条目

    if(ui->listWidget->currentRow()!=-1)

    {

        if(player->state()==QMediaPlayer::PausedState) //暂停播放状态

        {

             ui->lineEdit_errorinfo->setText("");

             player->play();

        }

        else

        {

            ui->lineEdit_errorinfo->setText("");

            //获取当前选中的视频进行播放

            player->setMedia(QUrl::fromLocalFile(ui->listWidget->currentItem()->text()));

            player->play();

         }

    }

}

//音量的值

void Widget::on_horizontalSlider_value_sliderMoved(int position)

{

    player->setVolume(position);//默认音量设置

}

//静音设置

void Widget::on_pushButton_mute_clicked()

{

     if(player->isMuted())

     {

         player->setMuted(false); //取消静音

     }

     else

     {

         player->setMuted(true); //静音

     }

}

//暂停

void Widget::on_pushButton_pause_clicked()

{

    player->pause(); //暂停

}

//播放速率

void Widget::on_comboBox_speed_activated(const QString &arg1)

{

    player->setPlaybackRate(arg1.toFloat());

}

//上一行

void Widget::on_pushButton_up_clicked()

{

    int cnt=ui->listWidget->currentRow();

    if(cnt!=-1) //选中了行

    {

        if(cnt==0)

        {

            ui->listWidget->setCurrentRow(0);

        }

        else

        {

            cnt--;

            ui->listWidget->setCurrentRow(cnt);

        }

        ui->lineEdit_errorinfo->setText("");

        //获取当前选中的视频进行播放

        player->setMedia(QUrl::fromLocalFile(ui->listWidget->currentItem()->text()));

        player->play();

    }

}

//下一行

void Widget::on_pushButton_down_clicked()

{

    int cnt=ui->listWidget->currentRow();

    if(cnt!=-1) //选中了行

    {

        cnt++;

        if(cnt>=ui->listWidget->count())ui->listWidget->setCurrentRow(ui->listWidget->count()-1);

        else ui->listWidget->setCurrentRow(cnt);

        ui->lineEdit_errorinfo->setText("");

        //获取当前选中的视频进行播放

        player->setMedia(QUrl::fromLocalFile(ui->listWidget->currentItem()->text()));

        player->play();

    }

}

//播放进度

void Widget::player_location(qint64 value)

{

    ui->progressBar->setValue(value);

    ui->label_Time->set

鲜花

1人点赞握手

雷人

路过

鸡蛋

刚表态过的朋友 (1 人)


公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了