使用 QMediaPlayer (PySide6) 为视频设置字幕

问题描述 投票:0回答:1

我正在尝试制作一个播放视频并显示其字幕的程序,以备不时之需。问题是字幕功能没有像我预期的那样工作。

可复制的小例子

import sys
from PySide6.QtCore import QUrl
from PySide6.QtWidgets import (QApplication,QMainWindow)
from PySide6.QtMultimedia import (QAudioOutput, QMediaPlayer)
from PySide6.QtMultimediaWidgets import QVideoWidget

if __name__ == '__main__':
    app = QApplication(sys.argv)

    audio_output = QAudioOutput()
    video_widget = QVideoWidget()
    player = QMediaPlayer()

    player.setAudioOutput(audio_output)
    player.setVideoOutput(video_widget)

    player.setSource(QUrl("video_subs.mkv"))
    player.play()

    # trying to view subtitles..
    print("1: ", player.activeSubtitleTrack())
    player.setActiveSubtitleTrack(0)
    print("2: ", player.subtitleTracks())

    main_win = QMainWindow()
    main_win.setCentralWidget(video_widget)
    available_geometry = main_win.screen().availableGeometry()
    main_win.show()
    sys.exit(app.exec())

输出

1: -1
2: []

正如您从输出中看到的那样,函数似乎出现故障。我做错了什么?

python python-3.x pyside6 subtitle qmediaplayer
1个回答
0
投票

在媒体完成加载之前,字幕轨道将不可用。因此,一旦达到适当的状态,您应该使用 mediaStatusChanged 信号 查询可用轨道,然后才尝试设置字幕轨道。

这是基于您的示例的基本演示:

import sys
from PySide6.QtCore import QUrl
from PySide6.QtWidgets import (QApplication,QMainWindow)
from PySide6.QtMultimedia import (QAudioOutput, QMediaPlayer)
from PySide6.QtMultimediaWidgets import QVideoWidget

if __name__ == '__main__':
    app = QApplication(sys.argv)

    audio_output = QAudioOutput()
    video_widget = QVideoWidget()
    player = QMediaPlayer()

    player.setAudioOutput(audio_output)
    player.setVideoOutput(video_widget)

    def status_changed(state):
        if state == QMediaPlayer.MediaStatus.LoadedMedia:
            if tracks := player.subtitleTracks():
                for index, track in enumerate(tracks):
                    print(f'Track ({index}):')
                    for key in track.keys():
                        print(f'  {track.metaDataKeyToString(key)} = '
                              f'{track.stringValue(key)}')
                player.setActiveSubtitleTrack(0)
            else:
                print('No subtitle tracks')

    player.mediaStatusChanged.connect(status_changed)

    player.setSource(QUrl("video_subs.mkv"))
    player.play()

    main_win = QMainWindow()
    main_win.setCentralWidget(video_widget)
    available_geometry = main_win.screen().availableGeometry()
    main_win.show()
    sys.exit(app.exec())

输出:

Track (0):
  Audio bit rate = 70
  Date = 2023-03-18T20:32:27.000Z
  Language = Default
  Title = English Subtitles
Track (1):
  Audio bit rate = 80
  Date = 2023-03-18T20:32:27.000Z
  Language = Default
  Title = German Subtitles

PS:我使用 mkvmerge 将字幕轨道添加到 mkv 中,并为每个轨道明确设置语言。然而,尽管 mkvinfo 工具正确显示了语言,但 Qt 却没有。 Qt 在我的系统上使用的平台多媒体后端是 gstreamer - 它也为字幕轨道显示正确的语言标签。所以看起来 Qt 某处可能存在错误......

© www.soinside.com 2019 - 2024. All rights reserved.