Audio convertion using ffmpeg on exec() php function - ffmpeg

any body explain why exec(),shell_exec(), system() can not return any return value while executing ffmpeg commands.
ie:
exec("Who am i", $output = array());
//here execution is success and $output is set an array value
$output= shell_exec("Who am i");
//here execution is success and $output is set an array value
system("Who am i", $output = array());
//here execution is success and $output is set an array value
but
exec('ffmpeg -i "$sourcepath/Test.mp3" -vn -acodec libvorbis -ab 128k -y $desnpath/TestTest.ogg"', $output = array());
//here execution is success but $output is not set an array value
$output= shell_exec('ffmpeg -i "$sourcepath/Test.mp3" -vn -acodec libvorbis -ab 128k -y $desnpath/TestTest.ogg"');
//here execution is success but $output is not set an array value
system('ffmpeg -i "$sourcepath/Test.mp3" -vn -acodec libvorbis -ab 128k -y $desnpath/TestTest.ogg"', $output = array());
//here execution is success but $output is not set an array value
i don't know why..!?
please any body help me.

It is because ffmpeg does not output anything to stdout. Its output is printed to stderr.
If you are on a non windows system you can do exec('ffmpeg -i "$sourcepath/Test.mp3" -vn -acodec libvorbis -ab 128k -y $desnpath/TestTest.ogg 2>&1"', $output = array()); or you can use proc_open()

Related

Compound ffmpeg commands stored in a variable is not executed correctly

