ffmpeg.js filter command without quotes - ffmpeg

I want to use a filter in an ffmpeg version compiled for Javascript (ffmpeg.js). But the parser doesn't seem to handle quotes, so I need to write the full command without quotes.
How can I write the following command without quotes?
ffmpeg -i video.mp4 -i image.jpg -filter_complex "[1][0]scale2ref[i][v];[v][i]overlay=10:10:enable=\'between(t,1,2)\'" -c:a copy output.mp4
In javascript I specify the command as follows:
worker.postMessage({
type: 'command',
arguments: "-i video.mp4 -i image.jpg -filter_complex '[1][0]scale2ref[i][v];[v][i]overlay=10:10' -c:a copy output.mp4".split(' '),
files: [
{
data: new Uint8Array(videofile),
name: 'video.mp4'
},
{
data: new Uint8Array(imagefile),
name: 'image.jpg'
},
]
});
Which however results in:
[AVFilterGraph # 0xdf4c30] No such filter:
'[1][0]scale2ref[i][v];[v][i]overlay=10:10'
I checked and the overlay filter works in simpler version without quotes, for example this command works:
arguments: "-i video.mp4 -i image.jpg -filter_complex overlay=10:10 -c:a copy output.mp4".split(' '),

I think the problem is that the ' will still be around after the split which makes ffmpeg confused. If this was a real shell the argument parser would split and parse the quotes properly.
Try to remove the ' in the original string like this:
arguments: "-i video.mp4 -i image.jpg -filter_complex [1][0]scale2ref[i][v];[v][i]overlay=10:10 -c:a copy output.mp4".split(' ')
Or maybe even skip doing split and pass a list of arguments directly instead:
arguments: ["-i", "video.mp4", "-i", "image.jpg", "-filter_complex", "[1][0]scale2ref[i][v];[v][i]overlay=10:10", "-c:a", "copy", "output.mp4"]

Related

ffmpeg downloading parts of Youtube videos but for some of them they have a black screen for a few seconds

So im using ffmpeg to download some youtube videos with specific start and stop times. My code looks like os.system("ffmpeg -i $(youtube-dl --no-check-certificate -f 18 --get-url %s) -ss %s -to %s -c:v copy -c:a copy %s"% (l, y, z, w)) where the variables would all be the name of the file, the url, and the start and stop times. Some of the vidoes come out just fine, others have a black screen and only a portion of the video, and a very few amount have just audio files. My time is formated as x.y where x would be the seconds and y would be the milliseconds. Is this the issue so I need to transform it to 00:00:00.0 format? Any help is appreciated
os.system("ffmpeg -ss %s -i $(youtube-dl --no-check-certificate -f 18 --get-url %s) -t %s -c:v copy -c:a copy %s"% (l, y, z, w))
-ss start the video with 00:00:00.0000 format
-t the duration of scene in seconds
example if you want to extract a scene from second 30, and a duration of 3 seconds
os.system("ffmpeg -ss 00:00:30.0000 -i $(youtube-dl --no-check-certificate -f 18 --get-url %s) -t 3 -c:v copy -c:a copy %s"% (l, y, z, w))
Try this with Python :)
Add '-c:a', 'copy',to ffmpeg command line (part) helps out with the black picture / frames / screen in the video.
def ydl_info():
ydl_opts = {
'format': 'bestvideo[height<=720][tbr>1][filesize>0.05M]',
'outtmpl': '%(id)s.%(ext)s', # Template for output names.
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(
'https://www.youtube.com/watch?v=HZhWTjnIn78',
download=False # False for just extract the info
)
return info
def ffmpeg_cut():
info = ydl_info()
URL = info['formats'][-1]['url'] # media_url # If there are several media formats then to get media url for the last format:
START = args.start_time
END = '00:00:03.00'
OUTPUT = os.path.join(args.output, args.name+args.format)
print('Output:', OUTPUT)
#ffmpeg -ss 00:00:15.00 -i "OUTPUT-OF-FIRST URL" -t 00:00:10.00 -c copy out.mp4
#cmd = "ffmpeg -ss {} -i {} -t {} -c copy {}".format(START, URL, END, OUTPUT)
subprocess.call([
'ffmpeg',
'-i', URL,
'-ss', START,
'-t', END,
'-c:a', 'copy', OUTPUT, # '-c:v' copies only video and '-c:a' only audio
])
return None

How to drawtext colon with localtime in ffmpeg -filter_complex?

ffmpeg -i in.mp4 -filter_complex "drawtext='fontfile=font.ttf : text=%{localtime\:%Y/%m/%d %H%M%S} : fontsize=24 : fontcolor=white : x=10: y=10'" out.mp4
works.
ffmpeg -i in.mp4 -filter_complex "drawtext='fontfile=font.ttf : text=%{localtime\:%Y/%m/%d %H\:%M\:%S} : fontsize=24 : fontcolor=white : x=10: y=10'" out.mp4
returns
%{localtime} requires at most 1 arguments
error.
the only difference is \:
You can use:
%{localtime\:%Y/%m/%d %H\\\\\:%M\\\\\:%S}
It's ugly. See FFmpeg: Quoting & Escaping for some info.
On Windows with .bat file I have to escape it like:
%%{localtime\:%%Y/%%m/%%d %%H\\\:%%M\\\:%%S}

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"

ffmpeg live stream only outputting 240p

I am having trouble rescaling the resolution of a video with complex filters to 720p, adding the scale to reference the video seems to cause an error
ffmpeg -re -i "https://mnmedias.api.telequebec.tv/m3u8/29880.m3u8" -i
./public/images/ACE.png -i ./public/images/logo2.jpg -i
./public/images/crunchy.png -i ./public/images/red.jpg -filter_complex "
[0]scale=1280:720[ovrl0], [va][ovrl0][v0];[1]scale=40:40[ovrl1], [v0]
[ovrl1] overlay=580:10:enable='lt(mod(t,40),10)'[v1];[2]scale=40:40[ovrl2],
[v1][ovrl2] overlay=580:10:enable='between(mod(t,40),10,20)'[v2];
[3]scale=40:40[ovrl3], [v2][ovrl3]
overlay=580:10:enable='gt(mod(t,40),20)'[v3];[4]scale=40:40[ovrl4], [v3]
[ovrl4] overlay=580:10:enable='gt(mod(t,40),30)'" -acodec aac -vcodec
libx264 -f flv "rtmp://a.rtmp.youtube.com/live2/2222-2222-2222-2222"
error output is [AVFilterGraph # 0x7f964163e9a0] No such filter: ''
Your filtergraph is malformed:
, [va][ovrl0][v0] appears to be a typo and is not applied to any filter.
Your first scale filter is referencing [v0] but [v0] does not exist (other than the orphaned declaration in the typo).
, is use to join linear filters to create a filterchain. ; is used to separate distinct filterchains. You're using , instead of ; in some locations. See FFmpeg Filter Syntax.
I'm guessing you want something like:
-filter_complex \
"[0]scale=1280:720[ovrl0]; \
[1]scale=40:40[ovrl1]; \
[2]scale=40:40[ovrl2]; \
[3]scale=40:40[ovrl3]; \
[4]scale=40:40[ovrl4]; \
[ovrl0][ovrl1] overlay=580:10:enable='lt(mod(t,40),10)'[v1]; \
[v1][ovrl2] overlay=580:10:enable='between(mod(t,40),10,20)'[v2]; \
[v2][ovrl3] overlay=580:10:enable='gt(mod(t,40),20)'[v3]; \
[v3][ovrl4] overlay=580:10:enable='gt(mod(t,40),30)'"

Resources