ive been searching for a solution for some hours now, but I cant find a solution.
I want ffmpeg to give me a log file after converting is completed.
this is my code:
$convert = '/usr/bin/ffmpeg -i /var/www/html/videos/' . $fileNormal . '.mp4 -vn -sn -c:a mp3 -ab 192k /var/www/html/audio/' . $fileFixed . '.mp3 2> var/www/html/logs/' . $id . '.txt';
exec($convert);
same with
$convert = '/usr/bin/ffmpeg -i /var/www/html/videos/' . $fileNormal . '.mp4 -vn -sn -c:a mp3 -ab 192k /var/www/html/audio/' . $fileFixed . '.mp3 2> /var/www/html/logs/' . $id . '.txt';
exec($convert);
or
$convert = '/usr/bin/ffmpeg -i /var/www/html/videos/' . $fileNormal . '.mp4 -vn -sn -c:a mp3 -ab 192k /var/www/html/audio/' . $fileFixed . '.mp3 2> /logs/' . $id . '.txt';
exec($convert);
if I add anything at the end after mp3 it doesnt convert at all.
appreciate any help. thanks
If you want to log the screen output of the ffmpeg command, you can do this by redirecting the output to a log file. For example:
/usr/bin/ffmpeg -i /var/www/html/videos/' . $fileNormal . '.mp4 -vn -sn -c:a mp3 -ab 192k /var/www/html/audio/' . $fileFixed . '.mp3 > log_file_path.txt
Also see the man page for the ffmpeg command: https://linux.die.net/man/1/ffmpeg. It mentions loglevel and debug options which can be used to control the level of detail in the log data
Related
code works fine but if the filename has a single qoute just as "Britney's video.mp4" it does not work.
$ffmpeg = "/usb/bin/local/ffmpeg";
$videos = "/videos/*.mp4";
$ouput_path = "/videos/thumbnails/";
foreach(glob($videos) as $video_file){
$lfilename = basename($video_file);
$filename = basename($video_file, ".mp4");
$thumbnail = $ouput_path.$filename.'.jpg';
if (!file_exists($filename)) {
#$thumbnail = str_replace("'", "%27", $thumbnail);
exec("/usr/local/bin/ffmpeg -i '$video_file' -an -y -f mjpeg -ss 00:00:30 -vframes 1 '$thumbnail'");
}
echo "<a href='$lfilename'>$filename<img src='thumbnails/$filename.jpg' width='350'>";
i got it working but not using something overly complicated.
thanks all
$comd = "/usr/local/bin/ffmpeg -i \"$video_file\" -y -f mjpeg -ss 00:00:30 -vframes 1 \"$thumbnail\" 2>&1"; shell_exec($comd);
shell_exec($comd);
As suggested in the comments, you can just wrap all your shell-command String within the escapeshellarg() as shown below.
<?php
foreach(glob($videos) as $video_file){
$lfilename = basename($video_file);
$filename = basename($video_file, ".mp4");
$thumbnail = $ouput_path.$filename.'.jpg';
if (!file_exists($filename)) {
$cmd = "/usr/local/bin/ffmpeg -i ";
$cmd .= $video_file . " -an -y -f mjpeg -ss 00:00:30 ";
$cmd .= "-vframes 1 " . $thumbnail;
exec( escapeshellarg($cmd) );
}
I'm coding up a website back-end that will include user-uploaded video. In order to ensure maximum accessibility, I'm compressing the uploaded videos and re-saving them as .mp4 and .webm format to cover all browsers (or as many as possible anyway). To do this, I'm running an avconv command in the PHP exec() function.
I don't want to make the user wait for the script to finish before the page loads, so I'm running the code asynchronously. My code so far is below.
exec('bash -c "exec nohup setsid avconv -i ' . $tempPath . ' -c:v libx264 ' . $transpose . ' ' . $newPath . 'mp4 > /dev/null 2>/dev/null &"');
exec('bash -c "exec nohup setsid avconv -i ' . $tempPath . ' -c:v libvpx ' . $transpose . ' ' . $newPath . 'webm > /dev/null 2>/dev/null &"');
In addition to running the exec functions, I also save the video to a database and send the user an email thanking them for uploading their video.
Here's the rub: I want the server to WAIT until the video conversion is finished, and THEN add it to the database and send the user an email. Basically, the program flow would be:
User uploads video.
Video is placed in a temp folder.
User is taken to a thank you page indicating their video will be up shortly.
The server executes two avconv commands to convert and compress the video for web use.
Once BOTH conversions are finished, the video info is added to a MySQL database, an email is sent to the user, and the original uploaded video is deleted.
It may just be my ignorance of the command line (in fact it almost definitely is), but how could I 'queue up' these commands? First do both conversions, then call a PHP script to add to the database, then delete the original video, all while being asynchronous with the original PHP script?
EDIT: I've tried queuing them up with an '&&' operator, like below:
exec('bash -c "exec nohup setsid avconv -i ' . $tempPath . ' -c:v libx264 ' . $transpose . ' ' . $newPath . 'mp4 && avconv -i ' . $tempPath . ' -c:v libvpx ' . $transpose . ' ' . $newPath . 'webm > /dev/null 2>/dev/null &"');
However, that seems to cancel out the fact that I'm running it asynchronously, since the page now seems to wait for the command to finish.
You should start an asynchronous command line php script that encodes both videos and then sends an email :
upload.php :
exec('/usr/bin/php -f encode_files.php > /dev/null 2>/dev/null &"');
echo "Files will be encoded, come back later !";
encode_files.php
exec('avconv ...'); // Synchronously ! Without > /dev/null etc ...
exec('avconv ...'); // webm ...
mail('user#user.com', 'Encoding complete ! ', 'Great ! ');
I left the call as "bash -c exec ..." but i think there are shorter ways to call php scripts asynchronously :
Asynchronous shell exec in PHP
You can even pass params (like the user/video id, ...)
$cmd = 'nohup /usr/bin/php -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & printf "%u" $!';
$pid = shell_exec($cmd);
You can disconnect the PHP script from the client but leave it running to complete your tasks.
// Your preliminary stuff here ...
/// then send the user elsewhere but carry on in the background
ignore_user_abort(true);
set_time_limit(0); // i.e. forever
header("Location: thankyoubutwait.php", true);
header("Connection: close", true);
header("Content-Encoding: none\r\n");
header("Content-Length: 0", true);
flush();
ob_flush();
session_write_close();
// more of your video stuff here including database writes
// and clean up bits
// (you may end up with zombie processes though so check your logs or write statuses to files etc.)
It's easy you just have to check the good execution of your command line like this:
// Your code before...
$command = 'bash -c "exec nohup setsid avconv -i ' . $tempPath . ' -c:v libx264 ' . $transpose . ' ' . $newPath . 'mp4 > /dev/null 2>/dev/null &"'
exec($command, $return, $status);
if($status == 0 ) {
$command2 = 'bash -c "exec nohup setsid avconv -i ' . $tempPath . ' -c:v libvpx ' . $transpose . ' ' . $newPath . 'webm > /dev/null 2>/dev/null &"';
exec($command2, $return2, $status2);
if($status2==0){
// let your user know your video traitement has been done
// lauch a new function for alert him
}
}
// Kill your process at end
die();
I am trying to use the command given in the selected answer here, but it does not work when executed. I know that everything else is working since I can create thumbnails with a different command. What is the proper way to format this? I am assuming that the problem is with " -vsync 0 -vf select='not(mod(n,100))' " but have not been able to get it working.
$cmd = $ffmpeg . " -i " . $src . " -vsync 0 -vf select='not(mod(n,100))' " . $out . ".jpg";
exec($cmd);
You have error on this line:
$cmd = $ffmpeg . " -i " . $src . " -vsync 0 -vf select='not(mod(n,100))' " . $out . ".jpg";
Change it to:
$cmd = "ffmpeg -i " . $src . " -vsync 0 -vf \"select='not(mod(n,100))'\" " . $out . ".jpg";
Or try:
$cmd = "ffmpeg -i " . $src . " -vsync 0 -vf select='not(mod(n,100))' " . $out . ".jpg";
Also when you call exec function call it like this:
exec($cmd,$out);
print_r($out);
Print_r will print you output of what was executed in exec()...
I am using the following code for uploading videos
$img1 = $_FILES['video']['name'];
if (!empty($img1)) {
$fname = $_FILES['video']['name'];
$img_name1 = "video/" . $fname;
if(move_uploaded_file($_FILES['video']['tmp_name'], $img_name1)){
$new_name = ShowFileName($fname);
$output = 'video/'.$new_name.'.flv';
$command = "$ffmpegpath -i $img_name1 -s 486x368 -b 400kb -ac 1 -ar 44100 -r 25 -s 320x240 -f flv $output";
$command = $ffmpegpath.' -i'.$img_name1.' -s 486x368 -b 400kb -ac 1 -ar 44100 -r 25 -qmin 3 -qmax 5 -y '.$output;
exec($command);
$thumb_dir = 'video_thumbs/';
$thumb = $new_name.'jpg';
exec($ffmpegpath .' -i '.$img_name1.' -an -y -f mjpeg -ss 0.05 -vframes 1 '.$thumb_dir.$img_name1);
unlink($img_name1);
}
}
It is working properly.ie Successfully moving video into videos folder and insering video name to database table. But the problem is related to the thumb image of this video. Thumb name was insert into database but the image wasn't uploding to the video_thumb folder.......
please help me....
The only problem I see is with the file name in the ffmpeg command line. If it contains special chars you should use escapeshellarg().
php function escapeshellarg
How can I convert FLV to WMV? Is there any script around there or some way I can integrate this?
Thank you!!!
I don't think you can do this directly with PHP.
But, you can use external tools called form PHP (ffmpeg for example).
Here is a code sample:
<?php
$src = "file.flv";
$output = "file.wmv";
ffmpegPath = "/path/to/ffmpeg";
$flvtool2Path = "/path/to/flvtool2";
$ffmpegObj = new ffmpeg_movie($src);
$srcWidth = makeMultipleTwo($ffmpegObj->getFrameWidth());
$srcHeight = makeMultipleTwo($ffmpegObj->getFrameHeight());
$srcFPS = $ffmpegObj->getFrameRate();
$srcAB = intval($ffmpegObj->getAudioBitRate()/1000);
$srcAR = $ffmpegObj->getAudioSampleRate();
exec($ffmpegPath . " -i " . $src . " -ar " . $srcAR . " -ab " . $srcAB . " -vcodec wmv1 -acodec adpcm_ima_wav -s " . $srcWidth . "x" . $srcHeight . " " . $output. " | " . $flvtool2Path . " -U stdin " . $output);
// Make multiples function
function makeMultipleTwo ($value)
{
$sType = gettype($value/2);
if($sType == "integer")
{
return $value;
} else {
return ($value-1);
}
}
?>
Sources:
http://vexxhost.com/blog/2007/05/20/how-to-convertencode-files-to-flv-using-ffmpeg-php/
http://ubuntuforums.org/showpost.php?p=7315615&postcount=10
All solutions you will find are going to use ffmpeg, because that's easy to install on servers and even easier to utilize from PHP scripts. Most always you can just do:
exec("ffmpeg -i video.flv video.wmv");