Why exec() is not working in foreach loop? - php

See, for testing purpose if I am trying to run PHP exec() statically with only one video file, then its compressing video perfectly(please see first line line).
Later when I am compressing dynamically in the loop, then exec function is not working. Please tell me why it's not working in the loop?
// echo shell_exec("/usr/local/bin/ffmpeg -i /home4/machine/public_html/riyaz/check_video/video_1494453415.mp4 -strict -2 -crf 20 /home4/machine/public_html/riyaz/zcompress/video_1494453415.mp4");
#include_once("start.php");
$directory_path = FILEPATH.'/';
$video_mp4 = glob("/home4/machine/public_html/riyaz/check_video/*.mp4");
/*video size will show in mb*/
foreach ($video_mp4 as $video_mp4_list){
$video_size = filesize($video_mp4_list);
$video_size_in_mb = round(($video_size/1048576), 2);
$get_file_name = explode('/',$video_mp4_list);
$get_file_name_for_destination = $get_file_name[6];
$getSourceFileNamePath = '/home4/machine/public_html/riyaz/check_video/'.$get_file_name_for_destination;
$getDestFileNamePath = '/home4/machine/public_html/riyaz/zcompress/'.$get_file_name_for_destination;
if ($video_size_in_mb >= 1000 ){
echo exec("/usr/local/bin/ffmpeg -i ". $getSourceFileNamePath ." -strict -2 -crf 20 ".$getDestFileNamePath);
}
}

shell_exec() returns the full output: PHP shell_exec() however
exec() returns only the last line from the outptut that might be empty.. So you have to provide second $output and third parameter $return_var to get more useful data: PHP exec()
if ($video_size_in_mb >= 1000 ){
$command = "/usr/local/bin/ffmpeg -y -i ". $getSourceFileNamePath ." -strict -2 -crf 20 ".$getDestFileNamePath . ' 2>&1';
echo PHP_EOL ."Executing command: ". $command;
if(file_exists($getDestFileNamePath)) echo "File already exists!";
$output = null;
$return_var = null;
exec($command, $output, $return_var);
print_r($command);
print_r($return_var);
print_r($output);
echo PHP_EOL;
} else {
echo "video too small to proceed';
}
php shell_exec() vs exec()
EDIT: The problem is that the destination file exists and ffmpeg exits without any action. One solution is to use attribute -y to overwrite the output file 5.4 Main options -y (global) Overwrite output files without asking.

Related

How to run ffmpeg with php in debian 10

i am trying to run a ffmpeg command with my php in Debian 10, but its not working, but the command is working perfectly in windows. The command is to add a watermark and a text at the bottom of the video.
Here is the php code
<?php
$new_file="new.mp4";
$text="eloke";
$video_name="video.mp4";
echo file_exists($new_file)? "<video autoplay src='$new_file'></video>":"No file";
$cmd="ffmpeg -i $video_name -i watermark.jpg -filter_complex overlay=W-w-5:H-h-15[video];[video]drawtext=\"text=$text:fontcolor=white:fontsize=12:x=(w-text_w)-5: y=(h-text_h)-5\" $new_file";
exec("$cmd 2>&1", $output);
var_dump($output);
?>
I am getting this in the browser
array(1) { [0]=> string(103) "sh: 1: [video]drawtext=text=eloke:fontcolor=white:fontsize=12:x=(w-text_w)-5: y=(h-text_h)-5: not found" }
Please what am i doing wrong
Try using the following snippet and replace into your original code:
$cmd = "ffmpeg -i ".$video_name." -i watermark.jpg -filter_complex overlay=W-w-5:H-h-15[video];[video]drawtext=\"text=".$text.":fontcolor=white:fontsize=12:x=(w-text_w)-5: y=(h-text_h)-5\" ".$new_file;
$cmd = escapeshellcmd($cmd);
exec($cmd." > /path/to/stdout_file 2>&1", $output);
Also, beware of using escapeshellcmd()

How to run Fast lane in terminal using php? exec() or shell_exec()

i was trying run fast lane commands in terminal using php, the commands like cd, pwd, ls and chmod working fine in php using exec or shell exec functions but when i try to run fast lane command it throws error 127, how can i run fast lane using php?
function terminal($command)
{
$output = [];
$return_var = '';
//exec
if (function_exists('exec')) {
exec($command, $output, $return_var);
} else {
$output = 'Command execution not possible on this system';
$return_var = 1;
}
return array('output' => $output, 'status' => $return_var);
}
// $path = "cd /Applications/XAMPP/xamppfiles/htdocs/mystudiomobile/cordova7/platforms/ios/fastlane";
// $path_c = "fastlane init"; path and path_c present in test.sh
$command = "/Applications/XAMPP/xamppfiles/htdocs/php1/test.sh";
$path_change = terminal("$command");
if($path_change['status'] == 0)
{
echo json_encode($path_change['output']);
echo $path_change['status'];
}
else
{
echo "some problem";
echo $path_change['status'];
}
I found out that there are limitations in php to perform http and https protocols using system functions like exec. which could not run fast lane, the best practise is to go with bash script which access php instead of vice versa .

Loop bash script until cURL response doesn't equal string

