summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AnyRip.pro18
-rw-r--r--dvdimagejob.cpp15
-rw-r--r--dvdimagejob.h6
-rw-r--r--dvdimagejobgui.cpp (renamed from imagegui.cpp)25
-rw-r--r--dvdimagejobgui.h24
-rw-r--r--encodemp4job.cpp23
-rw-r--r--encodemp4job.h21
-rw-r--r--imagegui.h25
-rw-r--r--job.h3
-rw-r--r--jobqueue.cpp31
-rw-r--r--jobqueue.h23
-rw-r--r--main.cpp3
-rw-r--r--titleloadjob.cpp23
-rw-r--r--titleloadjob.h21
-rw-r--r--uploadjob.cpp22
-rw-r--r--uploadjob.h20
-rw-r--r--video.cpp107
-rw-r--r--video.h31
-rw-r--r--videoqueue.cpp32
-rw-r--r--videoqueue.h22
20 files changed, 408 insertions, 87 deletions
diff --git a/AnyRip.pro b/AnyRip.pro
index a84415f..db8f7a5 100644
--- a/AnyRip.pro
+++ b/AnyRip.pro
@@ -1,14 +1,24 @@
SOURCES += main.cpp \
dvdimagejob.cpp \
- imagegui.cpp \
+ dvdimagejobgui.cpp \
job.cpp \
video.cpp \
- dvddrive.cpp
+ dvddrive.cpp \
+ jobqueue.cpp \
+ videoqueue.cpp \
+ encodemp4job.cpp \
+ uploadjob.cpp \
+ titleloadjob.cpp
HEADERS += dvdimagejob.h \
- imagegui.h \
+ dvdimagejobgui.h \
job.h \
video.h \
- dvddrive.h
+ dvddrive.h \
+ jobqueue.h \
+ videoqueue.h \
+ encodemp4job.h \
+ uploadjob.h \
+ titleloadjob.h
LIBS += -ldvdcss \
-ldvdread
QT += dbus
diff --git a/dvdimagejob.cpp b/dvdimagejob.cpp
index 98fe537..54e82ca 100644
--- a/dvdimagejob.cpp
+++ b/dvdimagejob.cpp
@@ -1,5 +1,6 @@
#include "dvdimagejob.h"
#include "dvddrive.h"
+#include "dvdimagejobgui.h"
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
@@ -10,9 +11,10 @@
#include <QIODevice>
#include <QFile>
-DVDImageJob::DVDImageJob(Video *video, DVDDrive *dvdDrive)
+DVDImageJob::DVDImageJob(Video *video, QString defaultPath)
: Job(video),
- m_dvdDrive(dvdDrive)
+ m_dvdDrive(new DVDDrive(this)), //TODO: get from static singleton instance
+ m_defaultPath(defaultPath)
{
}
@@ -30,10 +32,10 @@ int DVDImageJob::cmpvob(const void *p1, const void *p2)
bool DVDImageJob::executeJob()
{
- return saveImageToPath(QLatin1String("image.iso")); //Fix up
+ return saveImageToPath(m_defaultPath);
}
-Video::Jobs DVDImageJob::jobType()
+Video::Jobs DVDImageJob::jobType() const
{
return Video::DVDImage;
}
@@ -197,3 +199,8 @@ bool DVDImageJob::saveImageToDevice(QIODevice &out)
qDebug() << "Success:" << blkno << "blocks copied (" << (long long)blkno * DVDCSS_BLOCK_SIZE << ") of" << discend << "expected";
return true;
}
+
+QWidget* DVDImageJob::gui()
+{
+ return new DVDImageJobGui(this);
+}
diff --git a/dvdimagejob.h b/dvdimagejob.h
index 4a99f16..d70d414 100644
--- a/dvdimagejob.h
+++ b/dvdimagejob.h
@@ -9,10 +9,11 @@ class DVDImageJob : public Job
{
Q_OBJECT
public:
- DVDImageJob(Video *video, DVDDrive *dvdDrive);
+ DVDImageJob(Video *video, QString defaultPath);
bool saveImageToDevice(QIODevice &out);
bool saveImageToPath(const QString &path);
- Video::Jobs jobType();
+ Video::Jobs jobType() const;
+ QWidget* gui();
private:
static int cmpvob(const void *p1, const void *p2);
@@ -20,6 +21,7 @@ private:
int32_t start, end;
} vobfile;
DVDDrive *m_dvdDrive;
+ QString m_defaultPath;
protected:
bool executeJob();
diff --git a/imagegui.cpp b/dvdimagejobgui.cpp
index 52c5790..7db1dd6 100644
--- a/imagegui.cpp
+++ b/dvdimagejobgui.cpp
@@ -1,4 +1,4 @@
-#include "imagegui.h"
+#include "dvdimagejobgui.h"
#include "dvdimagejob.h"
#include "dvddrive.h"
#include <dvdcss/dvdcss.h>
@@ -6,28 +6,13 @@
#include <QProgressBar>
#include <QVBoxLayout>
#include <QFile>
-#include <QtConcurrentRun>
-ImageGui::ImageGui()
+DVDImageJobGui::DVDImageJobGui(DVDImageJob *job) :
+ m_first(true)
{
- m_dvdDrive = new DVDDrive(this);
- if (m_dvdDrive->dvdInserted()) {
- startImaging();
- } else {
- setWindowTitle(tr("Please insert DVD..."));
- connect(m_dvdDrive, SIGNAL(dvdAdded()), this, SLOT(startImaging()));
- }
-}
-void ImageGui::startImaging()
-{
- setWindowTitle(tr("Starting imaging..."));
- Video *video = new Video(m_dvdDrive);
- Job *job = video->nextJob();
- m_first = true;
connect(job, SIGNAL(extractProgress(int,int)), this, SLOT(extractProgress(int,int)));
- job->runJob();
}
-void ImageGui::extractProgress(int current, int maximum)
+void DVDImageJobGui::extractProgress(int current, int maximum)
{
if (m_first) {
m_startTime.start();
@@ -37,7 +22,7 @@ void ImageGui::extractProgress(int current, int maximum)
long long maximumBytes = (long long)maximum * DVDCSS_BLOCK_SIZE;
double bytesPerMillisecond = (double)currentBytes / (double)m_startTime.elapsed();
long long millisecondsRemaining = (long long)((maximumBytes - currentBytes) / bytesPerMillisecond);
- setWindowTitle(QString("AnyRip: %1 of %2 megabytes (%3 mb/s, %4 remaining)")
+ setWindowTitle(QString("%1 of %2 megabytes (%3 mb/s, %4 remaining)")
.arg(QString::number((double)currentBytes / 1024.0 / 1024.0, 'f', 2))
.arg(QString::number((double)maximumBytes / 1024.0 / 1024.0, 'f', 2))
.arg(QString::number(bytesPerMillisecond * (1000.0 / 1024.0 / 1024.0), 'f', 2))
diff --git a/dvdimagejobgui.h b/dvdimagejobgui.h
new file mode 100644
index 0000000..27aafe5
--- /dev/null
+++ b/dvdimagejobgui.h
@@ -0,0 +1,24 @@
+#ifndef DVDIMAGEJOBGUI_H
+#define DVDIMAGEJOBGUI_H
+
+#include <QProgressBar>
+#include <QTime>
+class DVDImageJob;
+
+class DVDImageJobGui : public QProgressBar
+{
+ Q_OBJECT
+
+public:
+ DVDImageJobGui(DVDImageJob *job);
+
+private:
+ QTime m_startTime;
+ bool m_first;
+ DVDImageJob *m_job;
+
+private slots:
+ void extractProgress(int current, int maximum);
+};
+
+#endif // DVDIMAGEJOBGUI_H
diff --git a/encodemp4job.cpp b/encodemp4job.cpp
new file mode 100644
index 0000000..84408d3
--- /dev/null
+++ b/encodemp4job.cpp
@@ -0,0 +1,23 @@
+#include "encodemp4job.h"
+#include <QWidget>
+
+EncodeMP4Job::EncodeMP4Job(Video *video, QString encodePath, QString imagePath) :
+ Job(video),
+ m_encodePath(encodePath),
+ m_imagePath(imagePath)
+{
+}
+Video::Jobs EncodeMP4Job::jobType() const
+{
+ return Video::EncodeMP4;
+}
+bool EncodeMP4Job::executeJob()
+{
+ //TODO: encode the actual mp4!
+ return true;
+}
+QWidget* EncodeMP4Job::gui()
+{
+ //TODO: make a gui
+ return new QWidget;
+}
diff --git a/encodemp4job.h b/encodemp4job.h
new file mode 100644
index 0000000..58ecd51
--- /dev/null
+++ b/encodemp4job.h
@@ -0,0 +1,21 @@
+#ifndef ENCODEMP4JOB_H
+#define ENCODEMP4JOB_H
+
+#include "job.h"
+#include "video.h"
+
+class EncodeMP4Job : public Job
+{
+ Q_OBJECT
+public:
+ EncodeMP4Job(Video *video, QString encodePath, QString imagePath);
+ Video::Jobs jobType() const;
+ QWidget* gui();
+protected:
+ bool executeJob();
+private:
+ QString m_encodePath;
+ QString m_imagePath;
+};
+
+#endif // ENCODEMP4JOB_H
diff --git a/imagegui.h b/imagegui.h
deleted file mode 100644
index ddd731e..0000000
--- a/imagegui.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef IMAGEGUI_H
-#define IMAGEGUI_H
-
-#include <QProgressBar>
-#include <QTime>
-class DVDDrive;
-
-class ImageGui : public QProgressBar
-{
- Q_OBJECT
-
-public:
- ImageGui();
-
-private:
- QTime m_startTime;
- bool m_first;
- DVDDrive *m_dvdDrive;
-
-private slots:
- void extractProgress(int current, int maximum);
- void startImaging();
-};
-
-#endif // IMAGEGUI_H
diff --git a/job.h b/job.h
index c0b1750..7717143 100644
--- a/job.h
+++ b/job.h
@@ -10,7 +10,8 @@ class Job : public QObject
Q_OBJECT
public:
void runJob();
- virtual Video::Jobs jobType() = 0;
+ virtual Video::Jobs jobType() const = 0;
+ virtual QWidget* gui() = 0;
protected:
Job(QObject *parent = 0);
virtual bool executeJob() = 0;
diff --git a/jobqueue.cpp b/jobqueue.cpp
new file mode 100644
index 0000000..c18ffee
--- /dev/null
+++ b/jobqueue.cpp
@@ -0,0 +1,31 @@
+#include "jobqueue.h"
+#include "job.h"
+
+#include <QDebug>
+
+JobQueue::JobQueue(QObject *parent) :
+ QObject(parent),
+ m_jobIsRunning(false)
+{
+}
+void JobQueue::addJob(Job *job)
+{
+ m_queue.enqueue(job);
+ if (!m_jobIsRunning)
+ runNextJob();
+}
+void JobQueue::runNextJob()
+{
+ if (m_queue.isEmpty())
+ return;
+ m_jobIsRunning = true;
+ Job *job = m_queue.dequeue();
+ qDebug() << "running job" << job->jobType() << "for video" << qobject_cast<Video*>(job->parent())->title();
+ connect(job, SIGNAL(completed(bool)), this, SLOT(jobCompleted()));
+ job->runJob();
+}
+void JobQueue::jobCompleted()
+{
+ m_jobIsRunning = false;
+ runNextJob();
+}
diff --git a/jobqueue.h b/jobqueue.h
new file mode 100644
index 0000000..09fa73f
--- /dev/null
+++ b/jobqueue.h
@@ -0,0 +1,23 @@
+#ifndef JOBQUEUE_H
+#define JOBQUEUE_H
+
+#include <QObject>
+#include <QQueue>
+class Job;
+
+class JobQueue : public QObject
+{
+ Q_OBJECT
+
+public:
+ JobQueue(QObject *parent = 0);
+ void addJob(Job *job);
+private:
+ QQueue<Job*> m_queue;
+ bool m_jobIsRunning;
+ void runNextJob();
+private slots:
+ void jobCompleted();
+};
+
+#endif // JOBQUEUE_H
diff --git a/main.cpp b/main.cpp
index 9e8963d..ef28e50 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,4 +1,3 @@
-#include "imagegui.h"
#include "dvddrive.h"
#include <QApplication>
@@ -11,7 +10,5 @@ int main(int argc, char *argv[])
a.setApplicationName(QLatin1String("AnyRip"));
a.setOrganizationName(QLatin1String("AnyClip"));
a.setOrganizationDomain(QLatin1String("anyclip.com"));
- ImageGui i;
- i.show();
return a.exec();
}
diff --git a/titleloadjob.cpp b/titleloadjob.cpp
new file mode 100644
index 0000000..f54c9b2
--- /dev/null
+++ b/titleloadjob.cpp
@@ -0,0 +1,23 @@
+#include "titleloadjob.h"
+#include <QWidget>
+
+TitleLoadJob::TitleLoadJob(Video *video, QString subtitlePath, QString posterPath) :
+ Job(video),
+ m_subtitlePath(subtitlePath),
+ m_posterPath(posterPath)
+{
+}
+Video::Jobs TitleLoadJob::jobType() const
+{
+ return Video::TitleLoad;
+}
+bool TitleLoadJob::executeJob()
+{
+ //TODO: title load the whole thing
+ return true;
+}
+QWidget* TitleLoadJob::gui()
+{
+ //TODO: make a gui
+ return new QWidget;
+}
diff --git a/titleloadjob.h b/titleloadjob.h
new file mode 100644
index 0000000..d4ff9ab
--- /dev/null
+++ b/titleloadjob.h
@@ -0,0 +1,21 @@
+#ifndef TITLELOADJOB_H
+#define TITLELOADJOB_H
+
+#include "job.h"
+#include "video.h"
+
+class TitleLoadJob : public Job
+{
+ Q_OBJECT
+public:
+ TitleLoadJob(Video *video, QString subtitlePath, QString posterPath);
+ Video::Jobs jobType() const;
+ QWidget* gui();
+protected:
+ bool executeJob();
+private:
+ QString m_subtitlePath;
+ QString m_posterPath;
+};
+
+#endif // TITLELOADJOB_H
diff --git a/uploadjob.cpp b/uploadjob.cpp
new file mode 100644
index 0000000..776db6b
--- /dev/null
+++ b/uploadjob.cpp
@@ -0,0 +1,22 @@
+#include "uploadjob.h"
+#include <QWidget>
+
+UploadJob::UploadJob(Video *video, QString encodePath) :
+ Job(video),
+ m_encodePath(encodePath)
+{
+}
+Video::Jobs UploadJob::jobType() const
+{
+ return Video::Upload;
+}
+bool UploadJob::executeJob()
+{
+ //TODO: upload the mp4!
+ return true;
+}
+QWidget* UploadJob::gui()
+{
+ //TODO: make a gui
+ return new QWidget;
+}
diff --git a/uploadjob.h b/uploadjob.h
new file mode 100644
index 0000000..ff77e6b
--- /dev/null
+++ b/uploadjob.h
@@ -0,0 +1,20 @@
+#ifndef UPLOADJOB_H
+#define UPLOADJOB_H
+
+#include "job.h"
+#include "video.h"
+
+class UploadJob : public Job
+{
+ Q_OBJECT
+public:
+ UploadJob(Video *video, QString encodePath);
+ Video::Jobs jobType() const;
+ QWidget* gui();
+protected:
+ bool executeJob();
+private:
+ QString m_encodePath;
+};
+
+#endif // UPLOADJOB_H
diff --git a/video.cpp b/video.cpp
index 9a8527e..a4240b9 100644
--- a/video.cpp
+++ b/video.cpp
@@ -1,41 +1,104 @@
#include "video.h"
#include "job.h"
#include "dvdimagejob.h"
-#include "dvddrive.h"
+#include "encodemp4job.h"
+#include "uploadjob.h"
+#include "titleloadjob.h"
-Video::Video(DVDDrive *dvdDrive) :
- m_jobsCompleted(QBitArray(5)),
- m_dvdDrive(dvdDrive)
+#include <QDir>
+
+Video::Video(QString title, QObject *parent) :
+ QObject(parent),
+ m_jobsCompleted(QBitArray(6)),
+ m_jobsInProgress(QBitArray(6))
{
- m_title = dvdDrive->dvdName();
+ m_title = title;
+ m_rootPath = QString("%1/AnyRip/%2").arg(QDir::homePath()).arg(m_title);
+ m_imagePath = QString("%1/%2 - Image.iso").arg(m_rootPath).arg(m_title);
+ m_encodePath = QString("%1/%2 - Encode.mp4").arg(m_rootPath).arg(m_title);
+ m_subtitlePath = QString("%1/%2 - Subtitles.srt").arg(m_rootPath).arg(m_title);
+ m_posterPath = QString("%1/%2 - Poster.jpg").arg(m_rootPath).arg(m_title);
}
void Video::completedJob(bool success)
{
Job *job = qobject_cast<Job*>(sender());
qDebug() << "Job code" << job->jobType() << "completed" << success;
m_jobsCompleted.setBit(job->jobType(), success);
+ m_jobsInProgress.setBit(job->jobType(), false);
+ emit jobCompleted(job->jobType(), success);
delete job;
-
- if (success) {
- //queue next job function
- ;
- } else {
- //failure mechanism
- ;
+}
+DVDImageJob* Video::dvdImageJob()
+{
+ if (!m_jobsInProgress.at(Video::DVDImage) && !m_jobsCompleted.at(Video::DVDImage)) {
+ DVDImageJob *job = new DVDImageJob(this, m_imagePath);
+ connect(job, SIGNAL(completed(bool)), this, SLOT(completedJob(bool)));
+ m_jobsInProgress.setBit(Video::DVDImage, true);
+ return job;
}
+ return 0;
}
-Job* Video::nextJob()
+EncodeMP4Job* Video::encodeMP4Job()
{
- Job *job;
- if (!m_jobsCompleted.at(Video::DVDImage)) {
- job = new DVDImageJob(this, m_dvdDrive);
- } else {
- job = 0; //Other jobs...
+ if (!m_jobsInProgress.at(Video::EncodeMP4) && !m_jobsCompleted.at(Video::EncodeMP4) && m_jobsCompleted.at(Video::DVDImage)) {
+ EncodeMP4Job *job = new EncodeMP4Job(this, m_encodePath, m_imagePath);
+ connect(job, SIGNAL(completed(bool)), this, SLOT(completedJob(bool)));
+ m_jobsInProgress.setBit(Video::EncodeMP4, true);
+ return job;
+ }
+ return 0;
+}
+UploadJob* Video::uploadJob()
+{
+ if (!m_jobsInProgress.at(Video::Upload) && !m_jobsCompleted.at(Video::Upload) && m_jobsCompleted.at(Video::EncodeMP4)) {
+ UploadJob *job = new UploadJob(this, m_encodePath);
+ connect(job, SIGNAL(completed(bool)), this, SLOT(completedJob(bool)));
+ m_jobsInProgress.setBit(Video::Upload, true);
+ return job;
+ }
+ return 0;
+}
+TitleLoadJob* Video::titleLoadJob()
+{
+ if (!m_jobsInProgress.at(Video::TitleLoad) && !m_jobsCompleted.at(Video::TitleLoad) && m_jobsCompleted.at(Video::Upload) && m_jobsCompleted.at(Video::Subtitle) && m_jobsCompleted.at(Video::Poster)) {
+ TitleLoadJob *job = new TitleLoadJob(this, m_subtitlePath, m_posterPath);
+ connect(job, SIGNAL(completed(bool)), this, SLOT(completedJob(bool)));
+ m_jobsInProgress.setBit(Video::TitleLoad, true);
+ return job;
}
- connect(job, SIGNAL(completed(bool)), this, SLOT(completedJob(bool)));
- return job;
+ return 0;
+}
+QList<Job*> Video::availableJobs()
+{
+ QList<Job*> jobs;
+ Job *job;
+ if ((job = dvdImageJob()))
+ jobs.append(job);
+ if ((job = encodeMP4Job()))
+ jobs.append(job);
+ if ((job = uploadJob()))
+ jobs.append(job);
+ if ((job = titleLoadJob()))
+ jobs.append(job);
+ return jobs;
+}
+void Video::setSubtitle(const QIODevice &input)
+{
+ m_jobsInProgress.setBit(Video::Subtitle, true);
+ //TODO: save input to subtitle file
+ m_jobsCompleted.setBit(Video::Subtitle, true);
+ m_jobsInProgress.setBit(Video::Subtitle, false);
+ emit jobCompleted(Video::Subtitle, true);
+}
+void Video::setPoster(const QIODevice &input)
+{
+ m_jobsInProgress.setBit(Video::Poster, true);
+ //TODO: save input to subtitle file
+ m_jobsCompleted.setBit(Video::Poster, true);
+ m_jobsInProgress.setBit(Video::Poster, false);
+ emit jobCompleted(Video::Poster, true);
}
-bool Video::isJobComplete(Jobs job) const
+QString Video::title() const
{
- return m_jobsCompleted.at(job);
+ return m_title;
}
diff --git a/video.h b/video.h
index 4efee93..0defb42 100644
--- a/video.h
+++ b/video.h
@@ -3,23 +3,42 @@
#include <QObject>
#include <QBitArray>
+#include <QList>
+class QIODevice;
+class DVDImageJob;
+class EncodeMP4Job;
+class UploadJob;
+class TitleLoadJob;
class Job;
-class DVDDrive;
+
class Video : public QObject
{
Q_OBJECT
public:
- Video(DVDDrive *dvdDrive);
- enum Jobs { DVDImage, EncodeMP4, Upload, Subtitle, Poster };
- Job* nextJob();
- bool isJobComplete(Jobs job) const;
+ Video(QString title, QObject *parent = 0);
+ enum Jobs { DVDImage, EncodeMP4, Upload, TitleLoad, Subtitle, Poster };
+ void setSubtitle(const QIODevice &input);
+ void setPoster(const QIODevice &input);
+ DVDImageJob* dvdImageJob();
+ EncodeMP4Job* encodeMP4Job();
+ UploadJob* uploadJob();
+ TitleLoadJob* titleLoadJob();
+ QList<Job*> availableJobs();
+ QString title() const;
private:
QBitArray m_jobsCompleted;
+ QBitArray m_jobsInProgress;
QString m_title;
- DVDDrive *m_dvdDrive;
+ QString m_rootPath;
+ QString m_imagePath;
+ QString m_encodePath;
+ QString m_subtitlePath;
+ QString m_posterPath;
private slots:
void completedJob(bool success);
+signals:
+ void jobCompleted(Video::Jobs job, bool success);
};
#endif // VIDEO_H
diff --git a/videoqueue.cpp b/videoqueue.cpp
new file mode 100644
index 0000000..f7a5991
--- /dev/null
+++ b/videoqueue.cpp
@@ -0,0 +1,32 @@
+#include "videoqueue.h"
+#include "video.h"
+#include "jobqueue.h"
+#include "job.h"
+
+#include <QDebug>
+
+VideoQueue::VideoQueue(QObject *parent) :
+ QObject(parent),
+ m_jobQueues(QVector<JobQueue*>(4))
+{
+ m_jobQueues.insert(Video::DVDImage, new JobQueue(this));
+ m_jobQueues.insert(Video::EncodeMP4, new JobQueue(this));
+ m_jobQueues.insert(Video::Upload, new JobQueue(this));
+ m_jobQueues.insert(Video::TitleLoad, new JobQueue(this));
+}
+void VideoQueue::newVideo(Video *video)
+{
+ connect(video, SIGNAL(jobCompleted(Video::Jobs,bool)), this, SLOT(videoChanged()));
+ enqueueVideo(video);
+}
+void VideoQueue::enqueueVideo(Video *video)
+{
+ foreach(Job *job, video->availableJobs()) {
+ qDebug() << "enqueueing job type" << job->jobType() << "for video" << video->title();
+ m_jobQueues.at(job->jobType())->addJob(job);
+ }
+}
+void VideoQueue::videoChanged()
+{
+ enqueueVideo(qobject_cast<Video*>(sender()));
+}
diff --git a/videoqueue.h b/videoqueue.h
new file mode 100644
index 0000000..a587c23
--- /dev/null
+++ b/videoqueue.h
@@ -0,0 +1,22 @@
+#ifndef VIDEOQUEUE_H
+#define VIDEOQUEUE_H
+
+#include <QObject>
+#include <QVector>
+class JobQueue;
+class Video;
+
+class VideoQueue : public QObject
+{
+ Q_OBJECT
+public:
+ VideoQueue(QObject *parent = 0);
+ void newVideo(Video *video);
+private:
+ QVector<JobQueue*> m_jobQueues;
+ void enqueueVideo(Video *video);
+private slots:
+ void videoChanged();
+};
+
+#endif // VIDEOQUEUE_H