630 lines
17 KiB
C++
Executable File
630 lines
17 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Handle Audio/Video output for thp through libvlc
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
#include "thp_audio_video_widget.h"
|
|
#include "thp_audio_video_widget_p.h"
|
|
#include "ui_thp_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 <math.h>
|
|
#include <stdio.h>
|
|
|
|
#include <vlc/libvlc_version.h>
|
|
|
|
namespace THP
|
|
{
|
|
|
|
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("THP.AudioVideoWidget"))
|
|
{
|
|
init();
|
|
|
|
connect(ui->btnSlower, &QToolButton::clicked, this, &AudioVideoWidget::Private::onSlower);
|
|
connect(ui->btnFaster, &QToolButton::clicked, this, &AudioVideoWidget::Private::onFaster);
|
|
connect(ui->btn100pct, &QToolButton::clicked, this, &AudioVideoWidget::Private::on100pct);
|
|
connect(ui->btnPlay, &QToolButton::clicked, this, &AudioVideoWidget::Private::onPlay);
|
|
connect(ui->btnStop, &QToolButton::clicked, this, &AudioVideoWidget::Private::onStop);
|
|
connect(ui->sldPosition, &QSlider::sliderMoved, this, &AudioVideoWidget::Private::onPositionChanged);
|
|
connect(ui->sldVolume, &QSlider::sliderMoved, this, &AudioVideoWidget::Private::onVolumeChanged);
|
|
connect(m_timer, &QTimer::timeout, this, &AudioVideoWidget::Private::onUpdateGUI);
|
|
|
|
m_initThread = new AudioVideoInitThread(this);
|
|
connect(m_initThread, &AudioVideoInitThread::finished, this, &AudioVideoWidget::Private::onVLCInstanceInitializd);
|
|
m_initThread->start(QThread::LowPriority);
|
|
}
|
|
|
|
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->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() && path.endsWith(QLatin1String(".pls")))
|
|
{
|
|
// pls parsing scheint nicht mehr richtig zu funktionieren - selbst machen
|
|
DEBUG_LOG(m_logger) << "Parse Playlist";
|
|
QFile f(path);
|
|
if (f.open(QIODevice::ReadOnly))
|
|
{
|
|
DEBUG_LOG(m_logger) << "Parse Playlist2 " << f.canReadLine();
|
|
QMap<int, QByteArray> fileMap;
|
|
QByteArray baAll = f.readAll();
|
|
const QList<QByteArray> lines = baAll.split('\n');
|
|
for (const QByteArray &line : lines)
|
|
{
|
|
QByteArray ba = line.trimmed();
|
|
DEBUG_LOG(m_logger) << "ba: " << ba;
|
|
if (!ba.startsWith("File "))
|
|
continue;
|
|
ba = ba.mid(qstrlen("File "));
|
|
int idx = ba.indexOf('=');
|
|
DEBUG_LOG(m_logger) << "idx: " << idx;
|
|
if (idx < 0)
|
|
continue;
|
|
bool bOk;
|
|
int id = ba.left(idx).toInt(&bOk);
|
|
DEBUG_LOG(m_logger) << "id: " << id << " bOk: " << bOk << " str: " << ba.left(idx);
|
|
if (!bOk)
|
|
continue;
|
|
QByteArray filename = ba.mid(idx + 1);
|
|
DEBUG_LOG(m_logger) << "filename: " << filename;
|
|
fileMap.insertMulti(id, fi.absolutePath().toLocal8Bit() + '/' + filename);
|
|
}
|
|
for (const QByteArray &fn : fileMap)
|
|
{
|
|
const QByteArray pNative = QDir::toNativeSeparators(QString::fromLocal8Bit(fn)).toLocal8Bit();
|
|
DEBUG_LOG(m_logger) << "pNative: " << pNative;
|
|
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;
|
|
}
|
|
//add option to disable hardware acceleration
|
|
libvlc_media_add_option(media, ":avcodec-hw=none");
|
|
libvlc_media_list_add_media(m_mediaList, media);
|
|
#if LIBVLC_VERSION_MAJOR > 2
|
|
libvlc_media_parse_with_options(media, libvlc_media_parse_local, 0);
|
|
#else
|
|
libvlc_media_parse(media);
|
|
#endif
|
|
libvlc_media_release(media); // libvlc_media_new_location(), ref-counting!
|
|
}
|
|
}
|
|
}
|
|
else 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);
|
|
libvlc_media_release(media); // libvlc_media_new_location(), ref-counting!
|
|
}
|
|
else if (fi.isDir())
|
|
{
|
|
QDirIterator dirIt(fi.absoluteFilePath());
|
|
while (dirIt.hasNext())
|
|
{
|
|
const QString fn = dirIt.next();
|
|
fi.setFile(fn);
|
|
if (!fi.isFile())
|
|
continue;
|
|
const QByteArray pNative = QDir::toNativeSeparators(fn).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);
|
|
#if LIBVLC_VERSION_MAJOR > 2
|
|
libvlc_media_parse_with_options(media, libvlc_media_parse_local, 0);
|
|
#else
|
|
libvlc_media_parse(media);
|
|
#endif
|
|
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->setEnabled(false);
|
|
ui->btnStop->setEnabled(true);
|
|
|
|
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, &AudioVideoWidget::Private::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);
|
|
|
|
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::onPositionChanged(int newPosition)
|
|
{
|
|
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
|
|
libvlc_media_player_set_position(m_mPlayer, newPosition / 1000.);
|
|
onUpdateGUI();
|
|
}
|
|
|
|
void AudioVideoWidget::Private::onVolumeChanged(int newVol)
|
|
{
|
|
libvlc_audio_set_volume(m_mPlayer, newVol);
|
|
onUpdateGUI();
|
|
}
|
|
|
|
void AudioVideoWidget::Private::onUpdateGUI()
|
|
{
|
|
onUpdateGUIWithState(libvlc_NothingSpecial);
|
|
}
|
|
|
|
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));
|
|
|
|
const int minutesCur = floor(curTime / 60.);
|
|
const int secondsCur = curTime - 60 * minutesCur;
|
|
const int minutesAbs = floor(maxTime / 60.);
|
|
const int secondsAbs = maxTime - 60 * minutesAbs;
|
|
char timeStr[64];
|
|
snprintf(timeStr, sizeof(timeStr), "%02d:%02d / %02d:%02d", minutesCur, secondsCur, minutesAbs, secondsAbs);
|
|
ui->lblPosition->setText(QString::fromLatin1(timeStr));
|
|
|
|
}
|
|
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);
|
|
m_timer->stop();
|
|
ui->sldPosition->setValue(0);
|
|
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))
|
|
{}
|
|
|
|
AudioVideoWidget::~AudioVideoWidget()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
bool AudioVideoWidget::play(const QUrl &file)
|
|
{
|
|
d->initVLCPlayer();
|
|
return d->playVLC(file);
|
|
}
|
|
|
|
bool AudioVideoWidget::stop()
|
|
{
|
|
return d->stopVLC();
|
|
}
|
|
|
|
void AudioVideoWidget::setAV(bool isAudio)
|
|
{
|
|
d->setAV(isAudio);
|
|
}
|
|
|
|
} // namespace THP
|