tags:

views:

369

answers:

4

Hi all,

I'm trying to execute a ffmpeg operation through Qt

I would like to execute this line :

./ffmpeg -t 10 -i temp1 -f mpeg  -  >  temp2

When I execute through the terminal, it works perfectly fine.

How ever when I launch it through Qt like this :

 QProcess    *process = new QProcess();

 QString parameters("./ffmpeg -t 10 -i temp1 -f mpeg  - >  temp2");
 std::cout << process->execute(parameters) << std::endl;

I get an Unable to find a suitable output format for '>' any body has the idea of why ?

+2  A: 

When you type your original command in the shell, ffmpeg outputs to stdout. The shell interprets the > redirection operator, so output is sent to temp2. The last thing ffmpeg sees is the -.

When you use QProcess like that, there is no shell, so ffmpeg sees > and temp2 as arguments, which it doesn't interpret as you expect. In this case, there's an easy solution. Just have ffmpeg output to temp2 instead of stdout:

QString parameters("./ffmpeg -t 10 -i temp1 -f mpeg temp2");
std::cout << QProcess::execute(parameters) << std::endl;

In other cases, you might have to execute a shell explicitly, something like:

QStringList paramList;
paramList << "-c" << "./ffmpeg -t 10 -i temp1 -f mpeg  - >  temp2";
std::cout << QProcess::execute("sh", paramList) << std::endl;

Note that QProcess::execute is static, so an instance is not needed (this applies no matter how you call execute).

Matthew Flaschen
A: 

When you run this from the shell, the shell interprets the '> temp 2' as a redirection and never passes that to the ffmpeg process. When you run process->execute() this function is passing everything after ./ffmpeg as command-line parameters. If you really want shell-redirection, you need to run a new shell and have that shell execute your command line. This might work:

QString parameters("/bin/sh -c '/ffmpeg -t 10 -i temp1 -f mpeg  - >  temp2'");
std::cout << process->execute(parameters) << std::endl;

I'm not familiar with the quoting rules for Qt, so this might not work perfectly, but basically you want to prepend /bin/sh -c and then quote the command you actually want to run including the stdout redirection.

kbyrd
It's better to use "/bin/sh -c" instead of "bash -c". This approach is more reliable since bash may be not installed at all.
VestniK
+2  A: 

Hi.

Here is another example:

QProcess p;
p.start("./ffmpeg", QStringList() << "-t 10" << "-i temp" << "-f mpeg");
p.waitForFinished();
qDebug() << p.readAllStandardOutput();

Where p.readAllStandardOutput() is a QByteArray and you can read with is all data available from the standard output of the process, for example write them to file:

QFile file("out.txt");
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    return;

QTextStream out(&file);
out << p.readAllStandardOutput();

file.close();
mosg
+1  A: 

Another remark: It's also a good idea to always use the QStringList variant to pass args instead of a plain string - otherwise you'll run into quoting issues pretty soon, especially on Windows where paths with spaces in it are common. The QStringList variants do the right thing (TM).

Frank
True. It has been changed in order to use QStringList. Thank you
Spredzy