Inserting variables as command arguments in a bash script - bash

I have a file for screencasting on linux, and I want to modify parts of it based on user input. At the moment I can't even get it to stick an argument in a command from a variable.
#!/bin/bash -x
fps="30"
capturesize="hd1080"
outputsize="720"
filter=-vf 'scale=${outputsize}'
avconv \
-f x11grab -r $fps -s $capturesize -i :0.0 \
-f alsa -ac 2 -i pulse \
-f alsa -ac 2 -i pulse \
-f alsa -ac 1 -i pulse \
-map 0:0 -map 1:0 -map 2:0 -map 3:0 \
-vcodec libx264 \
$filter \
-pre:v lossless_ultrafast \
-acodec libmp3lame \
-threads 4 \
-y $#
$fps and $capturesize are evaluated properly but $filter assignment gives a nice little:
+ filter=-vf
+ 'scale=${outputsize}'
~/bin/screencap: line 9: scale=${outputsize}: command not found
Changing the line to:
filter="-vf 'scale=$outputsize'"
Gives an even less pleasant:
+ filter='-vf '\''scale=720'\'''
+ avconv -f x11grab [...] -vf ''\''scale=720'\''' [...]
[...]
No such filter: 'scale=720'
Error opening filters!

Use an array. It has the added benefit of protecting items that contain spaces, something
you can't do if you try to store it in a space-separated list.
#!/bin/bash -x
fps="30"
capturesize="hd1080"
outputsize="720"
filter=( -vf "scale=${outputsize}" )
avconv \
-f x11grab -r "$fps" -s "$capturesize" -i :0.0 \
-f alsa -ac 2 -i pulse \
-f alsa -ac 2 -i pulse \
-f alsa -ac 1 -i pulse \
-map 0:0 -map 1:0 -map 2:0 -map 3:0 \
-vcodec libx264 \
"${filter[#]}" \
-pre:v lossless_ultrafast \
-acodec libmp3lame \
-threads 4 \
-y "$#"
You can put all the options in a single array; a small example:
options=( -f x11grab -r "$fps" -s "$capturesize" )
options+=( -i :0.o )
# etc
avconv "${options[#]}" -y "$#"

filter="-vf scale=${outputsize}"

Related

Chaining multiple ffmpeg filters into one command [duplicate]

I can't get FFMPEG to accept any spaces when I try to assign it to the metadata. Below is the command I am using in Terminal on MacOS. It gives me an error: [NULL # 0x7fce76026600] Unable to find a suitable output format for 'World' World: Invalid argument
ffmpeg -hide_banner \
-i Trolls.World.Tour.2020.Bluray-2160p.m2ts \
-ss 00:10:00 -t 00:1:00 \
-pix_fmt yuv420p10le \
-map_chapters 0 \
-metadata:s:t:0 filename="" -metadata:s:t:0 mimetype="image/jpeg" \
-metadata title=“Trolls World Tour” \
-map 0:0 -metadata:s:v:0 language=eng -metadata:s:v:0 title=“Trolls World Tour” \
-map 0:2 -metadata:s:a:0 language=eng -metadata:s:a:0 title=“Dolby TrueHD 7.1 Atmos” \
-map 0:6 -metadata:s:a:0 language=eng -metadata:s:a:1 title=“AC-3 2.0” \
-c:v libx265 -preset slow -crf 16 \
-x265-params keyint=60:bframes=3:vbv-bufsize=75000:vbv-maxrate=75000:hdr-opt=1:repeat-headers=1:colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc:master-display="G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,500)" \
-c:a copy \
Trolls.World.Tour.2020.2160p.BluRay.REMUX.HEVC.TrueHD.7.1.Atmos.mkv
I have tried 'title="Trolls World Tour"' title=Trolls" "World" "Tour to no luck.
Using title="Trolls\ World\ Tour" works but then the title includes the backslashes.
Any thoughts?
Replace the “smart / fancy” quotes with "normal double quotes".
Bad: “ & ”
Good: "

Change ffmpeg input while streaming

