QMediaPlayer。如何播放带有多个音频的视频?

2023-12-03

有一个带有两个音轨的视频文件:

  Duration: 01:05:09.12, start: 0.000000, bitrate: 2781 kb/s
    Stream #0:0: Video: mpeg4 (Advanced Simple Profile) (XVID / 0x44495658), yuv420p, 720x400 [SAR 1:1 DAR 9:5], 1998 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc
    Stream #0:1: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), fltp, 384 kb/s
    Stream #0:2: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), fltp, 384 kb/s

用这段代码玩一下:

self.player = QMediaPlayer()
self.player.setMedia(QMediaContent(QUrl.fromLocalFile(fileName)))
self.player.play()

播放视频和第一个音轨。如何切换到第二个音轨?


正如 @musicamante 在评论中指出的那样,解决方案是访问 QMediaStreamsControl 但 PyQt5 不会公开它。

相反,PySide2 确实公开了它,解决方案是使用 shiboken2 进行转换:

import os

from PySide2 import QtCore, QtWidgets, QtMultimedia, QtMultimediaWidgets

import shiboken2


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        video_widget = QtMultimediaWidgets.QVideoWidget()
        self.player = QtMultimedia.QMediaPlayer(
            self, QtMultimedia.QMediaPlayer.VideoSurface
        )
        file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test5.mkv")
        self.player.setMedia(
            QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file))
        )
        self.player.setVideoOutput(video_widget)
        self.player.play()
        self.setCentralWidget(video_widget)

        control = self.player.service().requestControl(
            "org.qt-project.qt.mediastreamscontrol/5.0"
        )
        qptr = shiboken2.getCppPointer(control)[0]
        self.qcontrol = shiboken2.wrapInstance(qptr, QtMultimedia.QMediaStreamsControl)
        self.resize(640, 480)

    def contextMenuEvent(self, event):
        menu = QtWidgets.QMenu()
        group = QtWidgets.QActionGroup(menu)
        group.setExclusive(True)
        index = 0
        for i in range(self.qcontrol.streamCount()):
            t = self.qcontrol.streamType(i)
            if t == QtMultimedia.QMediaStreamsControl.AudioStream:
                action = menu.addAction("Audio-{}".format(index))
                action.setCheckable(True)
                if self.qcontrol.isActive(i):
                    action.setChecked(True)
                action.setData(i)
                menu.addAction(action)
                index += 1
        action = menu.exec_(self.mapToGlobal(event.pos()))
        if action is not None:
            i = action.data()
            self.qcontrol.setActive(i, True)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

对于 pyqt5,您应该使用 sip 并使用以下代码:

import os

from PyQt5 import QtCore, QtWidgets, QtMultimedia, QtMultimediaWidgets

import sip


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        video_widget = QtMultimediaWidgets.QVideoWidget()
        self.player = QtMultimedia.QMediaPlayer(
            self, QtMultimedia.QMediaPlayer.VideoSurface
        )
        file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test5.mkv")
        self.player.setMedia(
            QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file))
        )
        self.player.setVideoOutput(video_widget)
        self.player.play()
        self.setCentralWidget(video_widget)

        control = self.player.service().requestControl(
            "org.qt-project.qt.mediastreamscontrol/5.0"
        )
        self.qcontrol = sip.cast(control, QtMultimedia.QMediaStreamsControl)
        self.resize(640, 480)

    def contextMenuEvent(self, event):
        menu = QtWidgets.QMenu()
        group = QtWidgets.QActionGroup(menu)
        group.setExclusive(True)
        index = 0
        for i in range(self.qcontrol.streamCount()):
            t = self.qcontrol.streamType(i)
            if t == QtMultimedia.QMediaStreamsControl.AudioStream:
                action = menu.addAction("Audio-{}".format(index))
                action.setCheckable(True)
                if self.qcontrol.isActive(i):
                    action.setChecked(True)
                action.setData(i)
                menu.addAction(action)
                index += 1
        action = menu.exec_(self.mapToGlobal(event.pos()))
        if action is not None:
            i = action.data()
            self.qcontrol.setActive(i, True)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

