You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PySide6的QMediaPlayer设置视频字幕失败问题排查

问题:PySide6 QMediaPlayer无法识别视频内置字幕

我正在开发一款可播放视频并显示内置字幕的程序,但字幕相关功能未按预期工作。

可复现代码

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

    # 尝试查看字幕..
    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: []

环境细节

  • 系统:Windows 10
  • Python版本:3.10.10
  • PySide版本:6.4.2

我曾尝试通过ffmpeg-python将srt文件添加为视频字幕。


解决方案

错误原因

核心问题是调用字幕API的时机过早:QMediaPlayer加载媒体是异步操作,你在调用play()后立即查询字幕轨道,此时媒体还未完成加载,自然无法获取到有效信息。

修正步骤

  1. 监听QMediaPlayer的mediaStatusChanged信号,等待媒体状态变为LoadedMedia(加载完成)后再操作字幕轨道。
  2. 确保视频内嵌字幕的格式被Qt支持(如SRT/ASS),且ffmpeg打包时参数正确,保证字幕轨道有效嵌入。

修正后的代码

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

def handle_media_status(status):
    # 媒体加载完成后处理字幕
    if status == QMediaPlayer.MediaStatus.LoadedMedia:
        subtitle_tracks = player.subtitleTracks()
        print("可用字幕轨道数量:", len(subtitle_tracks))
        if subtitle_tracks:
            player.setActiveSubtitleTrack(0)
            print("当前激活字幕轨道索引:", player.activeSubtitleTrack())

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

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

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

    # 绑定媒体状态变化信号
    player.mediaStatusChanged.connect(handle_media_status)

    # 使用本地文件路径的标准写法,避免解析错误
    player.setSource(QUrl.fromLocalFile("video_subs.mkv"))
    player.play()

    main_win = QMainWindow()
    main_win.setCentralWidget(video_widget)
    main_win.resize(800, 600)
    main_win.show()
    sys.exit(app.exec())

额外说明

  • 用QUrl.fromLocalFile()替代直接传字符串,能避免Windows下相对路径的解析问题。
  • 若仍无法识别字幕,检查ffmpeg打包命令是否正确:比如内嵌SRT字幕时,需确保使用-c:s copy保留原格式,或指定Qt支持的编码器,避免字幕轨道损坏。

内容的提问来源于stack exchange,提问作者Lurû

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 18:23:13