Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Plugins/AudioVideoManagement/Gui/AVMenuEdit/topic_replay.cpp
T
torstenandCopilot b774f4035c Qt6 Migration: DDS-Stubs, Logger-Fixes, Export-Header Korrekturen
- NGL_ADD_LIBRARY2: 87 CMakeLists.txt konvertiert für Export-Header Generierung
- 44 Export-Header Include-Pfade korrigiert (_export.h)
- 81 DDS-Stub-Header generiert (*_dtc.h, *_fts.h, *_dts.h, *_ftc.h)
- INGLLogger: Duplikat gelöscht, m_logger Member entfernt, variadische Makros
- Q_FUNC_INFO Redefinition behoben (Qt6 definiert bereits)
- FATAL_LOG Makro hinzugefügt
- InfrastructureManagement DDS-Stubs (ism.hpp, ism_enums.hpp, ism_ftc.h)
- FilterManagement DDS-Stubs (flt_ftc.h, flt_dts.h)
- AreaEffectSimulation DDS-Stubs (aes.hpp, aes_enums.hpp)
- SymbolAppearance Klasse vollständig definiert mit content() Methode
- BuildingComponentFilter Klasse definiert mit Copy-Konstruktor
- Ftc Factory: nullptr Return (abstract class)
- AesFilter Klasse in aes.hpp hinzugefügt
- Dtc Klasse in ppm.hpp mit participantChanged Signal
- AesType Enum: alle 15 At* Werte definiert
- AesEffectState_def: EsReceived hinzugefügt
- DataModification Enum: eAdded/eModified/eRemoved
- function_reply_object.h → core_types.h Include-Pfad (72 Dateien)
- Enum-Class-Streaming Template-Operator in INGLLogger.h
- ism_mounting_point.h: QImage → QtGui/QImage, QGuiApplication/QScreen
- ism_data_plugin_interface.h: QSet Include, Include-Reihenfolge
- QRegExp → QRegularExpression in tpm_js_parser.cpp
- .underlying() Aufrufe zu direktem Enum-Vergleich korrigiert
- Include-Pfade: aes.hpp in symbol_appearance_settings_impl.h und aes_display_filter_impl.h

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-19 06:06:24 +02:00

465 lines
11 KiB
C++
Executable File

