fix(mpv): auto-select subtitle and audio tracks on file open (#12)
Closes #7 mpv only turns on a subtitle that is flagged default or matches `slang`, so releases like VisionQuest (Russian dub by default, ru/ru/en subtitles, none flagged) open with subtitles off, which also disabled **Translate subtitle**. - New `TrackSelection` helpers in `qtpotato_core` with unit tests. - On file load: audio follows *Preferred languages* (Playback settings); subtitle follows *Preferred languages* (Subtitles settings), else keeps mpv's choice, else (new *Turn on a subtitle when none matches*, on by default) picks a full text subtitle in the system language, then English, then the audio language, then the default/first track. - Translate is enabled whenever the file has a text subtitle; with none or a bitmap subtitle shown it translates the best text track (English first). Verified in the real app on VisionQuest S01E01: subtitle 3 (en) is selected on open; with audio set to `en` and auto-select off, audio switches to track 7, subtitle stays off and Translate stays enabled with the English source. Reviewed-on: #12 Co-authored-by: Tri Vo Khac <git@trivk.dev>
This commit was merged in pull request #12.
This commit is contained in:
1 parent
32c686e0e3
commit
b34a01a92f
13 files changed
+437
-1
No files matched your search
@@ -1,11 +1,13 @@
|
||||
#include "mpvitem.h"
|
||||
|
||||
#include "mpvuserconfig.h"
|
||||
#include "trackselection.h"
|
||||
|
||||
#include <MpvController>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QLocale>
|
||||
#include <QSaveFile>
|
||||
#include <QStandardPaths>
|
||||
|
||||
@@ -25,6 +27,33 @@ QVariant trackIdValue(int id)
|
||||
{
|
||||
return id > 0 ? QVariant(id) : QVariant(QStringLiteral("no"));
|
||||
}
|
||||
|
||||
QList<TrackSelection::Track> selectionTracks(const QVariantList &tracks)
|
||||
{
|
||||
QList<TrackSelection::Track> result;
|
||||
for (const QVariant &entry : tracks) {
|
||||
const QVariantMap track = entry.toMap();
|
||||
result.append({
|
||||
.id = track.value(QStringLiteral("id")).toInt(),
|
||||
.lang = track.value(QStringLiteral("lang")).toString(),
|
||||
.codec = track.value(QStringLiteral("codec")).toString(),
|
||||
.forced = track.value(QStringLiteral("forced")).toBool(),
|
||||
.isDefault = track.value(QStringLiteral("default")).toBool(),
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString trackLanguage(const QVariantList &tracks, int id)
|
||||
{
|
||||
for (const QVariant &entry : tracks) {
|
||||
const QVariantMap track = entry.toMap();
|
||||
if (track.value(QStringLiteral("id")).toInt() == id) {
|
||||
return track.value(QStringLiteral("lang")).toString();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
MpvItem::MpvItem(QQuickItem *parent)
|
||||
@@ -64,6 +93,7 @@ MpvItem::MpvItem(QQuickItem *parent)
|
||||
this,
|
||||
[this] {
|
||||
setFileLoaded(true);
|
||||
selectInitialTracks();
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
connect(
|
||||
@@ -338,6 +368,37 @@ void MpvItem::showTranslatedSubtitleFile(const QUrl &url, const QString &title)
|
||||
commandAsync(QStringList{QStringLiteral("sub-add"), path, QStringLiteral("auto"), title});
|
||||
}
|
||||
|
||||
int MpvItem::translationSourceId() const
|
||||
{
|
||||
// English first: it is the usual original, and dubbed releases often default to
|
||||
// subtitles translated from it.
|
||||
return TrackSelection::pickTranslationSource(selectionTracks(m_subtitleTracks),
|
||||
{QStringLiteral("en"), trackLanguage(m_audioTracks, m_audioId)},
|
||||
m_subtitleId);
|
||||
}
|
||||
|
||||
void MpvItem::selectInitialTracks()
|
||||
{
|
||||
// The observed track-list may still describe the previous file; read it directly.
|
||||
updateTracks(getProperty(QStringLiteral("track-list")).toList());
|
||||
|
||||
const int audioId = TrackSelection::pickAudio(selectionTracks(m_audioTracks), m_preferredAudioLanguages, m_audioId);
|
||||
if (audioId != m_audioId) {
|
||||
setAudioId(audioId);
|
||||
}
|
||||
// Subtitles are for reading: the user's own language, then English, before the
|
||||
// audio language. Dubbed releases often default to a dub with matching subtitles.
|
||||
const QStringList fallbackLanguages{QLocale::languageToCode(QLocale::system().language()), QStringLiteral("en"), trackLanguage(m_audioTracks, audioId)};
|
||||
const int subtitleId = TrackSelection::pickSubtitle(selectionTracks(m_subtitleTracks),
|
||||
m_preferredSubtitleLanguages,
|
||||
fallbackLanguages,
|
||||
m_subtitleId,
|
||||
m_autoSelectSubtitle);
|
||||
if (subtitleId != m_subtitleId) {
|
||||
setSubtitleId(subtitleId);
|
||||
}
|
||||
}
|
||||
|
||||
void MpvItem::showOnlySubtitle(int id)
|
||||
{
|
||||
setSubtitleId(id);
|
||||
@@ -484,6 +545,8 @@ void MpvItem::updateTracks(const QVariantList &trackList)
|
||||
{QStringLiteral("title"), track.value(QStringLiteral("title")).toString()},
|
||||
{QStringLiteral("lang"), track.value(QStringLiteral("lang")).toString()},
|
||||
{QStringLiteral("codec"), track.value(QStringLiteral("codec")).toString()},
|
||||
{QStringLiteral("forced"), track.value(QStringLiteral("forced")).toBool()},
|
||||
{QStringLiteral("default"), track.value(QStringLiteral("default")).toBool()},
|
||||
});
|
||||
continue;
|
||||
}
|
||||
@@ -505,6 +568,9 @@ void MpvItem::updateTracks(const QVariantList &trackList)
|
||||
{QStringLiteral("title"), track.value(QStringLiteral("title")).toString()},
|
||||
{QStringLiteral("lang"), track.value(QStringLiteral("lang")).toString()},
|
||||
{QStringLiteral("codec"), track.value(QStringLiteral("codec")).toString()},
|
||||
{QStringLiteral("bitmap"), TrackSelection::isBitmapSubtitle(track.value(QStringLiteral("codec")).toString())},
|
||||
{QStringLiteral("forced"), track.value(QStringLiteral("forced")).toBool()},
|
||||
{QStringLiteral("default"), track.value(QStringLiteral("default")).toBool()},
|
||||
{QStringLiteral("external"), track.value(QStringLiteral("external")).toBool()},
|
||||
{QStringLiteral("externalFilename"), track.value(QStringLiteral("external-filename")).toString()},
|
||||
{QStringLiteral("ffIndex"), track.value(QStringLiteral("ff-index"), -1).toInt()},
|
||||
|
||||
Reference in new issue
Block a user