Hi
I wrote a Qt app that converts mp3 audiobooks to iTunes-compatible audiobooks using ffmpeg, too. Here is what I did to catch stdout & stderr logs from ffmpeg.
I made a wrapper class that takes care of converting tracks, one at a time, by running ffmpeg, then renaming the track (.m4b extension), and tagging it (book name, author, cover jpg, track #, etc). All these operations are atomic so I include all of them in one class.
To get ffmpeg output, I declare 2 private slots in my class:
void ffmpegHasStdout();
void ffmpegHasStderr();
void ffmpegHasStdout();
void ffmpegHasStderr();
To copy to clipboard, switch view to plain text mode
And before running ffmpeg, I connect the appropriate QProcess signals to these slots:
connect(&Runner, SIGNAL(readyReadStandardOutput()), this, SLOT(ffmpegHasStdout()), Qt::QueuedConnection);
connect(&Runner, SIGNAL(readyReadStandardError()), this, SLOT(ffmpegHasStderr()), Qt::QueuedConnection);
connect(&Runner, SIGNAL(readyReadStandardOutput()), this, SLOT(ffmpegHasStdout()), Qt::QueuedConnection);
connect(&Runner, SIGNAL(readyReadStandardError()), this, SLOT(ffmpegHasStderr()), Qt::QueuedConnection);
To copy to clipboard, switch view to plain text mode
Runner is the QProcess instance -- be very careful to use Qt::QueuedConnection! QProcess runs the process in a separate thread.
Here is the code for the slots:
void Converter::ffmpegHasStdout()
{
qDebug("Converter::ffmpegHasStdout(): %s", qPrintable(logMsg));
emit ffmpegHasLog(logMsg);
}
void Converter::ffmpegHasStderr()
{
qDebug("Converter::ffmpegHasStderr(): %s", qPrintable(logMsg));
emit ffmpegHasLog(logMsg);
}
void Converter::ffmpegHasStdout()
{
QString logMsg = QString(Runner.readAllStandardOutput()).trimmed();
qDebug("Converter::ffmpegHasStdout(): %s", qPrintable(logMsg));
emit ffmpegHasLog(logMsg);
}
void Converter::ffmpegHasStderr()
{
QString logMsg = QString(Runner.readAllStandardError()).trimmed();
qDebug("Converter::ffmpegHasStderr(): %s", qPrintable(logMsg));
emit ffmpegHasLog(logMsg);
}
To copy to clipboard, switch view to plain text mode
Once caught, I emit the logs to the main GUI window, that has a convenience slot.
Besides, you should get rid of "proc.WaitForFinished();": Qt is fundamentally event-driven, use the signals by connecting QProcess::started() and QProcess::finished(int,QProcess::ExitStatus) to your own slots and deal with it.
I still have some issues though, especially when ffmpeg crashes: sometimes QProcess just notices nothing and hangs. Anybody here has a workaround for this kind of situation?
rvgrouik
Bookmarks