#include "topic_replay.h"
#include <AudioVideoManagement/ava_types.h>
#include <AudioVideoManagement/avm_data_plugin_interface.h>
#include <AudioVideoManagement/ava_control.h>
#include <AudioVideoManagement/ava_session.h>
#include <AudioVideoManagement/vd_control.h>
#include <AudioVideoManagement/vd_session.h>
#include <TopicEditorBase/topic_editor_base.h>
#include <LtsUtilsCore/json_object.h>
#include <nglsettings/nglsettings_settings.h>
#include <QWidget>
#include <QFileInfo>
#include <QJsonDocument>
#include <QDir>
#include <QtGlobal>
#include <QRect>
#include <QDebug>
#include <vector>
#include <chrono>
namespace AudioVideoManagement
{
class TopicReplay::ExportScript : public QObject
{
Q_OBJECT
public:
ExportScript(const QString &topLevelExportDir, TopicEditorBase::ExportNotifier *exportStep);
public slots:
void avScriptFinished(const QString &exportDir, AvaStreamType streamType, bool success);
private:
QString audioVideoPlaylistErstellen(const QString &dir, AvaStreamType streamType);
bool writeFile(const QByteArray &data, const QString &fileName);
QString m_topLevelExportDir;
TopicEditorBase::ExportNotifier *m_exportStep;
};
TopicReplay::TopicReplay(DataInterface *dataIfc, bool isAudio)
: m_isAudio(isAudio)
, m_dataIfc(dataIfc)
{
DEBUG_LOG() << "TopicReplay::TopicReplay()";
Q_ASSERT(dataIfc);
}
TopicReplay::~TopicReplay()
{
DEBUG_LOG() << "TopicReplay::~TopicReplay()";
if (m_isPlaying)
playbackStop();
}
QWidget *TopicReplay::createWidget()
{
DEBUG_LOG() << "TopicReplay::createWidget()";
Q_ASSERT(!m_screenPlacementHelper);
if (m_isAudio)
return nullptr;
m_screenPlacementHelper.reset(new ScreenPlacementHelper());
connect(m_screenPlacementHelper.data(), &ScreenPlacementHelper::widgetPlaced, this, &TopicReplay::onWidgetPlaced);
return m_screenPlacementHelper.data();
}
void TopicReplay::slotSetScriptResponse(const AudioVideoManagement::AvaStreamInfo &streamInfo, AudioVideoManagement::AvaStreamState streamState)
{
if (streamState == AudioVideoManagement::AvaStreamState::NotPossible)
ERROR_LOG() << "Script could not be set";
else
ERROR_LOG() << "Script set!";
ERROR_LOG() << "streamInfo: start" << streamInfo.duration.count();
ERROR_LOG() << "streamState: " << static_cast<int>(streamState);
}
bool TopicReplay::playbackInit(const QJsonObject &attributes)
{
DEBUG_LOG() << "TopicReplay::playbackInit()";
DEBUG_LOG() << QJsonDocument(attributes).toJson();
if (m_screenPlacementHelper && !m_isAudio)
m_screenPlacementHelper->show();
m_playbackAttributes = attributes;
AvaControl *ctrl = getAvaControl();
if (ctrl == nullptr)
{
ERROR_LOG() << "no ava control!";
return false;
}
AvaTopicData topicData(m_playbackAttributes);
if (!topicData.isValid)
{
ERROR_LOG() << "topicData is invalid";
return false;
}
m_scriptName = topicData.scriptName();
Q_ASSERT(topicData.isAudio() == m_isAudio);
PlaybackApp *app = m_isAudio ? m_dataIfc->audioPresentationApp() : m_dataIfc->videoPresentationApp();
if (app == nullptr || app->inUse())
{
ERROR_LOG() << "app invalid or in use!";
return false;
}
if (!m_dialogGeometry)
{
if (m_isAudio)
m_appHandle = PlaybackAppHandle(app);
else
m_appHandle = PlaybackAppHandle(app, QRect(0, 0, 0, 0));
}
else
m_appHandle = PlaybackAppHandle(app, *m_dialogGeometry);
if (!m_appHandle)
{
ERROR_LOG() << "appHandle: missing app after creating appHandle!";
return false;
}
NGL::Settings s({});
bool isLocal = s.isDatabaseConnectionLocal();
DEBUG_LOG() << "isLocal? " << isLocal;
AvaScriptSource source;
if (isLocal)
{
if (m_isAudio)
source = AvaScriptSource::LocalAudio;
else
source = AvaScriptSource::LocalVideo;
}
else
{
if (m_isAudio)
source = AvaScriptSource::ServerAudio;
else
source = AvaScriptSource::ServerVideo;
}
DEBUG_LOG() << "source: " << static_cast<int>(source);
ctrl->setScript(m_appHandle.dialogId(), m_scriptName,
source, topicData.streamList(),
LtsUtils::createConnection(ctrl, &AudioVideoManagement::AvaControl::setScriptResponse,
this, &TopicReplay::slotSetScriptResponse));
return true;
}
bool TopicReplay::playbackStart(int secondsOffset)
{
DEBUG_LOG() << "TopicReplay::playbackStart()";
if (m_screenPlacementHelper && !m_isAudio)
m_screenPlacementHelper->show();
AvaControl *ctrl = getAvaControl();
if (ctrl == nullptr)
{
ERROR_LOG() << "ctrl == nullptr";
return false;
}
AvaTimePoint p{AvaDuration{std::chrono::seconds(secondsOffset)}};
if (!m_appHandle)
{
ERROR_LOG() << "appHandle: missing app!";
return false;
}
ctrl->setAbsPositionScript(m_appHandle.dialogId(), m_scriptName, p);
ctrl->startScript(m_appHandle.dialogId(), m_scriptName);
m_isPlaying = true;
DEBUG_LOG() << "m_isPlaying = true";
return true;
}
bool TopicReplay::playbackPause()
{
DEBUG_LOG() << "TopicReplay::playbackPause()";
if (m_screenPlacementHelper)
m_screenPlacementHelper->hide();
if (!m_isPlaying)
return true;
AvaControl *ctrl = getAvaControl();
if (ctrl == nullptr)
{
ERROR_LOG() << "no ctrl!";
return false;
}
if (!m_appHandle)
{
ERROR_LOG() << "appHandle: missing app!";
return false;
}
ctrl->pauseScript(m_appHandle.dialogId(), m_scriptName);
return true;
}
bool TopicReplay::playbackStop()
{
DEBUG_LOG() << "TopicReplay::playbackStop()";
if (m_screenPlacementHelper)
m_screenPlacementHelper->hide();
if (!m_isPlaying)
return true;
AvaControl *ctrl = getAvaControl();
if (ctrl == nullptr)
{
ERROR_LOG() << "no ctrl!";
return false;
}
if (!m_appHandle)
{
ERROR_LOG() << "appHandle: missing app!";
return false;
}
ctrl->stopScript(m_appHandle.dialogId(), m_scriptName);
ctrl->releaseScript(m_appHandle.dialogId(), m_scriptName);
m_isPlaying = false;
return true;
}
bool TopicReplay::exportTopic(const QJsonObject &attributes,
const QString &folderPath,
TopicEditorBase::ExportNotifier *exportNotifier)
{
Q_ASSERT(!m_exportScript);
VdControl *ctrl = getVdControl();
if (ctrl == nullptr)
{
ERROR_LOG() << "ctrl missing!";
exportNotifier->setExportFailed();
return false;
}
m_exportScript.reset(new ExportScript(folderPath, exportNotifier));
AvaTopicData topicData(attributes);
m_scriptName = topicData.scriptName();
if (!topicData.isValid)
{
ERROR_LOG() << "topicData is invalid";
exportNotifier->setExportFailed();
return false;
}
QFileInfo fileInfo(QDir(folderPath).filePath(topicData.scriptName()));
Q_ASSERT(topicData.isAudio() == m_isAudio);
ctrl->vdSetScript(m_scriptName,
m_isAudio ? AvaStreamType::Audio : AvaStreamType::Video,
0, topicData.streamList(), fileInfo.baseName(), fileInfo.absolutePath(),
this, &TopicReplay::avScriptFinished);
return true;
}
void TopicReplay::onWidgetPlaced(const QRect &geometry)
{
WARNING_LOG() << "TopicReplay::onWidgetPlaced() - geo: " << geometry.x() << "/" << geometry.y()
<< " m_isAudio=" << m_isAudio;
m_dialogGeometry = geometry;
if (m_isAudio)
return;
PlaybackApp *app = m_isAudio ? m_dataIfc->audioPresentationApp() : m_dataIfc->videoPresentationApp();
if (app == nullptr)
{
ERROR_LOG() << "app missing!";
return;
}
if (!app->inUse())
{
ERROR_LOG() << "app not in use - waiting for playbackInit to aquire it";
return;
}
DEBUG_LOG() << "setGeometry";
app->setGeometry(*m_dialogGeometry);
}
AvaControl *TopicReplay::getAvaControl()
{
if (!m_dataIfc->hasAvsSession())
return nullptr;
AvaSession *avaSession = m_dataIfc->avaSession();
if (!avaSession->isEstablished())
return nullptr;
return avaSession->control();
}
VdControl *TopicReplay::getVdControl()
{
if (!m_dataIfc->hasAvsSession())
return nullptr;
VdSession *vdSession = m_dataIfc->vdSession();
if (!vdSession->isEstablished())
return nullptr;
return vdSession->control();
}
void TopicReplay::avScriptFinished(const QString &exportDir, AvaStreamType streamType, bool success)
{
VdControl *ctrl = getVdControl();
ctrl->vdReleaseScript(m_scriptName);
m_exportScript->avScriptFinished(exportDir, streamType, success);
}
TopicReplay::ExportScript::ExportScript(const QString &topLevelExportDir, TopicEditorBase::ExportNotifier *exportStep)
: m_topLevelExportDir(topLevelExportDir)
, m_exportStep(exportStep)
{
connect(exportStep, &QObject::destroyed, this, [this]()
{
if (static_cast<TopicEditorBase::ExportNotifier *>(sender()) != m_exportStep)
return;
m_exportStep = nullptr;
});
Q_ASSERT(exportStep);
}
void TopicReplay::ExportScript::avScriptFinished(const QString &exportDir, AvaStreamType streamType, bool success)
{
QString absPathToPlaylist = audioVideoPlaylistErstellen(exportDir, streamType);
QDir toplevelExportDir(m_topLevelExportDir);
QString relativePathToPlaylist = toplevelExportDir.relativeFilePath(absPathToPlaylist);
if (m_exportStep == nullptr)
return;
if (success)
m_exportStep->setExportSuccessful(relativePathToPlaylist);
else
m_exportStep->setExportFailed();
}
QString TopicReplay::ExportScript::audioVideoPlaylistErstellen(const QString &dir, AvaStreamType streamType)
{
QDir avDir(dir);
const QFileInfoList dateienList = avDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
QByteArray dataForFile;
QString data;
dataForFile.append("[playlist]\n");
int numberOfEntries = 0;
int i = 1;
const QString tmpl1(QStringLiteral("File %1=%2\n"));
const QString tmpl2(QStringLiteral("# File %1=%2\n"));
for (const QFileInfo &fileInfo : dateienList)
{
if (streamType == AvaStreamType::Video && fileInfo.suffix() == QLatin1String(".wav"))
{
data += tmpl2.arg(QString::number(i), fileInfo.fileName());
i--;
}
else
{
data += tmpl1.arg(QString::number(i), fileInfo.fileName());
numberOfEntries++;
}
i++;
}
QString numberOfEntriesString = QStringLiteral("NumberOfEntries=") + QString::number(numberOfEntries) + QStringLiteral("\n");
dataForFile.append(numberOfEntriesString.toUtf8());
dataForFile.append(data.toUtf8());
QString fileName;
switch (streamType)
{
case AvaStreamType::Audio:
fileName = avDir.filePath(QStringLiteral("audio.pls"));
break;
case AvaStreamType::Video:
fileName = avDir.filePath(QStringLiteral("video.pls"));
break;
}
writeFile(dataForFile, fileName);
return fileName;
}
bool TopicReplay::ExportScript::writeFile(const QByteArray &data, const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return false;
if (file.write(data) == -1)
{
file.close();
return false;
}
file.close();
return true;
}
}
#include "topic_replay.moc"