但正如 QMediaStreamsControl 所指出的那样,它在 PyQt5 中不可用,因此解决方案是公开它,为此您必须:

  1. 下载PyQt5源代码:https://pypi.python.org/packages/source/P/PyQt5/PyQt5-5.14.2.tar.gz
  2. 在 PyQt5 源代码的“sip/QtMultimedia”文件夹中创建文件 qmediastreamscontrol.sip。

    qmediastreamscontrol.sip

    class QMediaStreamsControl : QMediaControl
    {
    %TypeHeaderCode
    #include <qmediastreamscontrol.h>
    %End
    
    public:
        enum StreamType { 
            UnknownStream, 
            VideoStream, 
            AudioStream, 
            SubPictureStream, 
            DataStream 
        };
    
        virtual ~QMediaStreamsControl();
        virtual int streamCount() = 0;
        virtual QMediaStreamsControl::StreamType streamType(int streamNumber) = 0;
        virtual QVariant metaData(int streamNumber, const QString &key) = 0;
        virtual bool isActive(int streamNumber) = 0;
        virtual void setActive(int streamNumber, bool state) = 0;
    
    signals:
        void streamsChanged();
        void activeStreamsChanged();
    
    protected:
    %If (Qt_5_6_1 -)
        explicit QMediaStreamsControl(QObject *parent /TransferThis/ = 0);
    %End
    %If (- Qt_5_6_1)
        QMediaStreamsControl(QObject *parent /TransferThis/ = 0);
    %End
    };
    
  3. Add %Include qmediastreamscontrol.sip到文件末尾 sip/QtMultimedia/QtMultimediamod.sip

  4. 使用修改后的源代码编译并安装 PyQt5。

综上所述:

  • 如果您使用 pyside2,解决方案很简单。

  • 如果您使用 pyqt5,则必须修改其源代码,编译并安装它。希望 @musicamante 报告类 QMediaStreamsControl 在 pyqt5 的未来版本中公开

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QMediaPlayer。如何播放带有多个音频的视频? 的相关文章

  • 使用Python开发Web应用程序

    我一直在用 python 做一些工作 但这都是针对独立应用程序的 我很想知道 python 的任何分支是否支持 Web 开发 有人还会建议一个好的教程或网站吗 我可以从中学习一些使用 python 进行 Web 开发的基础知识 既然大家都说
  • Python BigQuery 存储。并行读取多个流

    我有以下玩具代码 import pandas as pd from google cloud import bigquery storage v1beta1 import os import google auth os environ G
  • Django REST序列化器:创建对象而不保存

    我已经开始使用 Django REST 框架 我想做的是使用一些 JSON 发布请求 从中创建一个 Django 模型对象 然后使用该对象而不保存它 我的 Django 模型称为 SearchRequest 我所拥有的是 api view
  • 更改自动插入 tkinter 小部件的文本颜色

    我有一个文本框小部件 其中插入了三条消息 一条是开始消息 一条是结束消息 一条是在 单位 被摧毁时发出警报的消息 我希望开始和结束消息是黑色的 但被毁坏的消息 参见我在代码中评论的位置 插入小部件时颜色为红色 我不太确定如何去做这件事 我看
  • 安装后 Anaconda 提示损坏

    我刚刚安装张量流GPU创建单独的后环境按照以下指示here https github com antoniosehk keras tensorflow windows installation 但是 安装后当我关闭提示窗口并打开新航站楼弹出
  • NameError:名称“urllib”未定义”

    CODE import networkx as net from urllib request import urlopen def read lj friends g name fetch the friend list from Liv
  • feedparser 在脚本运行期间失败,但无法在交互式 python 控制台中重现

    当我运行 eclipse 或在 iPython 中运行脚本时 它失败了 ascii codec can t decode byte 0xe2 in position 32 ordinal not in range 128 我不知道为什么 但
  • 在pyyaml中表示具有相同基类的不同类的实例

    我有一些单元测试集 希望将每个测试运行的结果存储为 YAML 文件以供进一步分析 YAML 格式的转储数据在几个方面满足我的需求 但测试属于不同的套装 结果有不同的父类 这是我所拥有的示例 gt gt gt rz shorthand for
  • Python:字符串不会转换为浮点数[重复]

    这个问题在这里已经有答案了 我几个小时前写了这个程序 while True print What would you like me to double line raw input gt if line done break else f
  • Geopandas 设置几何图形:MultiPolygon“等于 len 键和值”的 ValueError

    我有 2 个带有几何列的地理数据框 我将一些几何图形从 1 个复制到另一个 这对于多边形效果很好 但对于任何 有效 多多边形都会返回 ValueError 请指教如何解决这个问题 我不知道是否 如何 为什么应该更改 MultiPolygon
  • 循环中断打破tqdm

    下面的简单代码使用tqdm https github com tqdm tqdm在循环迭代时显示进度条 import tqdm for f in tqdm tqdm range 100000000 if f gt 100000000 4 b
  • Python - 在窗口最小化或隐藏时使用 pywinauto 控制窗口

    我正在尝试做的事情 我正在尝试使用 pywinauto 在 python 中创建一个脚本 以在后台自动安装 notepad 隐藏或最小化 notepad 只是一个示例 因为我将编辑它以与其他软件一起使用 Problem 问题是我想在安装程序
  • Numpy 优化

    我有一个根据条件分配值的函数 我的数据集大小通常在 30 50k 范围内 我不确定这是否是使用 numpy 的正确方法 但是当数字超过 5k 时 它会变得非常慢 有没有更好的方法让它更快 import numpy as np N 5000
  • Python 3 中“map”类型的对象没有 len()

    我在使用 Python 3 时遇到问题 我得到了 Python 2 7 代码 目前我正在尝试更新它 我收到错误 类型错误 map 类型的对象没有 len 在这部分 str len seed candidates 在我像这样初始化它之前 se
  • Nuitka 未使用 nuitka --recurse-all hello.py [错误] 编译 exe

    我正在尝试通过 nuitka 创建一个简单的 exe 这样我就可以在我的笔记本电脑上运行它 而无需安装 Python 我在 Windows 10 上并使用 Anaconda Python 3 我输入 nuitka recurse all h
  • 如何将 PIL 图像转换为 NumPy 数组?

    如何转换 PILImage来回转换为 NumPy 数组 这样我就可以比 PIL 进行更快的像素级转换PixelAccess允许 我可以通过以下方式将其转换为 NumPy 数组 pic Image open foo jpg pix numpy
  • 在Python中重置生成器对象

    我有一个由多个yield 返回的生成器对象 准备调用该生成器是相当耗时的操作 这就是为什么我想多次重复使用生成器 y FunctionWithYield for x in y print x here must be something t
  • 如何在 Django 中使用并发进程记录到单个文件而不使用独占锁

    给定一个在多个服务器上同时执行的 Django 应用程序 该应用程序如何记录到单个共享日志文件 在网络共享中 而不保持该文件以独占模式永久打开 当您想要利用日志流时 这种情况适用于 Windows Azure 网站上托管的 Django 应
  • 在 Pandas DataFrame Python 中添加新列[重复]

    这个问题在这里已经有答案了 例如 我在 Pandas 中有数据框 Col1 Col2 A 1 B 2 C 3 现在 如果我想再添加一个名为 Col3 的列 并且该值基于 Col2 式中 如果Col2 gt 1 则Col3为0 否则为1 所以
  • Spark.read 在 Databricks 中给出 KrbException

    我正在尝试从 databricks 笔记本连接到 SQL 数据库 以下是我的代码 jdbcDF spark read format com microsoft sqlserver jdbc spark option url jdbc sql

