Files
QtPotato/autotests/subtitleextractortest.cpp
T

98 lines
3.4 KiB
C++

// SPDX-FileCopyrightText: 2026 Tri Vo Khac
// SPDX-License-Identifier: GPL-3.0-or-later
#include "subtitleextractor.h"
#include <QFile>
#include <QProcess>
#include <QStandardPaths>
#include <QTemporaryDir>
#include <QTest>
using namespace Qt::Literals::StringLiterals;
class SubtitleExtractorTest : public QObject
{
Q_OBJECT
private:
// Makes \a name in \a dir with a German audio track plus \a subtitleLanguages as
// SRT subtitle tracks, in that order.
static QString makeSample(const QTemporaryDir &dir, const QString &name, const QStringList &subtitleLanguages)
{
const QString ffmpeg = QStandardPaths::findExecutable(u"ffmpeg"_s);
const QString srt = dir.filePath(u"line.srt"_s);
QFile file(srt);
if (!file.open(QIODevice::WriteOnly) || file.write("1\n00:00:00,000 --> 00:00:01,000\nHello\n") < 0) {
return {};
}
file.close();
QStringList args{u"-v"_s, u"error"_s, u"-f"_s, u"lavfi"_s, u"-i"_s, u"sine=duration=1"_s};
for (qsizetype i = 0; i < subtitleLanguages.size(); ++i) {
args << u"-i"_s << srt;
}
args << u"-map"_s << u"0:a"_s << u"-metadata:s:a:0"_s << u"language=ger"_s;
for (qsizetype i = 0; i < subtitleLanguages.size(); ++i) {
args << u"-map"_s << u"%1:s"_s.arg(i + 1) << u"-metadata:s:s:%1"_s.arg(i) << u"language=%1"_s.arg(subtitleLanguages.at(i));
}
const QString path = dir.filePath(name);
args << u"-c:s"_s << u"srt"_s << path;
QProcess process;
process.start(ffmpeg, args);
if (!process.waitForFinished() || process.exitCode() != 0) {
qWarning() << process.readAllStandardError();
return {};
}
return path;
}
private Q_SLOTS:
void initTestCase()
{
if (QStandardPaths::findExecutable(u"ffmpeg"_s).isEmpty()) {
QSKIP("ffmpeg is needed to make sample files");
}
}
void findTranslationSourcePrefersEnglish()
{
QTemporaryDir dir;
const QString path = makeSample(dir, u"episode.mkv"_s, {u"fre"_s, u"eng"_s});
QVERIFY(!path.isEmpty());
const Subtitles::SourceResult result = Subtitles::findTranslationSource(path);
QVERIFY2(result.error.isEmpty(), qPrintable(result.error));
// Stream 0 is the audio, 1 French, 2 English.
QCOMPARE(result.streamIndex, 2);
std::atomic_bool cancelled = false;
const Subtitles::ExtractResult cues = Subtitles::extractEmbedded(path, result.streamIndex, cancelled);
QCOMPARE(cues.cues.size(), 1);
QCOMPARE(cues.cues.first().text, u"Hello"_s);
}
void findTranslationSourceFallsBackToTheAudioLanguage()
{
QTemporaryDir dir;
const QString path = makeSample(dir, u"episode.mkv"_s, {u"fre"_s, u"ger"_s});
QVERIFY(!path.isEmpty());
QCOMPARE(Subtitles::findTranslationSource(path).streamIndex, 2);
}
void findTranslationSourceWithoutSubtitles()
{
QTemporaryDir dir;
const QString path = makeSample(dir, u"episode.mkv"_s, {});
QVERIFY(!path.isEmpty());
const Subtitles::SourceResult result = Subtitles::findTranslationSource(path);
QVERIFY(result.error.isEmpty());
QCOMPARE(result.streamIndex, -1);
QVERIFY(!Subtitles::findTranslationSource(dir.filePath(u"missing.mkv"_s)).error.isEmpty());
}
};
QTEST_GUILESS_MAIN(SubtitleExtractorTest)
#include "subtitleextractortest.moc"