When I run exec() through php, I fail to get the output (stderr) into a file.
I've included "2> my_out_put_file.txt" at the end of my command to accomplish this. But when I include this, the command is not executed. However, if I run the command without "2> my_out_put_file.txt" then it works.
The interesting thing is that the whole command, even with "2> my_out_put_file.txt" at the end of the command works if I run directly via shell/promt, but not when I run it through php / apache.
Does not work:
exec("C:/FFmpeg/bin/ffmpeg -i $new_path/$filename_with_ext -f mp4 -vcodec libx264 -preset ultrafast -profile:v main -acodec aac $new_path/$filename.mp4 2> out.txt", $a, $b);
Works:
exec("C:/FFmpeg/bin/ffmpeg -i $new_path/$filename_with_ext -f mp4 -vcodec libx264 -preset ultrafast -profile:v main -acodec aac $new_path/$filename.mp4", $a, $b);
Best regardsNeo
This worked for me:
... 2>&1 >> log.txt
Tested from exec too:
php -r "exec('ffmpeg -version 2>&1 >> log.txt');"
Related
I have a video encoding server set up on Laravel Forge with nginx. I'm trying to run a testing script to encode a video remotely via SSH, using the LaravelCollective SSH package.
This is my testing script (index.php)
<?php
exec("ffmpeg -I input.mpg -c:v libx264 -preset faster -crf 22 -c:a aac -strict experimental -movflags +faststart -vf scale=360:-1 output.mp4 1> output.txt 2>&1");
When I SSH into the server and run the script from the command line it works: the video is encoded; the script is working.
$ php /home/forge/mydomainname.com/public/test/index.php
However, when I run the same command locally in my Laravel app - using the SSH package - it doesn't encode and I receive no output; the browser just returns a white page.
SSH::run('php /home/forge/mydomainname.com/public/test/index.php', function($line) {
echo $line.PHP_EOL;
});
However however, if I open index.php, comment out the FFmpeg command and add some code to check if exec is enabled, it will execute and send output, so I know that the SSH package is actually working and executing the script remotely.
<?php
// exec("ffmpeg -I input.mpg -c:v libx264 -preset faster -crf 22 -c:a aac -strict experimental -movflags +faststart -vf scale=360:-1 output.mp4 1> output.txt 2>&1");
if(function_exists('exec')) {
echo "exec is enabled";
} else {
echo "exec is disabled";
}
It will return "exec is enabled" to my browser.
To sum up:
The script will encode video when running it via the command line on the server.
The script will not encode video when running it remotely.
The script will execute when running it remotely.
WTH?
I figured it out.
From within my Laravel app I decided to try echo exec('whoami'); and see if that returned anything to the browser. It did, so I knew exec() was working and I could trigger it via the SSH package.
Then I realized that my ffmpeg encoding command was suppressing output with 2>&1. I removed that and finally saw what was going on: I was receiving a "file not found" error, which was weird because input.mpg is in the same directory as index.php.
This has worked on three other servers, but not on this one created with Forge.
So I added the full path to the input file and voilà! It works!
exec("ffmpeg -i /home/forge/mydomainname.com/public/test/input.mpg -c:v libx264 -preset faster -crf 22 -c:a aac -strict experimental -movflags +faststart -vf scale=360:-1 /home/forge/mydomainname.com/public/test/output.mp4 1> /home/forge/mydomainname.com/public/test/output.txt ");
I have a php script which is creating a list of images (usually around 400) to feed to ffmpeg via an exec command, it breaks. Is there another way to send multiple images?
Sample code below
$imgs4vid = "'dir/img1.jpg' 'dir/img2.jpg' 'dir/img3.jpg' 'dir/img4.jpg' 'dir/img5.jpg' etc.."
exec("ffmpeg -r 1/5 -pattern_type glob -i ".$imgs4vid." -c:v libx264 -r 30 -pix_fmt yuv420p ".$vid_name.".mp4 2>&1", $output);
var_dump($output);
I have a way to do with -f concat -i (generatoe a list of files and put her)
Seems like a long way to do it though, must be an easier solution?
Thanks
You can use patterns for input (and output) file names:
ffmpeg -i /dir/img%d.jpg -s 640x480 -vcodec mjpeg /tmp/out.avi
hai i am using ffmpeg command in php exec() for converting any type of video to flv format the command i'm using i sworking fine in the command prompt but when i run the same commend it returns nothing..actully the output is Array( ) and the the third parameter $result is "1"
i've read similar questions like this on stackoverflow but it's not helping
most of the time i noticed that the issue is in path and the safe mode of php
and i have disabled safe mode using .htaccess the syntax is given below and i am using windows 7 os
the directory to the ffmpeg application is c:\ffmpeg\bin\ffmpeg
the full script and output is given below:
the ffmpeg command:
ffmpeg -i c:\xampp\htdocs\video\original\robot.mp4 -c:v libx264 -ar 44100 -crf 17 c:\xampp\htdocs\video\vids\robot.flv
the php script:
echo "starting ffmpeg...<br/>";
echo exec("ffmpeg -i c:\xampp\htdocs\video\original\robot.mp4 -c:v libx264 -ar 44100 -crf 17 c:\xampp\htdocs\video\vids\robot.flv",$out,$r);
var_dump($out);
echo $r."<br/>";
echo "done...<br/>";
?>
the htaccess for switching off the safe mode:
php_value safe_mode "0"
the output:
starting ffmpeg...
array(0) { } 1
done...
Try the below one instead of using exec(ffmpeg -i 'inputfile' 'outputfile');
$cmd = "ffmpeg -i c:\xampp\htdocs\video\original\robot.mp4 -c:v libx264 -ar 44100 -crf 17 c:\xampp\htdocs\video\vids\robot.flv"
ob_start();
passthru($cmd);
$cmd_retr = ob_get_contents();
print_r($cmd_retr);
<?php
echo exec("cmd /c ffmpeg -i c:\\xampp\htdocs\video\original\robot.mp4 -c:v libx264 -ar 44100 -crf 17 c:\\xampp\htdocs\video\vids\robot.flv",$out,$r");
?>
I am trying to get FFMPEG to work in php. I just installed ffmpeg and x264 and ran the following command in my terminal:
$command = 'ffmpeg -i /home/gman/Desktop/cave.wmv -acodec libfaac -aq 100 -vcodec libx264 -preset slow -crf 22 -threads 0 /home/gman/Desktop/newvideo.flv
It worked perfectly and created a new flv video from the inital video, just like I wanted.
Now when I try the same thing in php, nothing happens...
$safe_path = escapeshellarg("/home/gman/Desktop/newvideo.flv");
$command = 'ffmpeg -i /home/gman/Desktop/cave.wmv -acodec libfaac -aq 100 -vcodec libx264 -preset slow -crf 22 -threads 0 ' . $safe_path;
exec($command);
Anyone have any ideas? Can I somehow see what exec is doing and see some sort of output? Would appreciate it.
Usually when you are calling ffmpeg in an exec you need to put in the absolute path to ffmpeg eg:
$safe_path = escapeshellarg("/home/gman/Desktop/newvideo.flv");
$command = '/usr/local/bin/ffmpeg -i /home/gman/Desktop/cave.wmv -acodec libfaac -aq 100 -vcodec libx264 -preset slow -crf 22 -threads 0 ' . $safe_path;
exec($command);
http://blog.codyjung.com/2011/05/29/problems-with-lampp-and-exec/
My solution was to simply copy the ones from /usr/lib/i386-linux-gnu and overwrite the LAMPP ones. Could that cause problems later? Maybe, but I guess we’ll deal with that when it shows up.
On my website I'm using phpmotion to convert videos into FLV files.
What I want to do is that after the successful conversion of any new FLV file add short FLV file at the beginning.
So, I need FFMPEG command in PHP which will join the file 1.flv (intro file) with 2.flv (successful converted file) and as a result create final.flv
I tried with:
ffmpeg -i 1.flv -i 2.flv -vcodec copy -acodec copy final.flv
But without result.
Thanks for any suggestion.
Here is the code, you have to seperate audio and video to raw files at first, join them then again convert back to flv
mkfifo temp1.a
mkfifo temp1.v
mkfifo temp2.a
mkfifo temp2.v
mkfifo all.a
mkfifo all.v
ffmpeg -i 1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
ffmpeg -i 2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
ffmpeg -i 1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
{ ffmpeg -i 2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; } &
cat temp1.a temp2.a > all.a &
cat temp1.v temp2.v > all.v &
ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
-f yuv4mpegpipe -i all.v \
-sameq -y output.flv
rm temp[12].[av] all.[av]
I guess you can use mencoder to merge two files.
mencoder -oac copy -ovc copy -o c:\video.flv c:\a.flv c:\b.flv