Is there a way to change ffmpeg input while streaming to rtmp?
I have this bash script
#! /bin/bash
VBR="1500k"
FPS="24"
QUAL="superfast"
RTMP_URL="rtmp://live.live/live"
KEY="xxxxxxxxxxxxxxxxxxxxx"
VIDEO_SOURCE="video.mp4"
AUDIO_SOURCE="song.mp3"
NP_SOURCE="song.txt"
FONT="font.ttf"
ffmpeg \
-re -f lavfi -i "movie=filename=$VIDEO_SOURCE:loop=0, setpts=N/(FRAME_RATE*TB)" \
-thread_queue_size 512 -i "$AUDIO_SOURCE" \
-map 0:v:0 -map 1:a:0 \
-map_metadata:g 1:g \
-vf drawtext="fontsize=25: fontfile=$FONT: \
box=1: boxcolor=black#0.5: boxborderw=20: \
textfile=$NP_SOURCE: reload=1: fontcolor=white#0.8: x=50: y=50" \
-vcodec libx264 -pix_fmt yuv420p -preset $QUAL -r $FPS -g $(($FPS * 2)) -b:v $VBR \
-acodec libmp3lame -ar 44100 -threads 6 -qscale:v 3 -b:a 320000 -bufsize 512k \
-f flv "$RTMP_URL/$KEY"
What i want to do is to be able to change VIDEO_SOURCE on the fly, i was thinking if it's possible to make the input a directory then change the video in that directory on the fly, i'm new to dealing with scripts so i don't know how to do that
This is a complete guess, based on what little I know about how ffmpeg handles interactive input:
while :; do
ffmpeg \
-re -f lavfi -i "movie=filename=$VIDEO_SOURCE:loop=0, setpts=N/(FRAME_RATE*TB)" \
-thread_queue_size 512 -i "$AUDIO_SOURCE" \
-map 0:v:0 -map 1:a:0 \
-map_metadata:g 1:g \
-vf drawtext="fontsize=25: fontfile=$FONT: \
box=1: boxcolor=black#0.5: boxborderw=20: \
textfile=$NP_SOURCE: reload=1: fontcolor=white#0.8: x=50: y=50" \
-vcodec libx264 -pix_fmt yuv420p -preset $QUAL -r $FPS -g $(($FPS * 2)) -b:v $VBR \
-acodec libmp3lame -ar 44100 -threads 6 -qscale:v 3 -b:a 320000 -bufsize 512k \
-f flv "$RTMP_URL/$KEY"
read -p "Next movie?" VIDEO_SOURCE
[ "$VIDEO_SOURCE" = q ] && break
done
ffmpeg should(?) exit if you send q to standard input. Your script will then prompt you for a new value for VIDEO_SOURCE. If you type q again, the loop exits. Otherwise, it restarts ffmpeg with the new video source file.
If this works, you can perhaps adapt it for something closer to your needs.

ffmpeg no audio after filter_complex

Could someone help with the disappeared audio?
video_2.mp4 logo3.mp4 - has audio
ffmpeg -i video_2.mp4 -i logo3.mp4 -filter_complex \
"color=black:s=1920x1080:d=24 \
,format=yuv444p \
,geq='lum=X*255/W: \
cr=128: \
cb=128' \
[alpha]; \
[0:v]scale=1920x1080, setsar=1[0v]; \
[1:v]scale=1920x1080, setpts=PTS-STARTPTS+10/TB, setsar=1[1v]; \
[1v][alpha]alphamerge[1v]; \
[0v][1v]overlay=enable='between(t\,11,14)',format=yuv420p [v]" -map "[v]" -map 1:a \
-an out.mp4
In -map 1:a -an, the -an negates the mapping. Remove it.

How do I formate spaces in terminal for FFMPEG metadata

I can't get FFMPEG to accept any spaces when I try to assign it to the metadata. Below is the command I am using in Terminal on MacOS. It gives me an error: [NULL # 0x7fce76026600] Unable to find a suitable output format for 'World' World: Invalid argument
ffmpeg -hide_banner \
-i Trolls.World.Tour.2020.Bluray-2160p.m2ts \
-ss 00:10:00 -t 00:1:00 \
-pix_fmt yuv420p10le \
-map_chapters 0 \
-metadata:s:t:0 filename="" -metadata:s:t:0 mimetype="image/jpeg" \
-metadata title=“Trolls World Tour” \
-map 0:0 -metadata:s:v:0 language=eng -metadata:s:v:0 title=“Trolls World Tour” \
-map 0:2 -metadata:s:a:0 language=eng -metadata:s:a:0 title=“Dolby TrueHD 7.1 Atmos” \
-map 0:6 -metadata:s:a:0 language=eng -metadata:s:a:1 title=“AC-3 2.0” \
-c:v libx265 -preset slow -crf 16 \
-x265-params keyint=60:bframes=3:vbv-bufsize=75000:vbv-maxrate=75000:hdr-opt=1:repeat-headers=1:colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc:master-display="G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,500)" \
-c:a copy \
Trolls.World.Tour.2020.2160p.BluRay.REMUX.HEVC.TrueHD.7.1.Atmos.mkv
I have tried 'title="Trolls World Tour"' title=Trolls" "World" "Tour to no luck.
Using title="Trolls\ World\ Tour" works but then the title includes the backslashes.
Any thoughts?
Replace the “smart / fancy” quotes with "normal double quotes".
Bad: “ & ”
Good: "

FFMpeg : Add audio stream via -filter_complex

In Reference to https://superuser.com/questions/833232/create-video-with-5-images-with-fadein-out-effect-in-ffmpeg
I have a bunch of images. and I want to make a video using these images.
Below is my code for FFMpeg. But the problem is how can I append an audio file to -filter_complex (with bitrate)
ffmpeg \
-loop 1 -i input0.png \
-loop 1 -i input1.png \
-loop 1 -i input2.png \
-loop 1 -i input3.png \
-loop 1 -i input4.png \
-filter_complex \
"[0:v]trim=duration=15,fade=t=out:st=14.5:d=0.5[v0]; \
[1:v]trim=duration=15,fade=t=in:st=0:d=0.5,fade=t=out:st=14.5:d=0.5[v1]; \
[2:v]trim=duration=15,fade=t=in:st=0:d=0.5,fade=t=out:st=14.5:d=0.5[v2]; \
[3:v]trim=duration=15,fade=t=in:st=0:d=0.5,fade=t=out:st=14.5:d=0.5[v3]; \
[4:v]trim=duration=15,fade=t=in:st=0:d=0.5,fade=t=out:st=14.5:d=0.5[v4]; \
[v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" out.mp4

Resources