Qt 之 MediaPlayer 音视频播放

Posted 老菜鸟的每一天

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt 之 MediaPlayer 音视频播放相关的知识,希望对你有一定的参考价值。

文章目录

1、QMediaPlayer简介

QMediaPlayer是Qt提供的一个跨平台媒体播放器类。它没有自带解码库,而是对平台相关的播放器框架做了封装,提供了平台无关的API。

在Windows下时,底层基于微软的DirectShow框架实现,需要提前安装解码库。可以下载K-Lite_Codec_Pack或者LAVFilters解码库安装。LAVFilters,下载地址:https://github.com/Nevcairiel/LAVFilters/releases

在Linux下时,底层基于GStreamer框架实现。

2、相关类介绍

2.1 QMediaPlayer

2.1.1 简单用法:

播放音频:

  player = new QMediaPlayer;
  connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
  player->setMedia(QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3"));
  player->setVolume(50);
  player->play();

播放视频:
QVideoWidget可与QMediaPlayer一起用于视频渲染,与QMediaPlaylist一起用于访问播放列表功能。

  playlist = new QMediaPlaylist;
  playlist->addMedia(QUrl("http://example.com/movie1.mp4"));
  playlist->addMedia(QUrl("http://example.com/movie2.mp4"));
  playlist->addMedia(QUrl("http://example.com/movie3.mp4"));
  playlist->setCurrentIndex(1);

  player = new QMediaPlayer;
  player->setPlaylist(playlist);

  videoWidget = new QVideoWidget;
  player->setVideoOutput(videoWidget);
  videoWidget->show();
  player->play();

2.1.2 关键枚举类

这些关键的枚举类,是实现好用的播放器的关键。需要重点关注哦。
播放器状态 QMediaPlayer::State
播放器有暂停、正在播放和停止三种状态,每种状态由下面 QMediaPlayer::MediaStatus来最终表现

状态枚举名称枚举值说明
StoppedState0播放停止状态
PlayingState1播放状态
PausedState2播放暂停状态

媒体状态 QMediaPlayer::MediaStatus

状态枚举名称枚举值说明
UnknownMediaStatus0未知状态
Nomedia1无媒体文件,player处于StoppedState
LoadingMedia2媒体文件加载中,player可以处于任何状态
LoadedMedia3媒体文件已加载,player处于StoppedState
StalledMedia4媒体处于延迟或者暂时的中断状态,player处于PlayingState或者PauseState
BufferingMedia5媒体正在缓冲数据,player处于PlayingState或者PausedState
BufferedMedia6媒体缓冲数据完成,player处于PlayingState或者PausedState
EndOfMedia7媒体结束,player处于StoppedState
InvalidMedia8非法的媒体文件,player处于StoppedState

播放标志位:Flags

状态枚举名称枚举值说明
LowLatency1播放未压缩的音频数据,播放表现为低延时,需要播放beeps,ringtones等
StreamPlayback2播放基于QIODevic构建的媒体文件,QMediaPlayer或自动选择支持的流行播放
VideoSurface4渲染视频到QAbstractVideoSurface otput

QMediaPlayer::Error 错误标志位

状态枚举名称枚举值说明
NoError0无错误
ResourceError1媒体源错误
FormatError2格式错误,播放可能会丢失音频或视频
NetworkError3

网络错误

AccessDeniedError4访问权限错误
ServiceMissingError5服务丢失错误

2.1.3 QMediaPlayer 常用属性

属性名称取值类型说明访问函数
audioAvailableconst bool音频是否可用,audioAvailableChanged信号函数用于监控其状态bool isAudioAvailable()
muted bool是否静音, void mutedChanged(bool muted) 信号函数用于监控其状态bool isMuted()
audioRoleQAudio::Role音频流播放role

QAudio::Role audioRole() const

void setAudioRole(QAudio::Role audioRoe)

bufferStatusconst int缓冲数据的百分比,在开始播放或者回复播放之前

int bufferStatus() const

void bufferStatusChanged(int percentFilled)

currentMediaconst qMediaContent当前激活的媒体,在使用Playlist时,可能与media属性不同

QMediaContent currentMedia() const

void currentMediaChanged(const QMediaContent &media)

durationconst qint64currentMedia的播放时长,单位ms

qint64 duration() const

void durationChanged(qint64 duration)

mediaQmediaContent激活并被使用的媒体源

QMediaContent media() const,

void setMedia(const QMediaContent &media, QIODevice *stream=nullptr),

void mediaChanged(const QMediaContent &media)

playbackRateqreal当前媒体的播放速度,默认为1.0

qreal playbackRate() const

void setPlaybackRate(qreal rate)

void playbackRateChanged(qreal rate)

playlistQMediaPlaylist *播放列表

QMediaPlaylist *playlist() const

void setPlaylist(QMediaPlaylist *playlist)

volumeint音量,取值范围0-100

int volume() const, void setVolume(int volume)

void volumeChanged(int volume)

2.2 QVideoWidget

QvideoWidget是一个用来展示视频的类,需要先定义一个QMediaPlayer对象,然后将QMediaPlayer的VideoOutput设置为QVideoWidget对象

常用属性

名称类型说明
aspectRatioModeQt::AspectRatioMode屏幕亮度比
brightnessint亮度
contrastint对比度
fullScreenbool是否全屏
hueint色调
mediaObjectQMediaObject *const视频媒体对象
saturationint饱和度

方法:

返回值类型函数名称描述说明
Qt::AspectRatioModeaspectRatioMode() const获取视频画面宽高比
intsaturation() const获取饱和度
intbrightnees() const获取亮度
intcontrast() const获取对比度
inthue() const获取色调
boolisFullScreen() const获取全屏状态

槽函数

返回值类型函数名称描述说明
voidsetAspectRatioMode(Qt::AspectRatioMode mode)设置宽高比
voidsetBrightness(int brightness)设置亮度
void

setContrast(int contrast)

设置对比度
voidsetFullScreen(bool fullScreen)设置全屏状态
voidsetHue(int hue)设置色调
voidsetSaturation(int saturation)设置饱和度

2.3 QMediaPlaylist

QMediaPlaylist类,可以为QMediaPlayer提供一个播放列表,它其实是QMediaContent对象的列表,QMediaPlayer通过函数setPlaylist来设置一个播放列表。QMediaPlaylist通过函数addMedia向播放列表添加一个媒体文件。

播放模式:PlaybackMode

状态枚举名称枚举值说明
CurrentItemOnce0当前选中的媒体文件仅播放一次
CurrentItemInLoop1当前选中的媒体文件循环播放
Sequential2从当前选中的媒体文件开始,列表中的文件顺序播放一次直到最后一个文件
Loop3列表中的文件顺序循环播放
Random4列表中的文件随机播放

属性:

名称类型说明
currentIndexint当前播放的媒体文件在列表中的索引
currentMediaconst QMediaContent当前选中的媒体文件
playbackModeQMediaPlaylist::PlaybackMode从当前选中的媒体文件开始,列表中的文件顺序播放一次直到最后一个文件

方法:

返回值类型函数名称描述说明
booladdMedia(const QMediaContent &content)Public Functions列表添加单个媒体文件
booladdMedia(const Qlist &items)Public Functions,列表添加多个媒体文件
intcurrentIndex() const获得当前播放媒体的索引
QMediaContentcurrentMedia() const

获得当前播放的媒体列表

QMediaPlaylist::Erroeerror() const列表错误状态
QStringerrorString() const播放列表错误字符串信息
boolinsertMedia(int pos, const QMediaContent &content)向播放列表插入一个媒体文件
boolinsertMedia(int pos, const QList &items)向播放列表插入多个媒体文件
boolisEmpty() const清空列表
boolisReadOnly() const清空列表
voidload(const QNetworkRequest &request, const char *format=nullptr)加载网络媒体
voidload(const QRul &location, const char *format=nullptr)加载本地媒体文件
voidload(QIODevice *device, const char *format=nullptr)加载IO设备文件
QMediaContentmeida(int index) const获得指定索引的媒体文件

int

mediaCount() const统计播放列表的文件数量
boolmoveMedia(int from, int to)根据位置参数移动媒体文件
intnextIndex(int steps=1) const当前播放文件的下一个文件索引
PlaybackModeplaybackMode() const获取列表播放模式
intpreviousIndex(int steps=1) const当前播放文件的上一个文件索引
boolremoveMedia(int pos)删除列表中指定位置的文件
boolremoveMedia(int start, int end)删除列表中start到end之间的文件
boolsave(const QUrl &location, const char *format=nullptr)保存列表QUrl指定位置
boolsave(QIODevice *device, const char *format)保存列表到IO设备
voidsetPlaybackMode(QMediaPlaylist::PlaybackMode mode)设置列表播放模式

槽函数:

返回值类型函数名称描述说明
voidnext()下一个文件
voidprevious()上一个文件
voidsetCurrentIndex(int playlistPosition)设置当前播放媒体的所有
voidshuffle()媒体顺序洗牌,重建媒体的索引

信号:

返回值类型函数名称描述说明
voidcurrentIndexChanged(int position)当前索引改变信号
voidcurrentMediaChanged(const QMediacontent &content)当前媒体文件改变信号
voidloadFailed()加载失败信号
voidloaded()加载完成信号
voidmediaAboutToBeInserted(int start, int end)媒体即将插入信号
voidmediaAboutToBeRemoved(int start, int end)媒体即将被删除信号
voidmediaChanged(int start, int end)媒体文件改变信号
voidmediaInserted(int start, int end)媒体文件插入信号
voidmediaRemoved(int start, int end)媒体文件删除信号
voidplaybackModeChanged(QMediaPlaylist::PlaybackMode mode)列表播放模式改变信号

2.4 QML 相关用法

2.4.1 MediaPlayer

import QtMultimedia 5.0

MediaPlayer 
        id: player;
        source: control.source
        onPositionChanged:
        
           
        

        onError: 
            console.error("MediaPlayer error:",errorString)
        

        onPlaying:
        
        

        onStatusChanged:
        
            console.warn("onStatusChanged",status);
        

        onPlaybackStateChanged:
        
        

		onMediaObjectChanged:        
        
   

2.4.2 QML Audio

 Text 
      text: "Click Me!";
      font.pointSize: 24;
      width: 150; height: 50;

      Audio 
          id: playMusic
          source: "music.wav"
      
      MouseArea 
          id: playArea
          anchors.fill: parent
          onPressed:   playMusic.play() 
      
  

2.4.3 QML Video

Video 是一种方便的类型,它将MediaPlayer的功能和视频输出结合在一起。它提供了简单的视频播放功能,无需声明多种类型。

 Video 
      id: video
      width : 800
      height : 600
      source: "video.avi"

      MouseArea 
          anchors.fill: parent
          onClicked: 
              video.play()
          
      

      focus: true
      Keys.onSpacePressed: video.playbackState == MediaPlayer.PlayingState ? video.pause() : video.play()
      Keys.onLeftPressed: video.seek(video.position - 5000)
      Keys.onRightPressed: video.seek(video.position + 5000)
  

3. 遇到的bug

特定版本:5.10

3.1 调整倍速,不起作用

调整播放倍速时,不起作用,后来通过重新设置下seek进度,来解决了。

function setPlayerSpeed(speed)
    
        var num = parseFloat(speed.slice(0,speed.length-1))
        player.playbackRate = num
        console.log("setPlayerSpeed",num)
        player.seek(player.position - 1000);
    

3.1 当弱网情况下,拖动进度条,导致UI卡主

1 是通过优化进度条的通知时机 比如 信号 moved
2 是通过媒体的状态flage 来展示loading 进行优化

多媒体(音乐视频播放器,相机)

  1、音乐、视频
  QMediaPlayer是多媒体核心类,可以播放音乐、视频。要使用MediaPlayer,需要引入QtMultimedia 5.0或以上版本。另外在pro文件中需要添加QT += multimedia
  音乐播放用MediaPlayer足以满足需求,但是视频需要VedioOutput元素和MediaPlayer结合,这个VideoOutput用来渲染视频,也可以作为相机的取景器(预览窗口)。

  多媒体元信息:就是描述媒体的信息,包括歌曲的专辑、发行时间、艺术家,或者视频的分辨率、编码格式以及针率等。关于这方面的信息,可以通过MediaPlayer的metaData来获取。虽然这属性提供了丰富的信息,但是要取决于MediaPlayer使用的底层播放服务能否提供这些

  2、相机
  QCamera有诸多属性,我们先来看看常用的属性
  digitalZoom 配置数字变焦
  maximumDigitalZoom保存了相机支持的最大数字变焦倍数,如果是1.0则说明不支持数字变焦
  opticalZoom 配置光学变焦倍数
  maximumOpticalZoom保存相机支持的最大光学变焦倍数,1.0表示不支持光学变焦
  captureMode枚举三种值:Camera.CaptureVideo(录制视频)、Camera.CaptureViewfinder(仅预览)、
  Camera.CaptureStillImage(捕获静态图片)三种模式
  CameraFocus类
    focus 控制聚焦和变焦的模式
    focusMode 是个枚举值,代表多种聚焦模式。比如Camera.ManualFocus代表手动聚焦、Camera.AutoFocus代表自动聚焦、Camera.MacroFocus微距聚焦,等等
    CameraFocus的isFocusModeSupported(mode) 用来查询物理设备是否支持制定的聚焦方式
    focusPointMode定义焦点模式,分别对应四种枚举值。Camera.FocusPointAuto(自动焦点)Camera.FocusPointCenter(中心焦点)、Camera.FocusPointFaceDetection(面部识别)
    Camera.FocusPointCustom(自定义焦点,使用customFocusPoint属性指定的点作为焦点)。isFocusPointModeSupported(mode)用来判断硬件是否支持该模式

  CameraExposure类
  这个类用来控制相机的曝光选项,可以通过Camera的exposure属性完成相关设置
  exposureMode 枚举了多个曝光选项,有Camera.ExposureAuto(自动)、Camera.ExposureManual(手动),还有运动、大光圈(近景)、小光圈(远景)、背光、夜景、人物、海岸等等
  shutterSpeed 表示当前的快门速度
  iso表示感光系数,其中manualIso曹村手动设置的感光度。iso越大,感光越快、城乡就越模糊;反之,则成像细腻
  aperture表示光圈的大小, manualAperture表示手动设置光圈大小,而setAutoAperture()可以打开自动模式
  CameraFlash用来控制闪光的
    mode 枚举了多个闪光灯的选项值,包括Camera.FlashOff(关闭闪光灯)、Camera.FlashOn(打开闪光灯)、Camera.FlashAuto、Camera.FlashRedEyeReduction(去红眼)等等更多模式
  CameraImageProcessing
  imageProcessing对照片做一些处理,比如降噪、白平衡、锐化、对比度、饱和度等等。该属性的类型是CameraImageProcessing,详细用法可查此类
取景器
  上面说过,可以用VideoOutput作为相机的取景器,只需要将souce设置为camera对象即可,
  如下放的代码

  

Rectangle{
            width: 960
            height: 540

            Camera{
                id: camera
                captureMode: Camera.CaptureStillImage
            }

            VideoOutput{
                source: camera
                anchors.fill: parent
            }
    }

 

以上是关于Qt 之 MediaPlayer 音视频播放的主要内容,如果未能解决你的问题,请参考以下文章

Qt qml MediaPlayer/Video 仅再现声音(无视频)

QML MediaPlayer ServiceMissing异常解决办法

Qt 视频流应用程序:未找到 qt.mediaplayer 的服务

多媒体(音乐视频播放器,相机)

Qt5.3 第二次 一个视频播放器的困难和解决办法

Qt5.3 第二次 一个视频播放器的困难和解决办法