上一期,小编给大家简要介绍了MPV的配置和使用方法,虽然MPV功能强大,但默认情况下,MPV无GUI图形界面,用户需要通过命令行或者手动修改其配置文件达到配置MPV的目的,这样就给普通用户带来了诸多不便。为此,本文将介绍如何在优麒麟系统上使用Qt编写带UI图形的MPV播放器,使用户对快速定制具有图形界面的MPV播放器有一个大致的了解。

安装编程开发依赖包:

$ sudo apt install qtbase5-dev qt5-qmake qtscript5-dev qttools5-dev-tools

1、QProcess类为了实现一个既可以在Qt程序中控制MPV,又可以让Qt程序得到MPV的输出信息的播放器,这里重点介绍Qt的QProcess类。QProcess类可用来调用外部程序,并与外部程序进行通信。其把外部程序的进程当作一个有序的I/O设备,通过对I/O设备的读写来完成进程间的通信,即:write()函数实现对进程标准输入的写操作,通过read(),readLine()和getChar()函数实现对标准输出的读操作。在正常渠道模式下,QProcess的无名管道stdinChannelpipe,stdoutChannelpipe和stderrChannelpipe分别与标准输入、标准输出和标准容错进行绑定,实现与外部程序的通信;而在融合模式下,没有容错管道,此时,标准容错端和标准输出端将共同挂接到子进程的stdoutChannelpipe的写端来实现内外进程的通信,即标准输出和标准容错绑定到同一个管道的写端。本文介绍通过QProcess类调用MPV,并设置一系列播放参数,如视频驱动、音频驱动、软解/硬解、缓存等。至于Qt图形和MPV视频窗口的关联,则是使用“--wid widget->winId()”进行绑定,通过winId()可以获得一个数字,其中widget是一个QWidget对象,这样将界面上一个窗口的句柄给了MPV,即视频输出定位到了widget窗体部件中(wid为MPV指定了输入窗口,-wid参数只在X11、directX和OpenGL中适用)。本文推荐使用融合模式,代码为:setProcessChannelMode(QProcess::MergedChannels)。2、Qt对MPV的控制前面详细介绍了Qt的QProcess类,这里描述下该类是如何设置MPV的参数和启动MPV的,即如何使用给标准输入控制MPV。MPV自动从标准输入中读取信息并执行,该类指令信息都需要以“\n”结尾。管道的读端描述符stdinChannelpipe[0]复制给了标准输入,即标准输入的描述符也为stdinChannelpipe[0],隐藏按照标准输入的描述符去读信息就是到stdinChannelpipe所对应的管道中读取信息。QProcess的start()函数将开启进程,第一个参数即为MPV二进制,第二个参数为给MPV的参数列表,执行start()函数后,将完成内核中管道以及通信环境的建立。QProcess的成员函数write()向stdinChannelpipe[1]端写入信息,比如想让MPV退出,则通过write函数写入“quit \n”即可(write()函数将向stdinChannelpipe[1]端写入命令)。参考代码如下:

QString mpvCmd = "/usr/bin/mpv";

QStringList args;

args << "-- no-quiet";

args << "--wid=100663330";

args << xxx.avi;

process->start(mpvCmd, args);//启动播放

waitForStarted();

QString cmd = "set pause yes";

process->write(cmd.toLocal8Bit() + "\n");//设置暂停

3、Qt获取MPV的信息使用QProcess的融合模式,从标准输出和标准容错得到MPV 的信息。绑定QProcess的信号readyReadStandardOutput,当该信号出发时,再通过QProcess的readAllStandardOutput()函数获取信息(当然,这里也可以while循环来判断是否可以读取一行数据:while(process->canReadLine()),如果可以,则读取一行:QString line(process->readLine());),readAllStandardOutput获取的数据类型为QByteArray,对数据进行解析时通过“\n” 和“\r” 切分后一行一行解析,通过对每行的QByteArray数据进行详细解析可以得出MPV的状态信息,并将一些状态在Qt的图形程序上动态展示处理,比如MPV播放成功,则根据播放成功的信息将Qt图形的播放按钮设置为可暂停状态,此时点击该按钮给MPV发送的指令应该是暂停而非启动。另外,可以绑定QProcess的信号finished(int, QProcess::ExitStatus),当该信号被触发时,通过判断QProcess的bytesAvailable()值,如果>0,则通过QProcess的readAllStandardOutput()函数获取信息。获取MPV的信息进行解析的难点是对繁杂冗余的信息进行过滤,针对关键字定位信息表示的意思。这里可以使用Qt的对获取的QRegExp来进行匹配。下述正则表达式可用于分析出正在启动中:

