【问题标题】:How to force QT5 MediaPlayer to show Subtitles?如何强制 QT5 MediaPlayer 显示字幕?
【发布时间】:2020-08-20 05:39:08
【问题描述】:

我正在评估从 Qt 4.8 到 Qt 5.2 的迁移,最重要的一点是多媒体后端。在 Qt 5.2 中,Qt 4.8 中的 Phonon 后端没有提供一些重要的功能。但至少旧版本显示字幕(SRT文件与视频文件在同一目录中)。

文档和反复试验都没有为我提供任何结果。

那么,有谁知道如何强制 Qt 5 显示这些字幕?或者它甚至不支持(会很遗憾)

任何帮助表示赞赏..

PS: 我需要正好相反:Disable showing subtitle file in QMediaPlayer

【问题讨论】:

    标签: qt qt5 multimedia subtitle


    【解决方案1】:

    您必须在 playbin2 上设置标志 GST_PLAY_FLAG_TEXT。 (它通常默认开启。如果需要,然后在 QGstreamerPlayerSession 的 ctor 中更改它)。

    如果您的字幕文件是外部的,那么您必须在 playbin2 上设置“suburi”属性。 suburi 属性的值是字幕文件的路径。此更改应在方法 QGstreamerPlayerSession::loadFromUri 中完成。

    在 Qt5.2 中,这些更改必须在文件 qgstreamerplayersession.cpp 中完成。您可以在 qtmultimedia/src/plugins/gstreamer/mediaplayer 中找到该文件。旧 4.x 版本的文件位置可能不同。

    我观察到的另一件事是插件代码设置了标志 GST_PLAY_FLAG_NATIVE_VIDEO。如果设置了此标志,则不会显示字幕。您将不得不阻止插件代码设置此标志。您可以注释掉设置此标志的代码,或者您必须将环境变量 QT_GSTREAMER_PLAYBIN_FLAGS 设置为 0x00000017(即 GST_PLAY_FLAG_VIDEO|GST_PLAY_FLAG_AUDIO|GST_PLAY_FLAG_TEXT)。将其设置为任何值都会跳过 GST_PLAY_FLAG_NATIVE_VIDEO 标志。

    完成这些更改后,构建插件并使用它。

    【讨论】:

      【解决方案2】:

      查了很多,显然Qt mediaplayer不支持字幕,我用srt parser显示字幕。

      我的后端类代码:

       #include "backend.h"
      BackEnd::BackEnd(QObject *parent) : QObject(parent)
      {
           readSubtitleFile("./en.srt");
      }
      
      void BackEnd::readSubtitleFile(QString directory)
      {
            cout<< "readSubtitleFile:"<< directory.toStdString()<<endl;
            if(!isFileExist(directory.toStdString())) {
                cout<< "file does not exist"<<endl;
                return ;
            }
            SubtitleParserFactory *subParserFactory = new SubtitleParserFactory(directory.toStdString());
            SubtitleParser *parser = subParserFactory->getParser();
      
            sub = parser->getSubtitles();
      }
      
      QString BackEnd::getSubtitleText(double playTime)
      {
          for(SubtitleItem * element : sub) {
              double startTime = element->getStartTime();
              double endTime = element->getEndTime();
              if( (startTime <= playTime) && (playTime <= endTime)) {
                  cout<< "getSubtitleText: founded"<< element->getText()<<endl;
                  return QString::fromStdString(element->getText());
              }
          }
          cout<< "getSubtitleText: not founded"<< endl;
          return "";
      }
      
      bool BackEnd::isFileExist(const string &temp)
      {
          if (FILE *file = fopen(temp.c_str(), "r")) {
                  fclose(file);
                  return true;
              } else {
                  return false;
              }
      }
      

      我的 qml 文件:

          Window {
          visible: true
          width: 900
          height: 700
          title: qsTr("My Player")
            Rectangle {
              id: root
              color: "black"
              width: parent.width
              height: parent.height
              function msToTime(duration) {
                var milliseconds=parseInt((duration%1000)/100),
                seconds = Math.floor((duration / 1000) % 60),
              minutes = Math.floor((duration / (1000 * 60)) % 60),
              hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
      
            hours = (hours < 10) ? "0" + hours : hours;
            minutes = (minutes < 10) ? "0" + minutes : minutes;
            seconds = (seconds < 10) ? "0" + seconds : seconds;
      
            return hours + ":" + minutes + ":" + seconds;
          }
          Column {
              width: parent.width
              height: parent.height
              Item {
                  width: parent.width
                  height: parent.height-100
                  MediaPlayer {
                      id: mediaplayer
                      source: "file:///E:/1.mp4"
                  }
      
                  VideoOutput {
                      anchors.fill: parent
                      source: mediaplayer
                  }
              }
              Text {
                  id: subtitleText
                  text: qsTr("")
                  y: -150
                  font.pixelSize: 18
                  color: "white"
                  anchors.horizontalCenter: 
               parent.horizontalCenter
              }
          }
          Timer {
            id: refreshTimer
            interval: 1000//30 // 60 Hz
            running: true
            repeat: true
            onTriggered: {
               durationPass.text =  
                  root.msToTime(mediaplayer.position);
               subtitleText.text = 
      
              BackEnd.getSubtitleText(mediaplayer.position);
            }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-09-28
        相关资源
        最近更新 更多