随机推荐

  • assetic.ERROR“DoctrineBundle:Collector:db.html.twig”包含错误:未知的“profiler_dump”函数

    我正在尝试使用 Symfony 发送电子邮件 一切在本地运行都很完美 但在服务器上我收到以下错误prod log assetic ERROR The template SecurityBundle Collector security ht
  • 如何更改EditText中的线条颜色

    我正在我的布局 xml 文件中创建一个 EditText 但我想将 EditText 中的颜色线从 Holo 更改为 例如 红色 如何做到这一点 这是您可以用于所有视图的最佳工具 并且它是免费的 非常感谢 杰罗姆 范德林登 Android
  • 设置 Firebase 存储文件大小和文件数量限制

    我上传成功images使用 AngularFire2 进行 Firebase 存储 我有以下上传代码 this AfStorage ref images userId timeStamp putString base64Image data
  • 未找到名称为“default”的配置。安卓工作室

    我有一个 Android Studio 应用程序 它有一个库依赖项 Android Bootstrap 当我尝试同步 gradle 时 它 给了我一个错误 未找到名称为 default 的配置 我的结构是 FTPBackup fotobac
  • 在UIWebview ios中显示特定的pdf页面

    我目前正在开发一个项目 我有 ios 需要显示 pdf 文件 不过我想选择要显示的页面 例如 请参阅 UIWebView 中的第 10 页 共 37 页 我还没有找到一种方法来干净地分离 pfd 的页面 感谢您的帮助 Use UIWebVi
  • 在 Bash 中将命令行参数转换为数组

    如何将命令行参数转换为 bash 脚本数组 我想采取这个 something sh arg1 arg2 arg3 并将其转换为 myArray arg1 arg2 arg3 这样我就可以在脚本中使用 myArray 来进一步使用 上一篇文章
  • 为 MSSQL Server docker 映像启用 XA 事务

    我有用于开发的 MSSQL Server Linux docker 映像 我需要在此实例上启用 XA 事务 我进行了很多搜索 但我发现的所有教程仅显示如何从 Windows 计算机执行此操作 而不显示 Linux 那么如何从命令行启用 XA
  • 迭代值时,为什么当 value 是数字时 typeof(value) 返回“string”? JavaScript

    我使用 Google Chrome 进行此测试 与直觉相反 第一个循环警告 string 三次 而第二个循环警告 number 三次 numarray 1 2 3 for each loop for num in numarray aler
  • 如何正确清理存储电子邮件的 SQL 查询

    我有一个查询 该查询转到邮箱并尝试将所有电子邮件保存在表中 它在大多数情况下都有效 但当电子邮件内容值包含双引号或单引号时 它会失败 如何修改我的代码以正确插入所有查询 num imap num msg imap if num gt 0 f
  • 如何在javascript中访问单击的表格行的特定单元格

    我有一个从数据库填充的 HTML 表 以及一个 jquery 函数 将客户端单击事件添加到每个表行 function TreeTable tr each function index this click function alert th
  • 使用 OpenCV 组合两个图像

    我正在尝试使用 OpenCV 2 1 将两个图像合并为一个 并将两个图像彼此相邻放置 在Python中 我正在做 import numpy as np cv img1 cv LoadImage fn1 0 img2 cv LoadImage
  • 保存为 GIF 后图像质量下降

    我正在开发一款 iOS 应用程序 它允许用户拍摄一系列照片 然后将照片放入动画中并导出为 MP4 和 GIF 虽然 MP4 呈现源质量 但 GIF 颜色等级是可见的 这是视觉比较 GIF MP4 我用于导出为 GIF 的代码 var dic
  • Android Firebase 消息传递 SDK 如何防范 Intent 欺骗?

    我使用 Firebase Messaging 创建了一个简单的项目 并使用以下依赖项 implementation com google firebase firebase messaging 20 0 0 我已经构建了该应用程序并检查了它
  • SwiftUI 登录页面布局

    我正在探索 SwiftUI 因为我正在尝试构建登录视图 现在我面临一个问题 这就是我想要实现的目标 正如你所看到的 我已经达到了这一点 但我不喜欢我的实现 struct ContentView View State var username
  • Twilio Studio:将短信对话日志转发到电子邮件

    我正在使用 SMS studio 与入站 SMS 消息进行快速聊天机器人对话 并希望在完成后将对话日志转发到电子邮件 我编写了一个使用 SendGrid API 的函数将短信转发至电子邮件 它独立工作 即 如果我将电话号码配置为在文本输入时
  • _泛型与可变参数函数相结合?

    在 C11 中 我可以创建一个函数 其原型如下所示 void myVaFunc const char const conv 我可以这样运行它 myVaFunc ici 1 test 2 该函数会知道 解析第一个参数后 还有 3 个附加参数
  • QImage 能够打开并渲染纯 16 位图像吗?

    我想标题已经解释了我想知道的事情 有没有可能用 Qt 打开和保存 16 位图像 我并不是指 3 8 24 位或 4 8 32 位 这与纯 8 位图像完全相同 我指的是 R G 和 B 的纯 16 位 与 Patrice 所说的相反 每个组件
  • 詹金斯奴隶中的“mvn:未找到”

    我有 Jenkins Slave 安装了 Java 和 Maven 环境是 Debian 我可以在控制台中运行 java version 和 mvn version 命令 但是当我尝试在 Jenkins 作业中执行 shell 命令时 我收
  • 如何将图像和文本垂直居中对齐?

    我在顶部有一个 DIV 和一些锚点 第一个是徽标样式 其余的是文本 我设置的样式如下 div nav top height 120px vertical align middle a nav logo background no repea
  • QMediaPlayer。如何播放带有多个音频的视频?

    有一个带有两个音轨的视频文件 Duration 01 05 09 12 start 0 000000 bitrate 2781 kb s Stream 0 0 Video mpeg4 Advanced Simple Profile XVID