QRegExp rx_playing;

rx_playing.setPattern("^Playing:.*|^\\[ytdl_hook\\].*");

下述正则表达式可可解析出暂停、缓存中等各种状态信息:

QRegExp rx_av;

rx_av.setPattern("^STATUS: ([0-9\\.-]+) / ([0-9\\.-]+) P: (yes|no) B: (yes|no) I: (yes|no) VB: ([0-9\\.-]+) AB: ([0-9\\.-]+)");

4、编程示例

使用Qt Creator创建一个新工程,模板中选择"QApplication -> Qt Widgets Application",以下示例取名为mympvplayer,如下图所示:

至此,一个最基本的UI图形框架已经成功搭建完毕了,编译和运行则会弹出一个最基本的QMainWindow图形界面。接下来我们要做的就是在此基础上丰富播放器的界面和完成最基本的功能逻辑处理,示例支持基本的文件播放(包括拖动文件到播放器进行播放和通过鼠标右键菜单选择文件播放)、暂停、停止、进度控制(包括鼠标拖动进度条进行控制和鼠标滚轮上下滚动控制)、音量调节。下面将对部分代码模块进行简单的说明,具体说明和示例代码请查看:https://github.com/eightplus/examples/tree/master/code/Qt/mympvplayer 或 https://eightplus.github.io/2019/08/19/2019-08-19-qt-mpv-player/。

1)增加播放控制栏

这里在主界面的最下方增加一个播放控制栏区域,包括播放/暂停、停止、进度条、音量控制以及时长显示等,如下图所示:

在实例中,图形界面相关的模块主要有两个,一个是类Mainwindow(mainwindow.cpp和mainwindow.h),另一个是类BottomWidget(bottomwidget.cpp和bottomwidget.h)。Mainwindow是主体,负责各个模块对象的创建,图形和数据的交互处理等。BottomWidget创建了三个按钮(播放/暂停、停止、静音),两个滑动条(播放进度条、音量控制条),一个文字显示区域(视频时长和播放时长)。具体代码见:https://github.com/eightplus/examples/blob/master/code/Qt/mympvplayer/bottomwidget.cpp。2)增加显示模块类类VideoWindow(videowindow.cpp和videowindow.h)中包含了一个QWidget对象,通过将QWidget对象的wid传递给MPV播放引擎用来显示视频。示例将视频的显示长宽比固定为了4/3。具体代码见:https://github.com/eightplus/examples/blob/master/code/Qt/mympvplayer/videowindow.cpp。3)增加进程控制类类MyProcess(myprocess.cpp和myprocess.h)继承于QProcess,使用上面接收QProcess时提到的QProcess::MergedChannels融合模式。该模块的主要功能有两点:一是负责向MPV发送指令,如播放、暂停等(通过write函数 ,每一条指令需要以"\n"结尾);而是接收MPV反馈的各类数据信息,并通过QRegExp设置正则表达式进行匹配和解析,从而显示一些用户可以识别和理解的信息,并实时根据一些状态信息修改界面状态或更改播放控制等。具体代码见:https://github.com/eightplus/examples/blob/master/code/Qt/mympvplayer/myprocess.cpp。4)增加交互类

类Core(core.cpp和core.h)相当于一个管家,负责播放器图形端和控制端的通信和交互。如图形上的指令通过该类调用进程控制类的方法去给MPV发送指令,MPV的信息通过该类给图形端去显示。具体代码见:https://github.com/eightplus/examples/blob/master/code/Qt/mympvplayer/core.cpp。

5)增加其他模块类上面提交的4个模块,已经将播放器需要的图形显示、数据管理和指令处理描述完毕,接下来还需要增加一些辅助类,让自定义的播放器功能更完善,如配置项类Preferences、视频文件数据结构类MediaData、视频文件各类数据设置类MediaSettings、MPV各类数据获取类InfoReader和辅助功能模块类Utils。

参考文档和项目:

https://github.com/ukui/kylin-video/https://mpv.io/manual/master/#configuration-fileshttps://mpv.io/manual/stable/https://github.com/mpv-player/mpv/blob/master/etc/mpv.confhttps://github.com/mpv-player/mpv/blob/master/etc/input.conf

