如何更改QML中有多个音轨的视频的音轨

2024-09-10 21:45:52 发布

您现在位置:Python中文网/ 问答频道 /正文

如何更改具有多个音轨的视频的音轨?例如,我有一个电影的.mkv文件,里面有印地语和英语的音频。但是当我用GNOME视频播放器播放它时,它会默认播放印地语。Gnome视频有更改音轨的选项。说到QML,我们如何指定需要以哪种语言播放视频。我正在使用QML QT多媒体视频组件

这就是未来的样子

Video {
    id: video
    width : 800
    height : 600
    source: "video.mkv"
    language: "English"

    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)
}

Tags: 文件play视频电影videopositionseekkeys
1条回答
网友
1楼 · 发布于 2024-09-10 21:45:52

基本上,这个问题与this post中的问题相同,因此我将忽略解释(要完全理解答案,您必须先阅读my other answer的解释),只提供代码

考虑到上述情况,有必要访问mediaplayer,但不幸的是,项Video不允许访问,因此必须使用VideoOutput+mediaplayer

PyQt5:

from PyQt5 import QtCore, QtGui, QtQml, QtMultimedia
import sip


class PlayerHelper(QtCore.QObject):
    qmlplayerChanged = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.qml_player = None

    @QtCore.pyqtProperty(QtCore.QObject, notify=qmlplayerChanged)
    def qmlplayer(self):
        return self.qmlplayer

    @qmlplayer.setter
    def qmlplayer(self, player):
        self.qml_player = player
        self.qmlplayerChanged.emit()

    @staticmethod
    def get_stream_control(qmlplayer):
        mediaObject = qmlplayer.property("mediaObject")
        player = sip.cast(mediaObject, QtMultimedia.QMediaPlayer)
        control = player.service().requestControl(
            "org.qt-project.qt.mediastreamscontrol/5.0"
        )
        return sip.cast(control, QtMultimedia.QMediaStreamsControl)

    @QtCore.pyqtSlot(result=int)
    def audioCount(self):
        if not self.qml_player:
            return -1
        stream_control = self.get_stream_control(self.qml_player)
        count = 0
        for i in range(stream_control.streamCount()):
            if (
                stream_control.streamType(i)
                == QtMultimedia.QMediaStreamsControl.AudioStream
            ):
                count += 1
        return count

    @QtCore.pyqtSlot(int)
    def setAudioActive(self, index):
        if not self.qml_player:
            return
        stream_control = self.get_stream_control(self.qml_player)
        count = 0
        for i in range(stream_control.streamCount()):
            if (
                stream_control.streamType(i)
                == QtMultimedia.QMediaStreamsControl.AudioStream
            ):
                if index == count:
                    stream_control.setActive(i, True)
                    return
                count += 1

    @QtCore.pyqtSlot(result=int)
    def audioActive(self):
        if not self.qml_player:
            return -1
        stream_control = self.get_stream_control(self.qml_player)
        count = 0
        for i in range(stream_control.streamCount()):
            if (
                stream_control.streamType(i)
                == QtMultimedia.QMediaStreamsControl.AudioStream
            ):
                if stream_control.isActive(i):
                    return count
                count += 1
        return -1


if __name__ == "__main__":
    import os
    import sys

    app = QtGui.QGuiApplication(sys.argv)

    QtQml.qmlRegisterType(PlayerHelper, "AudioHelper", 1, 0, "PlayerHelper")

    engine = QtQml.QQmlApplicationEngine()
    file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "main.qml")
    engine.load(QtCore.QUrl.fromLocalFile(file))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

main.qml

import QtQuick 2.14
import QtQuick.Controls 2.14
import QtMultimedia 5.14

import AudioHelper 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480

    MediaPlayer {
        id: player
        source: "video.mkv"
    }

    PlayerHelper{
        id: playerhelper
        qmlplayer: player
    }

    VideoOutput {
        id: videoOutput
        source: player
        anchors.fill: parent

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

        MouseArea{
            anchors.fill: parent
            acceptedButtons: Qt.LeftButton | Qt.RightButton
            onClicked: {

                if (mouse.button == Qt.LeftButton){
                    player.play()
                }
                else{
                    var count = playerhelper.audioCount()
                    var index = playerhelper.audioActive()

                    while(context_menu.count){
                        var it = context_menu.takeItem(0)
                        it.destroy()
                    }

                    for(var i = 0; i < count; ++i){
                        var item = Qt.createQmlObject('import QtQuick 2.13; import QtQuick.Controls 2.13; MenuItem {}', context_menu)
                        item.text = "Audio " + i;
                        item.checkable = true
                        item.checked = i == index 
                        var f = function(it, i){ 
                            it.triggered.connect(function (){ 
                                playerhelper.setAudioActive(i)
                            }
                        )}
                        f(item, i)
                        context_menu.addItem(item)
                    }

                    context_menu.popup(mouseX, mouseY)
                }
            }
        }

        Menu {
            id: context_menu
        }
    }
}

相关问题 更多 >