I am currently trying to convert various video files using FFmpeg with the help of my server (Windows Server 2016). PHP is supposed to initiate the process.
Whenever I start FFmpeg via CMD, everything works fine and the video file converts perfectly. But when I trigger the same process with PHP, FFmpeg aborts the conversion after a while and exits by itself.
I neither get an error in the log nor can I recognize system errors from Windows Server.
It doesn't matter if I run the command through shell_exec, exec, or system.
For converting I actually use this code:
ffmpeg -loglevel error -i $video -vf scale=1920:1080 -crf 10 -c:v libx264 -preset veryfast -threads 2 $output > NUL 2>&1 < NUL
This is my full php code:
ignore_user_abort(true);
set_time_limit(0);
error_reporting( E_ALL | E_STRICT );
$path = 'C:/inetpub/vhosts/confident-tharp.xx-xx-xxx-xxx.plesk.page/httpdocs';
$ffmpeg = $path . '/ffmpeg/ffmpeg.exe';
$video = $path . '/convert/myoldfile.mp4';
$output = $path . '/convertedfile.mp4';
$dimension = 'scale=1920:1080';
$command = "ffmpeg -loglevel error -i $video -vf scale=1920:1080 -crf 10 -c:v libx264 -preset veryfast -threads 2 $output > NUL 2>&1 < NUL";
shell_exec( $command );
I'm currently using FFmpeg 5, but there was no change with FFmpeg 4 either. The use of other codecs or file formats (e.g. .avi) also has no influence on the behavior of FFmpeg. Previously I tried to use the php-ffmpeg library. Again, I get the same "error".
Hope you guys can help.
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 simple site on which people upload videos, so i want to generate a simple thumbnail from an uploaded video. i have tried every trick and way to do this from a number of websites but i am failing to make the command run without problems.
$video = $_FILES['vpopupdropin']["tmp_name"];
$ffmpeg = "C:\\Ffmpeg\\ffmpeg-20130605-git-3289670-win64-static\\bin";
$image = "manu.jpg";
$second = 12;
$size = "150x90";
$command = "$ffmpeg -i $video -an -ss $second -s $size -vcodec mjpeg $image";
echo $command;
shell_exec($command);
if(shell_exec($command)){
echo 'okay';
echo '<img src="'.$image.'"/ >';
}
else{
echo ' Problem';
}
i Echoed the the command from PHP and this is what i got:
C:\Ffmpeg\ffmpeg-20130605-git-3289670-win64-static\bin -i C:\xampp\tmp\php27F1.tmp -an -ss 12 -s 150x90 -vcodec mjpeg manu.jpg Problem
so i took the Command above and entered it in Cmd and got this error
[image2 # 00000000000000003d87580] Could not open file : manu.jpg
av_interleaved_write_frame(): Input/output error. the uploaded file transfers well to where iam saving it and plays well on the site meaning the file is not corrupt. but the thumbnail command seems to fail, i have even checked the other questions on this site but i seem to fail to get the right solution. the paths in the Command are correct and i have verified that at least
You did not give ffmpeg a name :-) So you tried to execute a \\bin folder !
$ffmpeg = "C:\\Ffmpeg\\ffmpeg-20130605-git-3289670-win64-static\\bin";
you forget ffmpeg.exe
$ffmpeg = "C:\\Ffmpeg\\ffmpeg-20130605-git-3289670-win64-static\\bin\\ffmpeg";
I do it for a .avi with following command
ffmpeg -i Echo2012.avi -r 1 -s 1024x576 -f image2 -vframes 1 foo-001.jpg
Don't execute your command twice !
$command = "$ffmpeg -i $video -an -ss $second -s $size -vcodec mjpeg $image";
echo $command;
shell_exec($command);
if(shell_exec($command)){
EDIT :
your command string :
ffmpeg -i upload.tmp -an -ss 12 -s 150x90 -vcodec mjpeg manu.jpg
-vcodec codec (output) : Set the video output codec. It's a switch for a output video. You want as output an image.
-an : You can disable Audio stream. You don't need Audio for an image.
-ss : position (input/output) When used as an input option (before -i), seeks in this input file to position.
my command string :
ffmpeg -i Echo2012.avi -r 1 -s 1024x576 -f image2 -vframes 1 foo-001.jpg
-r : fps (input/output,per-stream) . Set frame rate (Hz value, fraction or abbreviation).
As an input option, ignore any timestamps stored in the file and instead generate timestamps assuming constant frame rate fps.
-f image2 : Force output file format image2. The format is normally auto detected guessed from the file extension for output files.
-vframes number (output) : Set the number of video frames to record.
I'm trying to convert some videos using ffmpeg into different formats.
I have this class,
<?php
define('FFMPEG', 'C:\\cygwin\\usr\\local\\bin\\ffmpeg.exe');
class VideoEncoder {
public function multicodeFileIntoDir($file, $directory) {
$parts = explode('/', $file);
$filename = $parts[count($parts)-1];
$encode_android = FFMPEG.' -i "'.$file.'" -s 480x320 -vcodec mpeg4 -acodec aac -ac 1 -ar 16000 -r 13 -ab 32000 -aspect 3:2 "'.$directory.$filename.'.g1.mp4"';
$encode_windows = FFMPEG.' -y -i "'.$file.'" "'.$directory.$filename.'.avi"';
$out = shell_exec($encode_android);
$out = shell_exec($encode_windows);
}
}
On debugging the commands that would be run, they work as expected, and produce the correct file. The permissions on the directory I'm calling this code on has permissions as 777, $out is null, and the command has no effect.
I have error_reporting as E_ALL, and display_errors is TRUE.
An example of the command (the value of $encode_windows just before executing) is
C:\cygwin\usr\local\bin\ffmpeg.exe -y -i "C:\xampp\htdocs\cams/../front/vid20110623_122802.mp4" "C:\xampp\htdocs\cams/../front/vid20110623_122802.mp4.avi"
Edit: It seems like it is writing to STDERR, somehow the output of the command is in the apache error log. Still, the output seems ok..
Any ideas?
Thanks
I have installed ffmpeg on my server.
Now I am looking for a php library which can perform ffmpeg functionality, like retrieving video information, converting it to FLV or in any other format, and streaming video.
Please help, Thanks!
You can use below function to convert mp4 video to flv
function mp4toflv($in, $out)
{
//echo $in.' '.$out;
$thumb_stdout;
$errors;
$retval = 0;
// Delete the file if it already exists
if (file_exists($out)) { unlink($out); }
$cmd = "ffmpeg -i $in -ar 22050 -acodec libmp3lame -ab 32K -r 25 -s 320x240 -vcodec flv $out";
//$cmd = "ffmpeg -i $in -b 1024k -s 352x264 -r 25 -acodec copy $out";
//echo escapeshellcmd($cmd);
exec(escapeshellcmd($cmd));
unlink($in);
}
similarly you can also convert other video formats to flv or any other format. Below are some help to convert videos to mp4(h264)
1]. ffmpeg -i input.mp4 -vcodec libx264 output.mp4
2]. ffmpeg input.AVI -vcodec libx264 -sameq output.mp4
option 1 can use for :- (mp4,mov,flv)
option 2 can user for :- (3gp,avi,mp4,mov,flv)
execute above commands using "exec(escapeshellcmd($cmd))" where $cmd will be any from above two options.
Hope this will help someone :)
We have been using ffmpeg-php without any major problems, just make sure you are using supported ffmpeg version. If you need any special behaviour, you can always additionally wrap it using exec().
I want to convert a video from one format to another using ffmpeg. I try lots of code but it does not convert the video.
For example:
exec("ffmpeg -i mickey.flv -ar 22050
-ab 32 -f avi -s 320x240 mickey.avi ");
This code does not convert the video, it does not show any error, it is loading continuously.
It is impossible to pinpoint the problem, because you are executing an external application and any number of things could be going wrong in the process.
See this question for a number of very good hints to debug exec() commands.
Display FFMPEG Error Output:
Command Line:
$command = "ffmpeg -i mickey.flv -ar 22050 -ab 32 -f avi -s 320x240 mickey.avi ";
exec($command . ' 2>&1', $output);
print_r($output);