绑定成员函数表达式上的非法操作_在优麒麟上使用MPV编写自己的播放器相关推荐

  1. electron forge 好用吗_在优麒麟上使用 Electron 开发桌面应用

    使用 Web 标准来创建桌面 GUI,上手快.成本低.跨平台.自适应分辨率,这些都是 Electron 的优势.

  2. std::bind绑定成员函数,为什么第二个参数必须绑定对象地址

    std::bind 这个函数在绑定成员函数的时候,必须显示指明实例化后的对象的地址. 因为在此处bind的第一个参数是 类 的成员函数的地址,没有经过实例化,所以不是内存中真正的位置,需要配合实例化后 ...

  3. boost::regex模块在 cpp 文件中搜索类定义,使用绑定成员函数回调测试程序

    boost::regex模块在 cpp 文件中搜索类定义,使用绑定成员函数回调测试程序 实现功能 C++实现代码 实现功能 boost::regex模块在 cpp 文件中搜索类定义,使用绑定成员函数回 ...

  4. java 非法操作异常_java – 空结果集上的非法操作

    我正试图在杂货店建立一个付款台,我的代码实际上执行了我打算做的事情,但有一件事. 在我要求用户输入他们想要的项目数量之后,产品信息被收集并且工作正常,但是当它要求用户输入下一个产品的产品ID时,该行重 ...

  5. 轻轻松松在优麒麟上使用 Steam 畅玩大型游戏

    Steam 平台是目前全球最大的综合性数字发行平台之一,由 Counter-Strike(CS) 的开发公司 Valve 聘请出的 BT 软件编写者 Bram.Cohen 亲自开发创建.原先只是作为 ...

  6. 游戏党注意了,超80款Steam游戏可在优麒麟上畅玩

    各位优客们,你还在为没有游戏玩而烦恼吗?根据 ProtonDB 网站显示,现在 80% 的 Steam 上排名前 100 的游戏都能在 Linux 桌面上会运行的很好.我们前面也出过一期详细教程教大家 ...

  7. (转载)历史——YouTube 上传第一个视频;网易云音乐正式上线;数字音频播放器的发明者出生

    透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是 2022 年 4 月 23 日,世界读书日.在 1564 年的这一天,全世界最卓越的文学家之一莎士比亚出生:1616 年的这一天,莎 ...

  8. 教程:如何在优麒麟上畅玩沙盒游戏--《我的世界》

    技术文章看累了?接下来由小优带领大家轻松一下,教大家如何在优麒麟上畅玩沙盒游戏–<我的世界>.本篇教程来自优麒麟核心爱好者陌生人的投稿,也欢迎大家与我们一起分享你喜爱的游戏哦! 01 安装 ...

  9. 中标麒麟mysql 安装_在中标麒麟上安装达梦数据库V8

    一.VNC环境 测试机IP:119.96.110.196:5902 VNC密码:dameng123 root账号密码:dameng123 二.中标麒麟操作系统环境配置 2.1 上传达梦数据库安装介质 ...

最新文章

  1. Fescar 发布 0.3.0 版本, 支持 Eureka 注册中心
  2. GeoPandas 笔记: GeoDataFrame.plot()
  3. 【Python入门】Python之OS模块39个常用函数详解
  4. powwr shell_Powershell Do While 循环
  5. 深入浅出设计模式——组合模式(Composite Pattern)
  6. 疯狂python讲义pdf_火了!她说:“请给我推荐一本Python书!”
  7. tp5支持啥数据库_MS Access数据库是被严重低估的一款优秀软件
  8. Cascader 级联选择器
  9. 通过反射突破访问修饰符,调用private私有的方法
  10. 开源游戏引擎_Hatchit:开源游戏引擎
  11. R语言学习笔记:矩阵与数组(array)
  12. CSS和JS引用图片(资源)的路径问题
  13. 用“看板图”实现敏捷项目的可视化
  14. 2020美赛回忆录|平生第一次打美赛的获奖方式......美赛准备方法和思想
  15. 发布 html win7 工具,win7 天气 Win7自带的桌面天气工具怎么使用
  16. Arcgis实现nc数据区域裁剪并输出nc文件
  17. Jenkins配置邮件, Extended E-mail Notification, 破解管理员密码
  18. 《吐血整理》一篇文章教你学废Git版本管理
  19. 可以打开c语言的软件图标是个虫子,VC雕虫小技集(四) (转)
  20. Linux 文档编辑 : let 命令详解

热门文章

  1. 从构建分布式秒杀系统聊聊限流特技
  2. 你有什么技能是公司离不开你
  3. 未来数据中心的选择:宽带多模光纤
  4. 我共享的资源,有四个上了首页的排行榜。
  5. 如何处理大数据:微博信息流数据库设计
  6. ProLiant 服务器安装 Ret Hat Enterprise Linux AS 3 说明 (一)
  7. 使用Process Explorer查看托管进程的性能记数器
  8. MySQL基础篇:SELECT几种子句
  9. 丢掉虚拟机,在裸机上使用 Kubernetes 六大优势!
  10. 业务系统性能问题分析和诊断