Transcoder now accepts URLs for sources.
This commit is contained in:
parent
245f64a882
commit
bb618efc5d
@ -74,8 +74,8 @@ void Organise::Start() {
|
||||
|
||||
thread_ = new QThread;
|
||||
connect(thread_, SIGNAL(started()), SLOT(ProcessSomeFiles()));
|
||||
connect(transcoder_, SIGNAL(JobComplete(QString, QString, bool)),
|
||||
SLOT(FileTranscoded(QString, QString, bool)));
|
||||
connect(transcoder_, SIGNAL(JobComplete(QUrl, QString, bool)),
|
||||
SLOT(FileTranscoded(QUrl, QString, bool)));
|
||||
|
||||
moveToThread(thread_);
|
||||
thread_->start();
|
||||
@ -177,7 +177,7 @@ void Organise::ProcessSomeFiles() {
|
||||
// Start the transcoding - this will happen in the background and
|
||||
// FileTranscoded() will get called when it's done. At that point the
|
||||
// task will get re-added to the pending queue with the new filename.
|
||||
transcoder_->AddJob(task.song_info_.song_.url().toLocalFile(), preset,
|
||||
transcoder_->AddJob(task.song_info_.song_.url(), preset,
|
||||
task.transcoded_filename_);
|
||||
transcoder_->Start();
|
||||
continue;
|
||||
@ -262,11 +262,12 @@ void Organise::UpdateProgress() {
|
||||
const int total = task_count_ * 100;
|
||||
|
||||
// Update transcoding progress
|
||||
QMap<QString, float> transcode_progress = transcoder_->GetProgress();
|
||||
for (const QString& filename : transcode_progress.keys()) {
|
||||
QMap<QUrl, float> transcode_progress = transcoder_->GetProgress();
|
||||
for (const QUrl& fileurl : transcode_progress.keys()) {
|
||||
QString filename = fileurl.toLocalFile();
|
||||
if (!tasks_transcoding_.contains(filename)) continue;
|
||||
tasks_transcoding_[filename].transcode_progress_ =
|
||||
transcode_progress[filename];
|
||||
transcode_progress[fileurl];
|
||||
}
|
||||
|
||||
// Count the progress of all tasks that are in the queue. Files that need
|
||||
@ -287,14 +288,17 @@ void Organise::UpdateProgress() {
|
||||
task_manager_->SetTaskProgress(task_id_, progress, total);
|
||||
}
|
||||
|
||||
void Organise::FileTranscoded(const QString& input, const QString& output,
|
||||
void Organise::FileTranscoded(const QUrl& input, const QString& output,
|
||||
bool success) {
|
||||
qLog(Info) << "File finished" << input << success;
|
||||
Q_ASSERT(input.isLocalFile()); // organise only handles local files
|
||||
QString input_file_path = input.toLocalFile();
|
||||
|
||||
qLog(Info) << "File finished" << input_file_path << success;
|
||||
transcode_progress_timer_.stop();
|
||||
|
||||
Task task = tasks_transcoding_.take(input);
|
||||
Task task = tasks_transcoding_.take(input_file_path);
|
||||
if (!success) {
|
||||
files_with_errors_ << input;
|
||||
files_with_errors_ << input_file_path;
|
||||
} else {
|
||||
tasks_pending_ << task;
|
||||
}
|
||||
|
@ -67,8 +67,7 @@ class Organise : public QObject {
|
||||
|
||||
private slots:
|
||||
void ProcessSomeFiles();
|
||||
void FileTranscoded(const QString& input, const QString& output,
|
||||
bool success);
|
||||
void FileTranscoded(const QUrl& input, const QString& output, bool success);
|
||||
|
||||
private:
|
||||
void SetSongProgress(float progress, bool transcoded = false);
|
||||
|
@ -53,16 +53,16 @@ SongSender::SongSender(Application* app, RemoteClient* client)
|
||||
}
|
||||
qLog(Debug) << "Transcoder preset" << transcoder_preset_.codec_mimetype_;
|
||||
|
||||
connect(transcoder_, SIGNAL(JobComplete(QString, QString, bool)),
|
||||
SLOT(TranscodeJobComplete(QString, QString, bool)));
|
||||
connect(transcoder_, SIGNAL(JobComplete(QUrl, QString, bool)),
|
||||
SLOT(TranscodeJobComplete(QUrl, QString, bool)));
|
||||
connect(transcoder_, SIGNAL(AllJobsComplete()), SLOT(StartTransfer()));
|
||||
|
||||
total_transcode_ = 0;
|
||||
}
|
||||
|
||||
SongSender::~SongSender() {
|
||||
disconnect(transcoder_, SIGNAL(JobComplete(QString, QString, bool)), this,
|
||||
SLOT(TranscodeJobComplete(QString, QString, bool)));
|
||||
disconnect(transcoder_, SIGNAL(JobComplete(QUrl, QString, bool)), this,
|
||||
SLOT(TranscodeJobComplete(QUrl, QString, bool)));
|
||||
disconnect(transcoder_, SIGNAL(AllJobsComplete()), this,
|
||||
SLOT(StartTransfer()));
|
||||
transcoder_->Cancel();
|
||||
@ -110,11 +110,11 @@ void SongSender::TranscodeLosslessFiles() {
|
||||
if (!item.song_.IsFileLossless()) continue;
|
||||
|
||||
// Add the file to the transcoder
|
||||
QString local_file = item.song_.url().toLocalFile();
|
||||
QUrl local_file = item.song_.url();
|
||||
|
||||
transcoder_->AddTemporaryJob(local_file, transcoder_preset_);
|
||||
|
||||
qLog(Debug) << "transcoding" << local_file;
|
||||
qLog(Debug) << "transcoding" << local_file.toLocalFile();
|
||||
total_transcode_++;
|
||||
}
|
||||
|
||||
@ -126,13 +126,14 @@ void SongSender::TranscodeLosslessFiles() {
|
||||
}
|
||||
}
|
||||
|
||||
void SongSender::TranscodeJobComplete(const QString& input,
|
||||
const QString& output, bool success) {
|
||||
qLog(Debug) << input << "transcoded to" << output << success;
|
||||
void SongSender::TranscodeJobComplete(const QUrl& input, const QString& output,
|
||||
bool success) {
|
||||
Q_ASSERT(input.isLocalFile()); // songsender only handles local files
|
||||
qLog(Debug) << input.toLocalFile() << "transcoded to" << output << success;
|
||||
|
||||
// If it wasn't successful send original file
|
||||
if (success) {
|
||||
transcoder_map_.insert(input, output);
|
||||
transcoder_map_.insert(input.toLocalFile(), output);
|
||||
}
|
||||
|
||||
SendTranscoderStatus();
|
||||
|
@ -34,7 +34,7 @@ class SongSender : public QObject {
|
||||
void ResponseSongOffer(bool accepted);
|
||||
|
||||
private slots:
|
||||
void TranscodeJobComplete(const QString& input, const QString& output,
|
||||
void TranscodeJobComplete(const QUrl& input, const QString& output,
|
||||
bool success);
|
||||
void StartTransfer();
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <QFile>
|
||||
#include <QMutexLocker>
|
||||
#include <QUrl>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include "core/closure.h"
|
||||
@ -47,8 +48,8 @@ Ripper::Ripper(CdIo_t* cdio, QObject* parent)
|
||||
finished_failed_(0),
|
||||
files_tagged_(0) {
|
||||
Q_ASSERT(cdio_); // TODO: error handling
|
||||
connect(transcoder_, SIGNAL(JobComplete(QString, QString, bool)),
|
||||
SLOT(TranscodingJobComplete(QString, QString, bool)));
|
||||
connect(transcoder_, SIGNAL(JobComplete(QUrl, QString, bool)),
|
||||
SLOT(TranscodingJobComplete(QUrl, QString, bool)));
|
||||
connect(transcoder_, SIGNAL(AllJobsComplete()),
|
||||
SLOT(AllTranscodingJobsComplete()));
|
||||
connect(transcoder_, SIGNAL(LogLine(QString)), SLOT(LogLine(QString)));
|
||||
@ -111,7 +112,7 @@ void Ripper::Cancel() {
|
||||
emit Cancelled();
|
||||
}
|
||||
|
||||
void Ripper::TranscodingJobComplete(const QString& input, const QString& output,
|
||||
void Ripper::TranscodingJobComplete(const QUrl& input, const QString& output,
|
||||
bool success) {
|
||||
if (success)
|
||||
finished_success_++;
|
||||
@ -125,7 +126,8 @@ void Ripper::TranscodingJobComplete(const QString& input, const QString& output,
|
||||
// file later on.
|
||||
for (QList<TrackInformation>::iterator it = tracks_.begin();
|
||||
it != tracks_.end(); ++it) {
|
||||
if (it->temporary_filename == input) {
|
||||
Q_ASSERT(input.isLocalFile());
|
||||
if (it->temporary_filename == input.toLocalFile()) {
|
||||
it->transcoded_filename = output;
|
||||
}
|
||||
}
|
||||
@ -232,7 +234,7 @@ void Ripper::Rip() {
|
||||
UpdateProgress();
|
||||
|
||||
it->temporary_filename = filename;
|
||||
transcoder_->AddJob(it->temporary_filename, it->preset,
|
||||
transcoder_->AddJob(QUrl::fromLocalFile(it->temporary_filename), it->preset,
|
||||
it->transcoded_filename, it->overwrite_existing);
|
||||
}
|
||||
transcoder_->Start();
|
||||
@ -249,7 +251,7 @@ void Ripper::SetupProgressInterval() {
|
||||
|
||||
void Ripper::UpdateProgress() {
|
||||
int progress = (finished_success_ + finished_failed_) * 100;
|
||||
QMap<QString, float> current_jobs = transcoder_->GetProgress();
|
||||
QMap<QUrl, float> current_jobs = transcoder_->GetProgress();
|
||||
for (float value : current_jobs.values()) {
|
||||
progress += qBound(0, static_cast<int>(value * 100), 99);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ class Ripper : public QObject {
|
||||
void Cancel();
|
||||
|
||||
private slots:
|
||||
void TranscodingJobComplete(const QString& input, const QString& output,
|
||||
void TranscodingJobComplete(const QUrl& input, const QString& output,
|
||||
bool success);
|
||||
void AllTranscodingJobsComplete();
|
||||
void LogLine(const QString& message);
|
||||
|
@ -121,8 +121,8 @@ TranscodeDialog::TranscodeDialog(QWidget* parent)
|
||||
connect(ui_->options, SIGNAL(clicked()), SLOT(Options()));
|
||||
connect(ui_->select, SIGNAL(clicked()), SLOT(AddDestination()));
|
||||
|
||||
connect(transcoder_, SIGNAL(JobComplete(QString, QString, bool)),
|
||||
SLOT(JobComplete(QString, QString, bool)));
|
||||
connect(transcoder_, SIGNAL(JobComplete(QUrl, QString, bool)),
|
||||
SLOT(JobComplete(QUrl, QString, bool)));
|
||||
connect(transcoder_, SIGNAL(LogLine(QString)), SLOT(LogLine(QString)));
|
||||
connect(transcoder_, SIGNAL(AllJobsComplete()), SLOT(AllJobsComplete()));
|
||||
}
|
||||
@ -162,7 +162,8 @@ void TranscodeDialog::Start() {
|
||||
QFileInfo input_fileinfo(
|
||||
file_model->index(i, 0).data(Qt::UserRole).toString());
|
||||
QString output_filename = GetOutputFileName(input_fileinfo, preset);
|
||||
transcoder_->AddJob(input_fileinfo.filePath(), preset, output_filename);
|
||||
transcoder_->AddJob(QUrl::fromLocalFile(input_fileinfo.filePath()), preset,
|
||||
output_filename);
|
||||
}
|
||||
|
||||
// Set up the progressbar
|
||||
@ -195,7 +196,7 @@ void TranscodeDialog::PipelineDumpAction(bool checked) {
|
||||
}
|
||||
}
|
||||
|
||||
void TranscodeDialog::JobComplete(const QString& input, const QString& output,
|
||||
void TranscodeDialog::JobComplete(const QUrl& input, const QString& output,
|
||||
bool success) {
|
||||
if (success)
|
||||
finished_success_++;
|
||||
@ -210,7 +211,7 @@ void TranscodeDialog::JobComplete(const QString& input, const QString& output,
|
||||
void TranscodeDialog::UpdateProgress() {
|
||||
int progress = (finished_success_ + finished_failed_) * 100;
|
||||
|
||||
QMap<QString, float> current_jobs = transcoder_->GetProgress();
|
||||
QMap<QUrl, float> current_jobs = transcoder_->GetProgress();
|
||||
for (float value : current_jobs.values()) {
|
||||
progress += qBound(0, int(value * 100), 99);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class TranscodeDialog : public QDialog {
|
||||
void Remove();
|
||||
void Start();
|
||||
void Cancel();
|
||||
void JobComplete(const QString& input, const QString& output, bool success);
|
||||
void JobComplete(const QUrl& input, const QString& output, bool success);
|
||||
void LogLine(const QString& message);
|
||||
void AllJobsComplete();
|
||||
void Options();
|
||||
|
@ -32,6 +32,11 @@
|
||||
|
||||
using std::shared_ptr;
|
||||
|
||||
static QString UrlToLocalFileIfPossible(QUrl url) {
|
||||
if (url.isLocalFile()) return url.toLocalFile();
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
int Transcoder::JobFinishedEvent::sEventType = -1;
|
||||
|
||||
TranscoderPreset::TranscoderPreset(Song::FileType type, const QString& name,
|
||||
@ -210,8 +215,7 @@ void Transcoder::JobState::PostFinished(bool success) {
|
||||
}
|
||||
|
||||
QString Transcoder::JobState::GetDisplayName() {
|
||||
return QFileInfo(job_.input).fileName() + " => " +
|
||||
QFileInfo(job_.output).fileName();
|
||||
return job_.input.fileName() + " => " + QFileInfo(job_.output).fileName();
|
||||
}
|
||||
|
||||
Transcoder::Transcoder(QObject* parent, const QString& settings_postfix)
|
||||
@ -318,7 +322,7 @@ Song::FileType Transcoder::PickBestFormat(QList<Song::FileType> supported) {
|
||||
return supported[0];
|
||||
}
|
||||
|
||||
void Transcoder::AddJob(const QString& input, const TranscoderPreset& preset,
|
||||
void Transcoder::AddJob(const QUrl& input, const TranscoderPreset& preset,
|
||||
const QString& output, bool overwrite_existing) {
|
||||
Job job;
|
||||
job.input = input;
|
||||
@ -329,7 +333,8 @@ void Transcoder::AddJob(const QString& input, const TranscoderPreset& preset,
|
||||
if (!output.isEmpty())
|
||||
job.output = output;
|
||||
else
|
||||
job.output = input.section('.', 0, -2) + '.' + preset.extension_;
|
||||
job.output = UrlToLocalFileIfPossible(input).section('.', 0, -2) + '.' +
|
||||
preset.extension_;
|
||||
|
||||
// Don't overwrite existing files if overwrite_existing is not set
|
||||
if (!overwrite_existing && QFile::exists(job.output)) {
|
||||
@ -348,14 +353,9 @@ void Transcoder::AddJob(const QString& input, const TranscoderPreset& preset,
|
||||
queued_jobs_ << job;
|
||||
}
|
||||
|
||||
void Transcoder::AddTemporaryJob(const QString& input,
|
||||
void Transcoder::AddTemporaryJob(const QUrl& input,
|
||||
const TranscoderPreset& preset) {
|
||||
Job job;
|
||||
job.input = input;
|
||||
job.output = Utilities::GetTemporaryFileName();
|
||||
job.preset = preset;
|
||||
|
||||
queued_jobs_ << job;
|
||||
AddJob(input, preset, Utilities::GetTemporaryFileName());
|
||||
}
|
||||
|
||||
void Transcoder::Start() {
|
||||
@ -434,13 +434,13 @@ void Transcoder::JobState::ReportError(GstMessage* msg) {
|
||||
|
||||
emit parent_->LogLine(
|
||||
tr("Error processing %1: %2")
|
||||
.arg(QDir::toNativeSeparators(job_.input), message));
|
||||
.arg(UrlToLocalFileIfPossible(job_.input), message));
|
||||
}
|
||||
|
||||
bool Transcoder::StartJob(const Job& job) {
|
||||
shared_ptr<JobState> state(new JobState(job, this));
|
||||
|
||||
emit LogLine(tr("Starting %1").arg(QDir::toNativeSeparators(job.input)));
|
||||
emit LogLine(tr("Starting %1").arg(UrlToLocalFileIfPossible(job.input)));
|
||||
|
||||
// Create the pipeline.
|
||||
// This should be a scoped_ptr, but scoped_ptr doesn't support custom
|
||||
@ -448,8 +448,7 @@ bool Transcoder::StartJob(const Job& job) {
|
||||
if (!state->Init()) return false;
|
||||
|
||||
// Create all the elements
|
||||
GstElement* src = CreateElement("filesrc", state->Pipeline());
|
||||
GstElement* decode = CreateElement("decodebin", state->Pipeline());
|
||||
GstElement* decode = CreateElement("uridecodebin", state->Pipeline());
|
||||
GstElement* convert = CreateElement("audioconvert", state->Pipeline());
|
||||
GstElement* resample = CreateElement("audioresample", state->Pipeline());
|
||||
GstElement* codec = CreateElementForMimeType(
|
||||
@ -458,7 +457,7 @@ bool Transcoder::StartJob(const Job& job) {
|
||||
"Codec/Muxer", job.preset.muxer_mimetype_, state->Pipeline());
|
||||
GstElement* sink = CreateElement("filesink", state->Pipeline());
|
||||
|
||||
if (!src || !decode || !convert || !sink) return false;
|
||||
if (!decode || !convert || !sink) return false;
|
||||
|
||||
if (!codec && !job.preset.codec_mimetype_.isEmpty()) {
|
||||
emit LogLine(
|
||||
@ -476,7 +475,6 @@ bool Transcoder::StartJob(const Job& job) {
|
||||
}
|
||||
|
||||
// Join them together
|
||||
gst_element_link(src, decode);
|
||||
if (codec && muxer)
|
||||
gst_element_link_many(convert, resample, codec, muxer, sink, nullptr);
|
||||
else if (codec)
|
||||
@ -485,7 +483,8 @@ bool Transcoder::StartJob(const Job& job) {
|
||||
gst_element_link_many(convert, resample, muxer, sink, nullptr);
|
||||
|
||||
// Set properties
|
||||
g_object_set(src, "location", job.input.toUtf8().constData(), nullptr);
|
||||
g_object_set(decode, "uri", job.input.toString().toUtf8().constData(),
|
||||
nullptr);
|
||||
g_object_set(sink, "location", job.output.toUtf8().constData(), nullptr);
|
||||
|
||||
// Create target directory, if it does not exist
|
||||
@ -528,7 +527,7 @@ bool Transcoder::event(QEvent* e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString input = (*it)->job_.input;
|
||||
QUrl input = (*it)->job_.input;
|
||||
QString output = (*it)->job_.output;
|
||||
|
||||
// Remove event handlers from the gstreamer pipeline so they don't get
|
||||
@ -591,8 +590,8 @@ void Transcoder::DumpGraph(int id) {
|
||||
}
|
||||
}
|
||||
|
||||
QMap<QString, float> Transcoder::GetProgress() const {
|
||||
QMap<QString, float> ret;
|
||||
QMap<QUrl, float> Transcoder::GetProgress() const {
|
||||
QMap<QUrl, float> ret;
|
||||
|
||||
for (const auto& state : current_jobs_) {
|
||||
if (!state->Pipeline()) continue;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <QMetaType>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
#include <memory>
|
||||
|
||||
#include "core/song.h"
|
||||
@ -70,12 +71,12 @@ class Transcoder : public QObject {
|
||||
int max_threads() const { return max_threads_; }
|
||||
void set_max_threads(int count) { max_threads_ = count; }
|
||||
|
||||
void AddJob(const QString& input, const TranscoderPreset& preset,
|
||||
void AddJob(const QUrl& input, const TranscoderPreset& preset,
|
||||
const QString& output = QString(),
|
||||
bool overwrite_existing = false);
|
||||
void AddTemporaryJob(const QString& input, const TranscoderPreset& preset);
|
||||
void AddTemporaryJob(const QUrl& input, const TranscoderPreset& preset);
|
||||
|
||||
QMap<QString, float> GetProgress() const;
|
||||
QMap<QUrl, float> GetProgress() const;
|
||||
int QueuedJobsCount() const { return queued_jobs_.count(); }
|
||||
|
||||
GstPipelineModel* model() { return model_; }
|
||||
@ -86,7 +87,7 @@ class Transcoder : public QObject {
|
||||
|
||||
static QString GetEncoderFactoryForMimeType(const QString& mime_type);
|
||||
signals:
|
||||
void JobComplete(const QString& input, const QString& output, bool success);
|
||||
void JobComplete(const QUrl& input, const QString& output, bool success);
|
||||
void LogLine(const QString& message);
|
||||
void AllJobsComplete();
|
||||
|
||||
@ -96,7 +97,7 @@ class Transcoder : public QObject {
|
||||
private:
|
||||
// The description of a file to transcode - lives in the main thread.
|
||||
struct Job {
|
||||
QString input;
|
||||
QUrl input;
|
||||
QString output;
|
||||
TranscoderPreset preset;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user