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
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
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}
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));
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"
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)'"