9#include <QtCore/QDateTime>
10#include <QtCore/QFileInfo>
11#include <QtCore/QString>
20 (void) connect(&_timer, &QTimer::timeout,
this, &SubtitleWriter::_captureTelemetry);
35 (void) grid->setProperty(
"settingsGroup", HorizontalFactValueGrid::telemetryBarSettingsGroup);
37 for (
int colIndex = 0; colIndex < grid->
columns()->
count(); colIndex++) {
39 for (
int rowIndex = 0; rowIndex < list->
count(); rowIndex++) {
42 _facts += value->
fact();
49 _lastEndTime = QTime(0, 0);
51 const QFileInfo videoFileInfo(videoFile);
52 const QString subtitleFilePath = QStringLiteral(
"%1/%2.ass").arg(videoFileInfo.path(), videoFileInfo.completeBaseName());
53 qCDebug(SubtitleWriterLog) <<
"Writing overlay to file:" << subtitleFilePath;
54 _file.setFileName(subtitleFilePath);
56 if (!_file.open(QIODevice::ReadWrite)) {
57 qCWarning(SubtitleWriterLog) <<
"Unable to write subtitle data to file";
61 QTextStream stream(&_file);
64 static constexpr int baseWidth = 640;
65 static constexpr int baseFontSize = 12;
66 const int scaledFontSize = (_size.width() * baseFontSize) / baseWidth;
69 stream << QStringLiteral(
71 "Title: QGroundControl Subtitle Telemetry file\n"
72 "ScriptType: v4.00+\n"
74 "ScaledBorderAndShadow: yes\n"
75 "YCbCr Matrix: TV.601\n"
80 "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\n"
81 "Style: Default,Monospace,%3,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,1,10,10,10,1\n"
84 "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n"
85 ).arg(_size.width()).arg(_size.height()).arg(scaledFontSize);
90 _timer.start(1000 / _kSampleRate);
95 qCDebug(SubtitleWriterLog) <<
"Stopping writing";
100void SubtitleWriter::_captureTelemetry()
102 if (!MultiVehicleManager::instance()->activeVehicle()) {
103 qCWarning(SubtitleWriterLog) <<
"Attempting to capture fact data with no active vehicle!";
108 QStringList namesStrings;
109 QStringList valuesStrings;
112 for (
const Fact *fact : std::as_const(_facts)) {
113 valuesStrings << QStringLiteral(
"%2 %3").arg(fact->cookedValueString(), fact->cookedUnits());
114 namesStrings << QStringLiteral(
"%1:").arg(fact->shortDescription());
118 const QTime start = _lastEndTime;
121 const QTime end = start.addMSecs(1000 / _kSampleRate);
126 static constexpr int offsetFactor = 100;
127 static constexpr float nRows = 3;
128 static const int rowWidth = (_size.width() + offsetFactor) / (nRows + 1);
129 const int nValuesByRow = ceil(_facts.length() / nRows);
131 QStringList stringColumns;
135 static const QString namesLine = QStringLiteral(
"Dialogue: 0,%3,%4,Default,,0,0,0,,{\\an3\\pos(%1,%2)}%5\n");
136 static const QString valuesLine = QStringLiteral(
"Dialogue: 0,%3,%4,Default,,0,0,0,,{\\pos(%1,%2)}%5\n");
139 for (
int i = 0; i < nRows; i++) {
140 const QStringList currentColumnNameStrings = namesStrings.mid(i * nValuesByRow, nValuesByRow);
141 const QStringList currentColumnValueStrings = valuesStrings.mid(i * nValuesByRow, nValuesByRow);
144 const QString names = namesLine.arg(QString::number((-offsetFactor / 2) + (rowWidth * (i + 1)) - 10),
145 QString::number(_size.height() - 30),
146 start.toString(
"H:mm:ss.zzz").chopped(2),
147 end.toString(
"H:mm:ss.zzz").chopped(2),
148 currentColumnNameStrings.join(
"\\N"));
149 stringColumns << names;
152 const QString values = valuesLine.arg(QString::number((-offsetFactor / 2) + (rowWidth * (i + 1))),
153 QString::number(_size.height() - 30),
154 start.toString(
"H:mm:ss.zzz").chopped(2),
155 end.toString(
"H:mm:ss.zzz").chopped(2),
156 currentColumnValueStrings.join(
"\\N"));
157 stringColumns << values;
161 stringColumns << QStringLiteral(
"Dialogue: 0,%1,%2,Default,,0,0,0,,{\\pos(10,35)}%3\n").arg(
162 start.toString(
"H:mm:ss.zzz").chopped(2),
163 end.toString(
"H:mm:ss.zzz").chopped(2),
164 QDateTime::currentDateTime().toString(QLocale::system().dateFormat(QLocale::ShortFormat)));
166 QTextStream stream(&_file);
167 for (
const QString &col : std::as_const(stringColumns)) {
#define QGC_LOGGING_CATEGORY(name, categoryStr)
QmlObjectListModel * columns(void) const
void componentComplete(void) final
A Fact is used to hold a single value within the system.
int count() const override final
void stopCapturingTelemetry()
void startCapturingTelemetry(const QString &videoFile, QSize size)