I'm trying to loop a bash script (cURL below) until my remote PHP script doesn't equal failure. I've tried the following, and it works when $fileName exists.. but doesn't loop when it returns failure.
My PHP:
<?php
$videoFile = $_GET["name"] . ".mp4";
if (file_exists($videoFile)) {
echo "success";
} else {
echo "failure";
}
?>
Bash command:
until $(curl --output /dev/null --silent --head --fail "my-remote-php-script.php"); do
printf '.'
sleep 1
done
This should work:
while [ "$(curl -s 'http://your-url.php')" == "failure" ]; do
echo -n '.'
sleep 1
done
The $() places the curl in a sub-shell. The resulting string, comming from your php script, is compared with failure.
Try this:
url="http://server.tld/foo.php"
until curl -sf "$url"; do echo -n "."; sleep 1; done

How to trim silence from audio with ffmpeg in php

My hosting does not have ffmpeg's silenceremove filter, so I'm trying to remove the beginning and end silence of an audio file with silencedetect then cut. I'm trying to do this programmatically with php. At this point, I can't even detect the silence. I've tried:
define('UPLOAD_DIR', $_SERVER['DOCUMENT_ROOT'].'/audiofiles/');
$filein = UPLOAD_DIR . "music.ogg";
$fileout = UPLOAD_DIR . "music_no_silence.ogg";
$fileouttxt = UPLOAD_DIR . "music_log.txt";
$ffmpeg = "/usr/local/ffmpeg/bin/ffmpeg";
I first tried to put the ffmpeg command into a variable and then tried to access the output but was unable:
$output = shell_exec("$ffmpeg -i $filein -af silencedetect=n=-50dB:d=1");
echo $output;
I then tried to create a.txt log of the conversion but the .txt file doesn't show anything about the silencedetect. Furthermore, how would I be able to extract the info that I need programmatically from the .txt log in order to use it in php?
shell_exec("$ffmpeg -i $filein -af silencedetect=n=-50dB:d=1 $fileout 2> $fileouttxt");
I'm basically trying to adapt the answer at https://stackoverflow.com/a/25698675 into php
Edit: Here's kind of a hack way to do it:
define('UPLOAD_DIR', $_SERVER['DOCUMENT_ROOT'].'/audiofiles/');
$filein = UPLOAD_DIR . "music.ogg";
$fileout1 = UPLOAD_DIR . "music_out1.ogg";
$fileout2 = UPLOAD_DIR . "music_out2.ogg";
$ffmpeg = "/usr/local/ffmpeg/bin/ffmpeg";
$command = "$ffmpeg -i $filein -filter_complex silencedetect=n=-10dB:d=0.5 -y $fileout1 2>&1";
$output = array();
exec($command,$output);
$searchword1 = 'silence_end';
$endmatches = array_filter($output, function($var) use ($searchword1) {return preg_match("/\b$searchword1\b/i", $var);});
$endmatches = array_values($endmatches);
$parts1 = explode(" ",$endmatches[0]);
$a = $parts1[4];
$a = $a-.5;
$searchword2 = 'silence_start';
$startmatches = array_filter($output, function($var) use ($searchword2) {return preg_match("/\b$searchword2\b/i", $var);});
$startmatches = array_values($startmatches);
$parts2 = explode(" ",end($startmatches));
$b = $parts2[4];
$b = $b+.5;
$c = $b-$a;
exec("$ffmpeg -i $fileout1 -ss $a -t $c -y $fileout2 && rm $fileout1");
PHP's shell_exec returns the output written to stdout and ffmpeg writes the messages to stderr. If you want to use shell_exec you must redirect the stderr output to stdout using 2>&1.
You also need to specify at least one output file for ffmpeg, in this case /dev/null.
set_time_limit(0);
$input_file = 'music.ogg';
$cmd = "ffmpeg -i {$input_file} -af silencedetect=n=-50dB:d=1 -f null /dev/null 2>&1";
$output = shell_exec($cmd);
if (preg_match_all("/^\[silencedetect\s[^]]+\]\s([^\n]+)/m", $output, $matches)) {
var_export($matches[1]);
}
An alternative is to use proc_open and stream_get_contents.

How to get pid of the process that run in background exec by shell in php

I'm working on a shell in php, and I want to display the same output as bash. When in bash you execute sleep 10 & you'll get [1] <PID>. How can I do the same in php, when I call shell using:
if (preg_match("/&\s*$/", $command)) {
$this->$shell_fn($token, '/bin/bash -c ' . escapeshellarg($command) .
" > /dev/null");
return array(
'output' => '',
'cwd' => $path
);
}
$shell_fn is variable that point to wrapper over shell_exec, exec or cgi script called by curl. Is it even possible to get the pid from php or using a shell?
If you want the pid in bash, you can do use the ! special parameter to get the pid of the most recently backgrounded process:
bash -c 'sleep 10 & echo $!'
I don't know exactly how php spawns external processes, but I imagine you'd be able to capture the echo output here, just by running the above shell command.
I use this functions to manage process:
function ProcessStart($cmdline) // return pid
{
exec( "nohup $cmdline >/dev/null 2>&1 & echo $!", $output) ;
// print_r ($output);
return (int)$output[0];
}
function ProcessStatus($pid) // return TRUE (live) o FALSE (dead)
{
exec("ps -p $pid",$output);
// print_r($output);
return ( isset($output[1]) ? TRUE : FALSE ) ;
}
function ProcessStop($pid)
{
exec("kill $pid",$output); // kill -9 ??
}

Categories