【问题标题】: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);
}
}
}