Following bash script:
#!/bin/bash
#-_-_-_--- CONFIGURATION ---_-_-_-
CAMERA_COUNT=2
SRC_WIDTH=320
SRC_HEIGHT=240
MARGIN=320
#-_-_-_--- END CONFIGURATION---_-_-_-
CHARS=( {A..Z} )
FULL_WIDTH=$((SRC_WIDTH * CAMERA_COUNT))
FFMPEG="ffmpeg "
for ((i = 0; i < CAMERA_COUNT; i++))
do
FFMPEG+="-f flv -i rtmp://127.0.0.1:1935/live/PanoView${CHARS[i]} "
done
FFMPEG+="-filter_complex \"nullsrc=size=$((SRC_WIDTH * CAMERA_COUNT))x${SRC_HEIGHT} [base]; [base][0:v] overlay [tmp1]; "
for ((i = 1; i < CAMERA_COUNT - 1; i++))
do
FFMPEG+="[tmp${i}][${i}:v] overlay=x=$((SRC_WIDTH * i)) [tmp$((i + 1))];"
done
FFMPEG+="[tmp$((CAMERA_COUNT - 1))][$((CAMERA_COUNT - 1)):v] overlay=x=$((SRC_WIDTH * (CAMERA_COUNT - 1)))\" -f flv -b:v 1M -an -r 25 rtmp://127.0.0.1:1935/live/test"
$FFMPEG
echo $FFMPEG
The output of the last echo:
ffmpeg -f flv -i rtmp://127.0.0.1:1935/live/PanoViewA -f flv -i rtmp://127.0.0.1:1935/live/PanoViewB -filter_complex "nullsrc=size=640x240 [base]; [base][0:v] overlay [tmp1]; [tmp1][1:v] overlay=x=320" -f flv -b:v 1M -an -r 25 rtmp://127.0.0.1:1935/live/test
When I execute the compound command in the FFMPEG variable in the script, I get the error message:
[AVFilterGraph # 0x7fffed837620] No such filter: '"nullsrc'
Error initializing complex filters.
Invalid argument
However, if I copy the composite code, which I have the script output at the end, paste it and execute it, everything works as expected. What could be the reason?

concat two video using ffmpeg working on local but not working on server why?

Here the code is for concat two video and adding watermark to that video but this code working perfectly in local but not in server.
The code is as follows:
$videoFileName = rand('111111', '999999').'_'.time().'.'.$request->file('video1')->getClientOriginalExtension();
$intermediateVideo1 = rand('1111111', '9999999').'_'.time().'.ts';
$intermediateVideo2 = rand('1111111', '9999999').'_'.time().'.ts';
$concatVideoFileName = rand('111111', '999999').'_'.time().'.'.$request->file('video1')->getClientOriginalExtension();
exec('ffmpeg -i '.$request->file('video1').' -c copy -bsf:v h264_mp4toannexb -f mpegts '.$intermediateVideo1);
exec('ffmpeg -i '.$request->file('video2').' -c copy -bsf:v h264_mp4toannexb -f mpegts '.$intermediateVideo2);
exec('ffmpeg -i "concat:'.$intermediateVideo1.'|'.$intermediateVideo2.'" -c copy -bsf:a aac_adtstoasc '.public_path('uploads/videos/'.$concatVideoFileName));
exec('ffmpeg -i '.public_path('uploads/videos/'.$concatVideoFileName).' -i '.storage_path("assets/image/watermark.png").' -filter_complex "overlay" '.public_path('uploads/videos/'.$videoFileName));
File::delete($intermediateVideo1);
File::delete($intermediateVideo2);
File::delete(public_path('uploads/videos/'.$concatVideoFileName));

How to Create video from selected images of a folder using FFMPEG?

For the time being I am doing
ProcessStartInfo ffmpeg = new ProcessStartInfo();
ffmpeg.CreateNoWindow = false;
ffmpeg.UseShellExecute = false;
ffmpeg.FileName = "e:\ffmpeg\ffmpeg.exe";
ffmpeg.Arguments = "for file in (D:\\Day\\*.jpg); do ffmpeg -i \"$file\" -vf fps=1/60 -q:v 3 \"D:\\images\\out.mp4\"; done;";
ffmpeg.RedirectStandardOutput = true;
Process x = Process.Start(ffmpeg);
Here I'm getting exception saying system cannot find specified file.
For time being I'm considering all the files in D:\Day\*.jpg but actually I need to query individual files from a list.
Where am I wrong in the above scenario?
We need to create a separate text file with the image names and use that text file to create your video.
inside frameList.txt :
file 'D:\20180205_054616_831.jpg'
file 'D:\20180205_054616_911.jpg'
file 'D:\20180205_054617_31.jpg'
file 'D:\20180205_054617_111.jpg'
and in Arguments of the process use,
"-report -y -r 15/1 -f concat -safe 0 -i frameList.txt -c:v libx264 -s 1920*1080 -b:v 2000k -vf fps=15,format=yuv420p out.mp4"

If conditions in a loop breaking ffmpeg zoom command

I have built a bash script where I am trying to zoom in an image with ffmpeg, for 10s:
ffmpeg -r 25 -i image0.jpg -filter_complex "scale=-2:10*ih,zoompan=z='min(zoom+0.0015,1.5)':d=250:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)',scale=-2:720" -y -shortest -c:v libx264 -pix_fmt yuv420p temp_1.mp4
This command is included in a while loop, with two "if" conditions at the beginning of the loop:
first=1017
i=0
while read status author mySource myFormat urlIllustration credit shot_id originalShot categories title_EN length_title_EN text_EN tags_EN title_FR length_title_FR text_FR tags_FR title_BR length_title_BR text_BR tags_BR; do
if [ $myFormat != "diaporama" ]; then
let "i = i + 1"
continue
fi
if [ "$shot_id" -lt "$first" ]; then
let "i = i + 1"
continue
fi
rm temp_1.mp4
ffmpeg -r 25 -i image0.jpg -filter_complex "scale=-2:10*ih,zoompan=z='min(zoom+0.0015,1.5)':d=250:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)',scale=-2:720" -y -shortest -c:v libx264 -pix_fmt yuv420p temp_1.mp4
let "i = i + 1"
done <../data.tsv
echo "All done."
(I have removed stuff in the loop, this is the minimal code that is able to capture the problem).
Now the weird bug: if I run this code like that, the video I am trying to generate will not be 10s long, only 1-2s long. ffmpeg exits with error "[out_0_0 # 0x2fa4c00] 100 buffers queued in out_0_0, something may be wrong."
Now if I remove one of the "if" conditions at the beginning of my loop (the first or the second, it doesn't matter), the video will be generated fine and be 10s long.
What could be the cause of this problem?

Spaces in variable

I am facing some problems with spaces in variables:
ALBUM=' -metadata album="Peregrinações Alheias"'
This command:
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k "$ALBUM" -y $OUT
Returns:
Unable to find a suitable output format for ' -metadata album="Peregrinações Alheias"'
And if I take out the "" from the variable:
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k $ALBUM -y $OUT
Returns:
Unable to find a suitable output format for 'Alheias"'
And I am sure I am missing something in the bash sintax...
UPDATE:
So it looks that the matter is not with spaces but with the "-metadata" argument...
The problem is that I have many metadata and I'd like to put them in just one variable. Like this:
META=' -metadata album="Peregrinações" -metadata title="Passeio ao PETAR" -metadata author="Rogério Madureira" -metadata date="2012" -metadata description="Áudio de um passeio ao PETAR" -metadata comment="Áudio capturado com TACAM DR-07MKII e Foto capturada com Canon PowerShot S5IS" '
And then:
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k $META -y $OUT
Bash interprets words in quotes as a single argument. Try
ALBUM='album="Peregrinações Alheias"'
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND \
-acodec libmp3lame -ab 128k -metadata "$ALBUM" -y $OUT
Put your command in an array instead.
ALBUM='album=Peregrinações Alheias'
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k -metadata "$ALBUM" -y $OUT
If you always want to set ALBUM, then Adam's answer is OK. But if you want to optionally set ALBUM then use this:
ALBUM="Peregrinações Alheias"
TITLE="Passeio ao PETAR"
OPTIONAL=
ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND \
-acodec libmp3lame -ab 128k \
${ALBUM:+-metadata album="$ALBUM"} \
${TITLE:+-metadata title="$TITLE"} \
${OPTIONAL:+-metadata optional="$OPTIONAL"} \
-y $OUT
When not setting ALBUM the complete ${var:+subst} block is omitted. Other vars are just the same of course-
Of course this scales up to several -metadata options if there is a fixed set of data you want to set.
Using eval can do what you want... Depending on what you have in $R_IMG, $SOUND and $OUT, they may need double-quote escaping, eg. \"$SOUND\" ....
Your $META (which I assume is another name for youur originally named $ALBUM) doesn't need to be laid out like this, but it surely helps (me) ... Just spaces, as in your original works just as well.
META='
-metadata album="Peregrinações"
-metadata title="Passeio ao PETAR"
-metadata author="Rogério Madureira"
-metadata date="2012"
-metadata description="Áudio de um passeio ao PETAR"
-metadata comment="Áudio capturado com TACAM DR-07MKII e Foto capturada com Canon PowerShot S5IS"
'; META="$(echo "$META" |sed 's|"|\\\\"|g' |tr '\n' ' ')"
eval "ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k $META -y $OUT"
If you prefer to not use the sed conversion line, you simply need to change each " in $META to \\" as in this next example:
META=' -metadata album=\\"Peregrinações\\" -metadata title=\\"Passeio ao PETAR\\" -metadata author=\\"Rogério Madureira\\" -metadata date=\\"2012\\" -metadata description=\\"Áudio de um passeio ao PETAR\\" -metadata comment=\\"Áudio capturado com TACAM DR-07MKII e Foto capturada com Canon PowerShot S5IS" '
eval "ffmpeg -i $R_IMG -r 1 -b 1800 -i $SOUND -acodec libmp3lame -ab 128k $META -y $OUT"
I've tested it successfully with the following ffmpeg encoding parameters:
eval "ffmpeg -i ~/input.flv -sameq -acodec libmp3lame -ab 128k $META -y ~/output.mp3"

Resources