Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+52
View File
@@ -0,0 +1,52 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# CMakeLists.txt fuer VideoImport
#
SET(videoimport_SRCS
mainwindow.cpp
audio_video_widget.cpp
main.cpp
)
SET(videoimport_HDRS
mainwindow.h
audio_video_widget.h
audio_video_widget_p.h
)
NGL_WRAP_UI(videoimport_SRCS ui/mainwindow.ui ui/audio_video_widget.ui)
NGL_ADD_EXECUTABLE(WS videoimport ${videoimport_SRCS} ${videoimport_HDRS})
NGL_TARGET_INCLUDE_DIRECTORIES(videoimport
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
PRIVATE
${VLC_INCLUDE_DIR}
)
NGL_TARGET_COMPILE_DEFINITIONS(videoimport
PRIVATE
${VLC_DEFINES}
)
NGL_TARGET_LINK_LIBRARIES(videoimport
PUBLIC
${VLC_LIBRARIES}
NGLLogger
LtsWidgets
Qt5::Core
Qt5::Widgets
LtsPluginLoader
StylePluginInterface
LtsCommandLineParser
nglapplication
)
NGL_INSTALL_TARGET(videoimport)
+670
View File
@@ -0,0 +1,670 @@
/**
* @RDE_HEADER@
* Handle Audio/Video output for thp through libvlc
* $Id$
* $HeadURL$
* $Author$
*/
#include "audio_video_widget.h"
#include "audio_video_widget_p.h"
#include "ui_audio_video_widget.h"
#include <QCoreApplication>
#include <QDirIterator>
#include <QFileInfo>
#include <QMutex>
#include <QScreen>
#include <QTimer>
#include <QUrl>
#include <QGuiApplication>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <LtsWidgets/lts_range_slider.h>
#include <QFileDialog>
#include <QProcess>
#include <math.h>
#include <stdio.h>
#include <vlc/libvlc_version.h>
namespace VideoImport
{
static const float s_speedArray[] =
{
1. / 8.,
1. / 4.,
1. / 2.,
1.,
2.,
4.,
8.
};
/**
* AudioVideoWidget::Private
*/
AudioVideoWidget::Private::Private(QFrame *parent)
: m_vlcinstance(nullptr)
, m_mPlayer(nullptr)
, m_mListPlayer(nullptr)
, m_mediaList(nullptr)
, currentSpeedIdx(3)
, m_parent(parent)
, m_timer(new QTimer)
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("VideoImport.AudioVideoWidget"))
{
init();
connect(ui->btnSlower, &QToolButton::clicked, this, &Private::onSlower);
connect(ui->btnFaster, &QToolButton::clicked, this, &Private::onFaster);
connect(ui->btn100pct, &QToolButton::clicked, this, &Private::on100pct);
connect(ui->btnPlay, &QToolButton::clicked, this, &Private::onPlay);
connect(ui->btnStop, &QToolButton::clicked, this, &Private::onStop);
connect(ui->btnCut, &QPushButton::clicked, this, &Private::onCut);
connect(ui->sldPosition, &QSlider::valueChanged, this, &Private::onPositionChanged);
connect(ui->sldRange, &LtsWidgets::LtsRangeSlider::maximumValueChanged, this, &Private::onRangeMaximumChanged);
connect(ui->sldRange, &LtsWidgets::LtsRangeSlider::minimumValueChanged, this, &Private::onRangeMinimumChanged);
// connect(ui->sldPosition, &LtsWidgets::LtsRangeSlider::minimumValueChanged, this, &AudioVideoWidget::Private::onPositionChanged);
connect(ui->sldVolume, &QSlider::sliderMoved, this, &Private::onVolumeChanged);
connect(m_timer, &QTimer::timeout, this, &Private::onUpdateGUI);
m_initThread = new AudioVideoInitThread(this);
connect(m_initThread, &AudioVideoInitThread::finished, this, &Private::onVLCInstanceInitializd);
m_initThread->start(QThread::LowPriority);
ui->sldRange->setEnabled(false);
ui->sldPosition->setEnabled(false);
}
AudioVideoWidget::Private::~Private()
{
uninitVLCPlayer();
uninitVLCInstance();
delete ui;
delete m_timer;
}
bool AudioVideoWidget::Private::init()
{
if (!m_parent)
return false;
ui = new Ui::audioVideoWidget();
ui->setupUi(m_parent);
QPixmap pm(10, 10);
pm.fill(Qt::black);
ui->outputWidget->setPixmap(pm);
ui->outputWidget->setScaledContents(true);
ui->sldRange->setMaximum(1000);
ui->sldRange->setMaximumValue(1000);
ui->sldPosition->setMaximum(1000);
ui->sldVolume->setMaximum(100);
return true;
}
void AudioVideoWidget::Private::onVLCInstanceInitializd()
{
m_initThread->deleteLater();
m_initThread = nullptr;
}
void AudioVideoWidget::Private::setAV(bool isAudio)
{
if (isAudio)
{
delete ui->btn100pct;
delete ui->btnFaster;
delete ui->btnSlower;
delete ui->outputWidget;
ui->outputWidget = nullptr;
}
else
{
// delete ui->verticalSpacer; ui->verticalSpacer = 0;
delete ui->lblAudio;
}
}
static QMutex *serializeVLCInit()
{
static QMutex s_serializeVLCInit;
return &s_serializeVLCInit;
}
bool AudioVideoWidget::Private::initVLCInstance(bool bInInitThread)
{
QMutexLocker l(serializeVLCInit());
if (!bInInitThread && m_initThread != nullptr)
{
QLabel myLabel;
myLabel.setWindowTitle(tr("Loading VLC player..."));
myLabel.setText(tr("Waiting until VLC player is loaded"));
QRect r = QGuiApplication::primaryScreen()->availableGeometry();
myLabel.show();
myLabel.move(r.width() / 2 - myLabel.width() / 2, r.height() / 2 - myLabel.height() / 2);
myLabel.setWindowIcon(QIcon(QLatin1String(":icons/16x16/rde.ico")));
while (m_initThread)
QCoreApplication::processEvents();
}
if (m_vlcinstance != nullptr)
return true;
//preparation of the vlc command
const char *vlc_argv[20];
int iCount = 0;
vlc_argv[iCount++] = "-I";
vlc_argv[iCount++] = "dummy"; // Don't use any interface
// vlc_argv[iCount++] = "--ignore-config"; // Don't use VLC's config
#ifdef LTS_DEBUG
vlc_argv[iCount++] = "--extraintf=logger"; // log anything
vlc_argv[iCount++] = "--verbose=2"; // be much more verbose then normal for debugging purpose
#else
vlc_argv[iCount++] = "--quiet";
#endif
if (bInInitThread)
vlc_argv[iCount++] = "--no-media-library";
vlc_argv[iCount++] = "--";
vlc_argv[iCount] = nullptr;
//Initialize an instance of vlc
//create a new libvlc instance
m_vlcinstance = libvlc_new(iCount, vlc_argv); //tricky calculation of the char space used
if (!m_vlcinstance)
ERROR_LOG(m_logger) << "Error initializing libVLC - unable to play audio or video";
return (m_vlcinstance != nullptr);
}
bool AudioVideoWidget::Private::uninitVLCInstance()
{
QMutexLocker l(serializeVLCInit());
if (!uninitVLCPlayer())
return false;
if (m_vlcinstance)
{
libvlc_release(m_vlcinstance);
m_vlcinstance = nullptr;
}
return true;
}
bool AudioVideoWidget::Private::initVLCPlayer()
{
DEBUG_LOG(m_logger) << "Initializing libVLC";
if (m_mPlayer)
{
if (!ui)
return false;
ui->sldVolume->setValue(libvlc_audio_get_volume(m_mPlayer));
return true;
}
initVLCInstance();
//Initialize an instance of vlc
//Create a media player playing environement
m_mPlayer = libvlc_media_player_new(m_vlcinstance);
m_mListPlayer = libvlc_media_list_player_new(m_vlcinstance);
m_mediaList = libvlc_media_list_new(m_vlcinstance);
libvlc_media_list_player_set_media_player(m_mListPlayer, m_mPlayer);
libvlc_media_list_player_set_media_list(m_mListPlayer, m_mediaList);
ui->sldVolume->setValue(libvlc_audio_get_volume(m_mPlayer));
return true;
}
bool AudioVideoWidget::Private::uninitVLCPlayer()
{
DEBUG_LOG(m_logger) << "Uninitializing libVLC";
if (m_mListPlayer)
{
/* Stop playing */
libvlc_media_list_player_stop(m_mListPlayer);
/* Free the media_player */
libvlc_media_list_player_release(m_mListPlayer);
m_mListPlayer = nullptr;
}
if (m_mediaList)
{
clearMediaList();
libvlc_media_list_release(m_mediaList);
m_mediaList = nullptr;
}
if (m_mPlayer)
{
/* Stop playing */
libvlc_media_player_stop(m_mPlayer);
/* Free the media_player */
libvlc_media_player_release(m_mPlayer);
m_mPlayer = nullptr;
}
return true;
}
void AudioVideoWidget::Private::clearMediaList()
{
DEBUG_LOG(m_logger) << "Clearing current playlist";
if (!m_mediaList)
return;
libvlc_media_list_lock(m_mediaList);
const int cnt = libvlc_media_list_count(m_mediaList);
for (int i = cnt - 1; i >= 0; --i)
libvlc_media_list_remove_index(m_mediaList, i);
libvlc_media_list_unlock(m_mediaList);
}
bool AudioVideoWidget::Private::playVLC(const QUrl &url)
{
if (!ui)
return false;
DEBUG_LOG(m_logger) << "Try to play " << url.toString();
const QString path = url.toLocalFile();
if (path.isEmpty())
return false;
clearMediaList();
libvlc_media_list_lock(m_mediaList);
QFileInfo fi(path);
DEBUG_LOG(m_logger) << "path: " << path << " isFile: " << fi.isFile();
if (fi.isFile())
{
const QByteArray pNative = QDir::toNativeSeparators(path).toLocal8Bit();
libvlc_media_t *media = libvlc_media_new_path(m_vlcinstance, pNative.data());
if (!media)
{
ERROR_LOG(m_logger) << "Error setting media to '" << pNative << "'";
return false;
}
libvlc_media_list_add_media(m_mediaList, media);
// Todo: streams is always 0, although media was parsed. Why?
// If frames can be obtained: Both sliders should be as large as number of frames.
// libvlc_media_parse(media);
// if (libvlc_media_is_parsed(media))
// {
// libvlc_media_track_t **tracks;
// double framerate = 1;
// unsigned streams = libvlc_media_tracks_get(media, &tracks);
// for (unsigned i = 0; i < streams; ++i)
// {
// libvlc_video_track_t *video = tracks[i]->video;
// if (video)
// framerate = 1. * video->i_frame_rate_num / video->i_frame_rate_den;
// }
// libvlc_media_tracks_release(tracks, streams);
// m_frames = floor(1000. * libvlc_media_get_duration(media) * framerate);
// }
// else {
// m_frames = 1000;
// }
libvlc_media_release(media); // libvlc_media_new_location(), ref-counting!
}
else
{
ERROR_LOG(m_logger) << "Unknown media given: " << path;
libvlc_media_list_unlock(m_mediaList);
return false;
}
libvlc_media_list_unlock(m_mediaList);
if (ui->outputWidget)
{
#if defined(Q_OS_WIN)
libvlc_media_player_set_hwnd(m_mPlayer, (HWND)ui->outputWidget->winId());
#elif defined(Q_OS_MAC)
libvlc_media_player_set_agl(m_mPlayer, ui->outputWidget->winId()) ;
#else //Linux
libvlc_media_player_set_xwindow(m_mPlayer, ui->outputWidget->winId());
#endif
}
ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-start.png")));
ui->btnPlay->setEnabled(true);
// ui->sldPosition->setMaximum(m_frames);
ui->sldPosition->setEnabled(false);
// ui->sldRange->setMaximum(m_frames);
ui->sldRange->setEnabled(false);
ui->btnStop->setEnabled(true);
onRangeMaximumChanged(0); // Initialize Min/Max
currentSpeedIdx = 3;
QTimer::singleShot(0, this, &AudioVideoWidget::Private::onPlay);
return true;
}
bool AudioVideoWidget::Private::stopVLC()
{
DEBUG_LOG(m_logger) << "Stop playing";
QTimer::singleShot(0, this, SLOT(onStop()));
return true;
}
void AudioVideoWidget::Private::setRate()
{
DEBUG_LOG(m_logger) << "Setting speed to " << s_speedArray[currentSpeedIdx];
libvlc_state_t state = getState();
if (state == libvlc_Playing || state == libvlc_Paused)
libvlc_media_player_set_rate(m_mPlayer, s_speedArray[currentSpeedIdx]);
}
libvlc_state_t AudioVideoWidget::Private::getState() const
{
libvlc_state_t s = libvlc_media_list_player_get_state(m_mListPlayer);
static libvlc_state_t lastState = libvlc_NothingSpecial;
if (s == lastState)
return s;
lastState = s;
if (s == libvlc_Error)
ERROR_LOG(m_logger) << "libVLC error: " << libvlc_errmsg();
return s;
}
void AudioVideoWidget::Private::onSlower()
{
if (currentSpeedIdx == 0)
return;
--currentSpeedIdx;
setRate();
onUpdateGUI();
}
void AudioVideoWidget::Private::onFaster()
{
if (currentSpeedIdx == 6)
return;
++currentSpeedIdx;
setRate();
onUpdateGUI();
}
void AudioVideoWidget::Private::on100pct()
{
currentSpeedIdx = 3;
setRate();
onUpdateGUI();
}
void AudioVideoWidget::Private::onPlay()
{
if (libvlc_media_list_player_is_playing(m_mListPlayer))
{
DEBUG_LOG(m_logger) << "Pause playing";
libvlc_media_list_player_pause(m_mListPlayer);
ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-start.png")));
m_timer->stop();
onUpdateGUIWithState(libvlc_Paused);
}
else
{
DEBUG_LOG(m_logger) << "Start playing";
ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-pause.png")));
ui->sldPosition->setEnabled(true);
ui->sldRange->setEnabled(true);
libvlc_media_list_player_play(m_mListPlayer);
setRate();
m_timer->start(100);
onUpdateGUIWithState(libvlc_Playing);
}
}
void AudioVideoWidget::Private::onStop()
{
if (!m_mListPlayer)
return;
libvlc_state_t state = getState();
if (state == libvlc_Stopped)
return;
DEBUG_LOG(m_logger) << "Stop playing";
libvlc_media_list_player_stop(m_mListPlayer);
onUpdateGUI();
}
void AudioVideoWidget::Private::onCut()
{
double maxTimeSecs = libvlc_media_player_get_length(m_mPlayer) / 1000.;
double minimumRelative = ui->sldRange->minimumValue() / 1000.;
double maximumRelative = ui->sldRange->maximumValue() / 1000.;
QString inTime = timeString(maxTimeSecs * minimumRelative, true);
QString duration = timeString(maxTimeSecs * (maximumRelative - minimumRelative), true);
emit signalCut(inTime, duration);
}
void AudioVideoWidget::Private::onPositionChanged(int newPosition)
{
if (newPosition < ui->sldRange->minimumPosition())
{
ui->sldPosition->setValue(ui->sldRange->minimumValue());
return;
}
if (newPosition > ui->sldRange->maximumPosition())
{
ui->sldPosition->setValue(ui->sldRange->maximumValue());
return;
}
libvlc_state_t state = getState();
DEBUG_LOG(m_logger) << "Slider changed - going to new position";
if (state != libvlc_Playing && state != libvlc_Paused)
return;
// Position geht von 0..1, Slider hat 1000 Steps
// Todo: if slider is different than 1000 steps, correct here:
libvlc_media_player_set_position(m_mPlayer, newPosition / 1000.);
onUpdateGUI();
}
void AudioVideoWidget::Private::onRangeMinimumChanged(int newMinimum)
{
if (ui->sldPosition->value() < newMinimum)
ui->sldPosition->setValue(newMinimum);
double maxTimeSecs = libvlc_media_player_get_length(m_mPlayer) / 1000.;
double minimumRelative = newMinimum / 1000.;
double maximumRelative = ui->sldRange->maximumValue() / 1000.;
ui->lblMinMax->setText(timeString(maxTimeSecs * minimumRelative) + QLatin1Literal(" / ") + timeString(maxTimeSecs * maximumRelative));
}
void AudioVideoWidget::Private::onRangeMaximumChanged(int newMaximum)
{
if (ui->sldPosition->value() > newMaximum)
ui->sldPosition->setValue(newMaximum);
double maxTimeSecs = libvlc_media_player_get_length(m_mPlayer) / 1000.;
double minimumRelative = ui->sldRange->minimumValue() / 1000.;
double maximumRelative = newMaximum / 1000.;
ui->lblMinMax->setText(timeString(maxTimeSecs * minimumRelative) + QLatin1Literal(" / ") + timeString(maxTimeSecs * maximumRelative));
}
void AudioVideoWidget::Private::onVolumeChanged(int newVol)
{
libvlc_audio_set_volume(m_mPlayer, newVol);
onUpdateGUI();
}
void AudioVideoWidget::Private::onUpdateGUI()
{
onUpdateGUIWithState(libvlc_NothingSpecial);
}
QString AudioVideoWidget::Private::timeString(double curTime, bool exact)
{
const int minutesCur = floor(curTime / 60.);
const int secondsCur = curTime - 60 * minutesCur;
const int millies = floor((curTime - floor(curTime)) * 1000);
char timeStr[32];
if (exact)
snprintf(timeStr, sizeof(timeStr), "%02d:%02d.%03d", minutesCur, secondsCur, millies);
else
snprintf(timeStr, sizeof(timeStr), "%02d:%02d", minutesCur, secondsCur);
return QString::fromLatin1(timeStr);
}
void AudioVideoWidget::Private::onUpdateGUIWithState(libvlc_state_t overwrite_state)
{
libvlc_state_t state = overwrite_state;
if (state == libvlc_NothingSpecial)
state = getState();
DEBUG_LOG(m_logger) << "onUpdateGUI for state " << state;
if (state == libvlc_Playing || state == libvlc_Paused)
{
double maxTime = libvlc_media_player_get_length(m_mPlayer) / 1000.;
if (maxTime > 0.1)
{
libvlc_media_list_lock(m_mediaList);
const int cnt = libvlc_media_list_count(m_mediaList);
for (int i = cnt - 1; i >= 0; --i)
{
libvlc_media_t *media = libvlc_media_list_item_at_index(m_mediaList, i);
DEBUG_LOG(m_logger) << "Duration: " << libvlc_media_get_duration(media);
libvlc_media_release(media);
}
libvlc_media_list_unlock(m_mediaList);
}
double curTime = libvlc_media_player_get_time(m_mPlayer) / 1000.;
auto curPos = libvlc_media_player_get_position(m_mPlayer);
// Slider ist in 1000 Schritte eingeteilt
ui->sldPosition->setValue(qRound(curPos * 1000));
ui->lblPosition->setText(timeString(curTime) + QLatin1Literal(" / ") + timeString(maxTime));
if (state == libvlc_Playing && ui->sldPosition->value() >= ui->sldRange->maximumValue())
onPlay(); // -> Pause
}
else if (state == libvlc_Stopped || state == libvlc_Ended)
{
// wir können nicht onStop() aufrufen -> rekursion!
bool bStop = true;
if (state == libvlc_Ended)
{
// Timer und VLC *nicht* stoppen da der aktuelle State ggf. genau zwischen den einzelnen
// Video-Schnipseln einer Playlist abgefragt wurde
// --> prüfen, ob es das letzte Video der Playlist war
libvlc_media_t *media = libvlc_media_player_get_media(m_mPlayer);
if (media != nullptr)
{
const int cnt = libvlc_media_list_count(m_mediaList);
if (cnt > 0)
{
libvlc_media_t *media2 = libvlc_media_list_item_at_index(m_mediaList, cnt - 1);
bStop = (media2 == media);
libvlc_media_release(media2);
}
libvlc_media_release(media);
}
if (bStop)
libvlc_media_list_player_stop(m_mListPlayer);
}
if (bStop)
{
ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-start.png")));
ui->sldPosition->setEnabled(false);
ui->sldRange->setEnabled(false);
m_timer->stop();
ui->sldPosition->setValue(ui->sldRange->minimumValue());
ui->lblPosition->setText(QLatin1String("--:-- / --:--"));
}
}
QString speedStr = QStringLiteral("%1x").arg(s_speedArray[currentSpeedIdx], 4, 'f', 2);
ui->lblSpeed->setText(speedStr);
}
/**
* AudioVideoInitThread
*/
AudioVideoInitThread::AudioVideoInitThread(AudioVideoWidget::Private *p)
: m_private(p)
{}
void AudioVideoInitThread::run()
{
m_private->initVLCInstance(true);
}
/**
* AudioVideoWidget
*/
AudioVideoWidget::AudioVideoWidget(QWidget *parent)
: QFrame(parent)
, d(new Private(this))
{
connect(d, &AudioVideoWidget::Private::signalCut, this, &AudioVideoWidget::onCut);
}
void AudioVideoWidget::onCut(const QString &inTime, const QString &duration)
{
const QString localFile = m_url.toLocalFile();
QString extension = localFile.mid(localFile.lastIndexOf(QLatin1Char('.')) + 1);
QUrl outUrl = QFileDialog::getSaveFileUrl(this, tr("Save Video File"), QUrl(), tr("Source File Format (*.%1)").arg(extension));
// ffmpeg -ss [inTime] -t [outTime] -i [m_url] [url]
QString command = tr("ffmpeg -i \"%3\" -ss %1 -t %2 -acodec copy -vcodec copy \"%4\"").arg(inTime, duration, m_url.toLocalFile(), outUrl.toLocalFile());
QProcess::startDetached(command);
}
AudioVideoWidget::~AudioVideoWidget()
{
delete d;
}
bool AudioVideoWidget::play(const QUrl &file)
{
d->initVLCPlayer();
setEnabled(true);
return d->playVLC(file);
}
bool AudioVideoWidget::stop()
{
return d->stopVLC();
}
void AudioVideoWidget::setAV(bool isAudio)
{
d->setAV(isAudio);
}
void AudioVideoWidget::onOpenFile()
{
QString folder = QString::fromLatin1(qgetenv("USER"));
if (folder.isEmpty())
folder = QString::fromLatin1(qgetenv("USERNAME"));
folder.prepend(QLatin1String("/run/media/"));
m_url = QFileDialog::getOpenFileUrl(this, tr("Open Video File"), QUrl::fromLocalFile(folder), tr("Video files (*.*)"));
play(m_url);
}
} // namespace VideoImport
+38
View File
@@ -0,0 +1,38 @@
/**
* @RDE_HEADER@
* Handle Audio/Video output for thp through libvlc
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QFrame>
#include <QUrl>
namespace VideoImport
{
class AudioVideoWidget : public QFrame
{
Q_OBJECT
public:
explicit AudioVideoWidget(QWidget *parent = nullptr);
~AudioVideoWidget();
bool play(const QUrl &file);
bool stop();
void setAV(bool isAudio = false);
protected slots:
void onCut(const QString &inTime, const QString &duration);
public slots:
void onOpenFile();
private:
class Private;
Private *const d;
friend class AudioVideoInitThread;
QUrl m_url;
};
} // namespace VideoImport
+102
View File
@@ -0,0 +1,102 @@
/**
* @RDE_HEADER@
* Handle Audio/Video output for video import through libvlc, private data
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#ifdef _MSC_VER
// no ssize_t with msdn...
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif
#include <vlc/vlc.h>
#include <QObject>
#include <QThread>
#include <NGLLogger/INGLLogger.h>
#include "audio_video_widget.h"
class QUrl;
class QFrame;
class QTimer;
namespace Ui
{
class audioVideoWidget;
}
namespace VideoImport
{
class AudioVideoInitThread;
class AudioVideoWidget::Private : public QObject
{
Q_OBJECT
public:
explicit Private(QFrame *parent);
~Private();
bool initVLCInstance(bool bInInitThread = false);
bool uninitVLCInstance();
bool initVLCPlayer();
bool uninitVLCPlayer();
bool playVLC(const QUrl &url);
bool stopVLC();
void setAV(bool isAudio);
protected Q_SLOTS:
void onSlower();
void onFaster();
void on100pct();
void onPlay();
void onStop();
void onCut();
void onPositionChanged(int);
void onVolumeChanged(int);
void onUpdateGUI();
void onVLCInstanceInitializd();
void onRangeMinimumChanged(int);
void onRangeMaximumChanged(int);
signals:
void signalCut(const QString &inTime, const QString &outTime);
protected:
void clearMediaList();
void playVLCInternal();
void onUpdateGUIWithState(libvlc_state_t overwrite_state);
QString timeString(double curTime, bool exact = false);
bool init();
void setRate();
libvlc_state_t getState() const;
libvlc_instance_t *m_vlcinstance;
libvlc_media_player_t *m_mPlayer;
libvlc_media_list_player_t *m_mListPlayer;
libvlc_media_list_t *m_mediaList;
int currentSpeedIdx;
QFrame *m_parent;
QTimer *m_timer;
int m_frames;
AudioVideoInitThread *m_initThread;
Ui::audioVideoWidget *ui;
NGL::INGLLogger &m_logger;
};
class AudioVideoInitThread final : public QThread
{
Q_OBJECT
public:
explicit AudioVideoInitThread(AudioVideoWidget::Private *p);
protected:
void run() override;
protected:
AudioVideoWidget::Private *m_private;
};
} // namespace VideoImport
+88
View File
@@ -0,0 +1,88 @@
/**
* @RDE_HEADER@
* DDS View -> The "LogView" for DDS
* $Id$
* $HeadURL$
* $Author$
*/
// #include "nglsettings.h"
#include "mainwindow.h"
#include <LtsCommandLineParser/LtsCommandLineParser.h>
#include <NGLLogger/INGLLogger.h>
//#include <nglsettings/nglsettings_settings.h>
#include <nglapplication/nglapplication.h>
#include <LtsPluginManager/lts_plugin_loader.h>
#include <PluginInterfaces/style_plugin_interface.h>
//#include <QtCore/QSettings>
//#include <QInputDialog>
//#include <QUrl>
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
{
public:
CmdLineParser() : LtsCommandLineParser::LtsCommandLineParser(ProvideCommandLineParameterOptions(LtsCommandLineParser::CreateDomainIdFromIp |
LtsCommandLineParser::DomainId |
LtsCommandLineParser::ExerciseId |
LtsCommandLineParser::TcpConnectionUrl))
{}
const char *langCode() const { return m_langCode.data(); }
bool init()
{
setDomainId(-1);
QCommandLineOption langCodeOption(QStringList() << QLatin1String("l") << QLatin1String("langCode"),
QLatin1String("Language."),
QLatin1String("en_US|de_DE"),
QLatin1String("en_US"));
addOption(langCodeOption);
if (!LtsCommandLineParser::init())
return false;
if (isSet(langCodeOption))
m_langCode = value(langCodeOption).toLatin1();
return true;
}
private:
QByteArray m_langCode;
};
int main(int argc, char *argv[])
{
NGLApplication app(argc, argv);
app.createLogger("VideoImporter", "log4cxx_videoimporter.props");
NGL::INGLLogger &logger = app.baseLogger();
QCoreApplication::setApplicationName(QLatin1String("Video Importer"));
QCoreApplication::setOrganizationName(QLatin1String("RDE"));
LtsPluginManager::LtsPluginLoader::getInstance()->loadPlugins(LtsPluginManager::PluginType::STYLE, nullptr
, QStringList() << QStringLiteral("rme.light")); // load style plugin
CmdLineParser options;
if (!options.init())
return -1;
// NGL::Settings settings(app.organizationName(), app.applicationName());
STARTUP_LOG(logger);
// NGL::init_translator(options.langCode());
MainWindow *mw = new MainWindow();
mw->show();
app.setQuitOnLastWindowClosed(true);
int retval = app.exec();
SHUTDOWN_LOG(logger);
return retval;
}
+21
View File
@@ -0,0 +1,21 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "audio_video_widget.h"
MainWindow::MainWindow(QWidget *parent)
: QWidget(parent)
, m_ui(new Ui::MainWindow)
, m_avw(new VideoImport::AudioVideoWidget(this))
{
m_ui->setupUi(this);
m_ui->gridLayout->replaceWidget(m_ui->mainFrame, m_avw);
m_ui->mainFrame->hide();
m_ui->mainFrame->deleteLater();
m_avw->setEnabled(false);
connect(m_ui->pbOpen, &QPushButton::clicked, m_avw, &VideoImport::AudioVideoWidget::onOpenFile);
}
MainWindow::~MainWindow()
{
delete m_ui;
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include <QWidget>
namespace Ui {
class MainWindow;
}
namespace VideoImport {
class AudioVideoWidget;
}
class MainWindow : public QWidget
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *m_ui;
VideoImport::AudioVideoWidget *m_avw;
};
+274
View File
@@ -0,0 +1,274 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>audioVideoWidget</class>
<widget class="QFrame" name="audioVideoWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>929</width>
<height>578</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">Form</string>
</property>
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="outputWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="LtsWidgets::LtsRangeSlider" name="sldRange">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="sldPosition">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="lblAudio">
<property name="text">
<string>Audio</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="lblPosition">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">55:55 / 55:55</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="lblMinMax">
<property name="text">
<string>00:00 / 99:99</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QToolButton" name="btnPlay">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset>
<normaloff>:icons/16x16/media-playback-start.png</normaloff>:icons/16x16/media-playback-start.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnStop">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset>
<normaloff>:icons/16x16/media-playback-stop.png</normaloff>:icons/16x16/media-playback-stop.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnSlower">
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset>
<normaloff>:icons/16x16/media-play-slower.png</normaloff>:icons/16x16/media-play-slower.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btn100pct">
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset>
<normaloff>:icons/16x16/media-play-normal.png</normaloff>:icons/16x16/media-play-normal.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnFaster">
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset>
<normaloff>:icons/16x16/media-play-faster.png</normaloff>:icons/16x16/media-play-faster.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lblSpeed">
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string notr="true">100 %</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnCut">
<property name="text">
<string>CUT</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Volume:</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="sldVolume">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>60</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsRangeSlider</class>
<extends>QSlider</extends>
<header>LtsWidgets/lts_range_slider.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QWidget" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="pbOpen">
<property name="text">
<string>Open File</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QFrame" name="mainFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>