Using ImageMagick to resize images from command line in PHP - php

I'm using ImageMagick to generate a small thumbnail of images. convert --version shows ImageMagick 4.2.9 99/09/01.
$output = array();
$cmd = "/opt/RZmagick4/bin/convert data/test.jpg data/small.png"; // works fine
$cmd = "/opt/RZmagick4/bin/convert data/test.jpg -resize 300x200 data/small.jpg"; // does not work
exec($cmd, $output);
echo "<pre>";
print_r($output);
echo "</pre>";
Why does the second $cmd not work? Output for both is Array( ). However, there is just no output image.

You should write this:
$cmd = "/opt/RZmagick4/bin/convert -resize 300x200 data/test.jpg data/small.jpg";

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()

Why exec() is not working in foreach loop?

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.

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.

saving email body as tiff php

I want to save the email body (the content of email) in tiff format
I am able to download and save it as txt with:
$data = imap_qprint(imap_body($imap, $num));
file_put_contents($folder.$timestamp, $data);
but I want to save it in tiff and the Format of the content should remain exactly as it is.
Any Ideas how to do it in PHP? Thanks.
Assuming you have ImageMagick installed:
$txt = $folder . $timestamp;
$tiff = $txt . '.tiff';
$cmd = sprintf("convert text:%s %s 2> /dev/null", $txt, $tiff);
exec($cmd, $output, $return_var);
$return_var == 0 or die("Conversion failed\n");
I think there are a lot of other ways tough.

imagemagick no output

here is my code:
<?php
error_reporting(E_ALL) ;
$orig = "original.jpg";
$out = "output.jpg";
$cmd = "-sepia-tone 90%";
exec("/usr/bin/convert $orig $cmd $out ");
?>
After I run this, I expected a sepia toned version of original.jpg named output.jpg. when I check the directory, output.jpg doesnt exist.
What am I missing?
<? php should be <?php.

Categories