草庐IT

Qt 之 MediaPlayer 音视频播放

老菜鸟的每一天 2023-04-12 原文

文章目录

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

有关Qt 之 MediaPlayer 音视频播放的更多相关文章

  1. Qt Designer的简单使用 - 2

    在前面两节的例子中,主界面窗口的尺寸和标签控件显示的矩形区域等,都是用C++代码编写的。窗口和控件的尺寸都是预估的,控件如果多起来,那就不好估计每个控件合适的位置和大小了。用C++代码编写图形界面的问题就是不直观,因此Qt项目开发了专门的可视化图形界面编辑器——QtDesigner(Qt设计师)。通过QtDesigner就可以很方便地创建图形界面文件*.ui,然后将ui文件应用到源代码里面,做到“所见即所得”,大大方便了图形界面的设计。本节就演示一下QtDesigner的简单使用,学习拖拽控件和设置控件属性,并将ui文件应用到Qt程序代码里。使用QtDesigner设计界面在开始菜单中找到「Q

  2. 动漫制作技巧如何制作动漫视频 - 2

    动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、

  3. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  4. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  5. ruby - 如何更改此正则表达式以从未指定 v 参数的 Youtube URL 获取 Youtube 视频 ID? - 2

    目前我正在使用这个正则表达式从YoutubeURL中提取视频ID:url.match(/v=([^&]*)/)[1]我怎样才能改变它,以便它也可以从这个没有v参数的YoutubeURL获取视频ID:http://www.youtube.com/user/SHAYTARDS#p/u/9/Xc81AajGUMU感谢阅读。编辑:我正在使用ruby​​1.8.7 最佳答案 对于Ruby1.8.7,这就可以了。url_1='http://www.youtube.com/watch?v=8WVTOUh53QY&feature=feedf'url

  6. ruby - 如何以编程方式将 mp3 转换为 itunes 可播放的 aac/m4a 文件? - 2

    我一直在寻找一种以编程方式或通过命令行将mp3转换为aac的方法,但没有成功。理想情况下,我有一段代码可以从我的Rails应用程序中调用,将mp3转换为aac。我安装了ffmpeg和libfaac,并能够使用以下命令创建aac文件:ffmpeg-itest.mp3-acodeclibfaac-ab163840dest.aac当我将输出文件的名称更改为dest.m4a时,它无法在iTunes中播放。谢谢! 最佳答案 FFmpeg提供AAC编码功能(如果您已编译它们)。如果您使用的是Windows,则可以从here获取完整的二进制文件。

  7. 关于Qt程序打包后运行库依赖的常见问题分析及解决方法 - 2

    目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'

  8. ruby - 如何播放 mp3 文件? - 2

    我如何用ruby​​编写一个脚本,当从命令行执行时播放mp3文件(背景音乐)?我试过了run="mplayer#{"/Users/bhushan/resume/m.mp3"}-aosdl-vox11-framedrop-cache16384-cache-min20/100"system(run)但它也不起作用,以上是播放器特定的。如果用户没有安装mplayer怎么办。有没有更好的办法? 最佳答案 我一般都是这样pid=fork{exec'mpg123','-q',file} 关于ruby

  9. 续集来了丨UI自动化测试(二):带视频,实在RPA高效进行web项目UI自动化测试 - 2

    一、什么是web项目ui自动化测试?通过测试工具模拟人为操控浏览器,使软件按照测试人员的预定计划自动执行测试的一种方式,可以完成许多手工测试无法完成或者不易实现的繁琐工作。正确使用自动化测试,可以更全面的对软件进行测试,从而提高软件质量进而缩短迭代周期。二、构建测试用例的“九部曲”(一)创建流程包划分功能模块日常测试活动中,都会根据功能模块进行拆分,所以在设计器中我们可以通过创建流程包的方式来拆分需要测试的功能模块,如下图中操作创建一个电脑流程包并且取名为对应的功能模块名称,如果有多个功能模块就创建多个对应的流程包,实在RPA设计器有易用的图形可视化界面,方便管理较多的功能模块。(二)在流程包

  10. Java调用ffmpeg处理视频,并记录下遇到的坑 - 2

    目录需求基于JavaCV跨平台执行ffmpeg命令[^1]坑一内存不足坑二多个ffmpeg进程并行导致IO负载大,进而导致ioerror?坑三使用Java操作ffmpeg时,有时会卡死坑四Process的waitFor死锁问题及解决办法需求给透明背景的视频自动叠加一张背景图片基于JavaCV跨平台执行ffmpeg命令1我测试发现的本需求的最小依赖:dependency>groupId>org.bytedecogroupId>artifactId>ffmpeg-platform-gplartifactId>version>5.0-1.5.7version>dependency>核心代码:Stri

随机推荐