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 进行优化

  • 15
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值