improve the performance of making slide video using ffmpeg - linux

I have 10 images(1080x1920) and 2 video(1080x1920).
I want to merge all of them to make a final video using command:
INPUT_DATA=(_img1.jpg vid1.mp4 _img2.jpg vid2.mp4 _img3.jpg _img4.jpg _img5.jpg _img6.jpg _img7.jpg _img8.jpg _img9.jpg _img10.jpg)
IMAGE_TIME_SPAN=5
INPUT_DIR="input"
OUTPUT_DIR="output"
BACKGROUND_MUSIC="$INPUT_DIR/background.mp3"
OUTPUT_STEP1="$OUTPUT_DIR/tmp_video.mp4"
OUTPUT_STEP3="$OUTPUT_DIR/tmp_background.mp3"
OUTPUT_FILE="$OUTPUT_DIR/final.mp4"
SCALE_SIZE="1080x1920"
ffmpeg -y \
-f lavfi -t 1 -i anullsrc \
-i $INPUT_DIR/${INPUT_DATA[0]} \
-i $INPUT_DIR/${INPUT_DATA[1]} \
-i $INPUT_DIR/${INPUT_DATA[2]} \
-i $INPUT_DIR/${INPUT_DATA[3]} \
-i $INPUT_DIR/${INPUT_DATA[4]} \
-i $INPUT_DIR/${INPUT_DATA[5]} \
-i $INPUT_DIR/${INPUT_DATA[6]} \
-i $INPUT_DIR/${INPUT_DATA[7]} \
-i $INPUT_DIR/${INPUT_DATA[8]} \
-i $INPUT_DIR/${INPUT_DATA[9]} \
-i $INPUT_DIR/${INPUT_DATA[10]} \
-i $INPUT_DIR/${INPUT_DATA[11]} \
-filter_complex \
"[1:v]fade=t=in:st=0:d=4:alpha=1,zoompan=z='zoom+0.0009':d=25*$IMAGE_TIME_SPAN:s=$SCALE_SIZE[img1]; \
[2:v]fade=t=in:st=0:d=4:alpha=1,scale=$SCALE_SIZE[v1]; \
[3:v]fade=t=in:st=0:d=4:alpha=1,zoompan=z='zoom+0.0009':d=25*$IMAGE_TIME_SPAN:s=$SCALE_SIZE[img2]; \
[4:v]fade=t=in:st=0:d=4:alpha=1,scale=$SCALE_SIZE[v2]; \
[5:v]fade=t=in:st=0:d=4:alpha=1,zoompan=z='zoom+0.0009':d=25*$IMAGE_TIME_SPAN:s=$SCALE_SIZE[img3]; \
[6:v]fade=t=in:st=0:d=4:alpha=1,zoompan=z='zoom+0.0009':d=25*$IMAGE_TIME_SPAN:s=$SCALE_SIZE[img4]; \
[7:v]fade=t=in:st=0:d=4:alpha=1,zoompan=z='zoom+0.0009':d=25*$IMAGE_TIME_SPAN:s=$SCALE_SIZE[img5]; \
[8:v]fade=t=in:st=0:d=4:alpha=1,zoompan=z='zoom+0.0009':d=25*$IMAGE_TIME_SPAN:s=$SCALE_SIZE[img6]; \
[9:v]fade=t=in:st=0:d=4:alpha=1,zoompan=z='zoom+0.0009':d=25*$IMAGE_TIME_SPAN:s=$SCALE_SIZE[img7]; \
[10:v]fade=t=in:st=0:d=4:alpha=1,zoompan=z='zoom+0.0009':d=25*$IMAGE_TIME_SPAN:s=$SCALE_SIZE[img8]; \
[11:v]fade=t=in:st=0:d=4:alpha=1,zoompan=z='zoom+0.0009':d=25*$IMAGE_TIME_SPAN:s=$SCALE_SIZE[img9]; \
[12:v]fade=t=in:st=0:d=4:alpha=1,zoompan=z='zoom+0.0009':d=25*$IMAGE_TIME_SPAN:s=$SCALE_SIZE[img10]; \
[img1][0:a][v1][0:a][img2][0:a][v2][0:a][img3][0:a][img4][0:a][img5][0:a][img6][0:a][img7][0:a][img8][0:a][img9][0:a][img10][0:a]concat=n=12:v=1:a=1" \
-pix_fmt yuv420p -c:v libx264 \
$OUTPUT_STEP1
I run this command on a virtual machine (Linux, 4GB memories) and it takes ~11 min to finish! It takes too long and I want to reduce the process time to less than 5 min.
Any suggestion for the better performance.

Related

Curl bash script truncated/ merging

My aim is to have bash scripts get up to get a token from a WEB API and parse that token into a post command which will then create an new account (based on user input) on that WEB API. It succesffuly gets the token but when I reference the variable in my POST command, it either cuts it off or merges it into the tab. Has anyone seen this happen before?
I have read a similar issue where the issue was the content header, I have removed that but it hasnt fixed the issue.
A warning...I am a learner so my code isn't the best!
My bash script:
#!/bin/bash
curl --insecure -X POST \
https://192.168.XX.XXX:8443/application/token \
-H 'Accept: */*' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/xml' \
-H 'Host: 192.168.XX.XX:8443' \
-H 'cache-control: no-cache' \
-H 'client-key: 123' \
-H 'client-name: 1234' \
-H 'client-secret: 123456' \
-H 'grant_type: OAuth' \
-d '<request>
<username>johndoe</username>
<password>secret</password>
</request>' > tokenNewAcc.xml
grep 'access_token' tokenNewAcc.xml | sed 's/.*://' | sed s/,// | tr -d '"' > /home/oracle/tokenNewAcc.txt
rm tokenNewAcc.xml
value=`cat /home/oracle/tokenNewAcc.txt`
MYVAR=`cat /home/oracle/testaccounts.txt`
ID=`cut -d' ' -f1 /home/oracle/testaccounts.txt`
FNAME=`cut -d' ' -f2 /home/oracle/testaccounts.txt`
LNAME=`cut -d' ' -f3 /home/oracle/testaccounts.txt`
EMAIL=`cut -d' ' -f4 /home/oracle/testaccounts.txt`L
\
curl -k -X POST \
https://192.168.XX.XXX:8443/application/accounts \
-H 'Accept: */*' \
-H 'Content-Type: application/xml' \
-H 'Host: 192.168.XX.XXX:8443' \
-H "auth: "$value"" \
-H 'cache-control: no-cache' \
-d '<request>
<userid'$ID'</userid>
<firstname>'$FNAME'</firstname>
<lastname>'$LNAME'</lastname>
<email>'$EMAIL'</email>
</request>'
OUTPUT of POST where it has trouble:
curl -k -X POST https://192.168.36.XXX:8443/cloudminder/accounts -H 'Accept: */*' -H 'Content-Type: application/xml' -H 'Host: 192.168.36.1' -H 'cache-control: no-cache' -d '<request>ad9f23295b6
<useridconnectortest</userid>
<firstname>conn</firstname>
<lastname>connect</lastname>
<email>connectorL</email>
</request>'
As you can see, the host url is cut off, the beginning of the token (ad9f23295b6) merges into the request.

ffmpeg add music to video playing after video

I'm using ffmpeg to create slideshow of images.
I have to add music in the backgroup which will be played to the size of the slideshow (slicing audio if audio length is greater than video or repeating audio if audio length is shorter than video)
This is what my script is
ffmpeg -y \
-loop 1 -i in1.png \
-loop 1 -i in2.png \
-loop 1 -i in3.png \
-loop 1 -i in4.png \
-loop 1 -i in5.png \
-filter_complex \
"[0:v]trim=duration=6,fade=t=in:st=0:d=1,fade=t=out:st=5:d=1,setsar=1:1[v0]; \
[1:v]trim=duration=6,fade=t=in:st=0:d=1,fade=t=out:st=5:d=1,setsar=1:1[v1]; \
[2:v]trim=duration=6,fade=t=in:st=0:d=1,fade=t=out:st=5:d=1,setsar=1:1[v2]; \
[3:v]trim=duration=6,fade=t=in:st=0:d=1,fade=t=out:st=5:d=1,setsar=1:1[v3]; \
[4:v]trim=duration=6,fade=t=in:st=0:d=1,fade=t=out:st=5:d=1,setsar=1:1[v4]; \
[v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,setsar=1:1[v]" -i music.mp3 -shortest -map "[v]" -aspect 16:9 -r 24 shortSlideshow1234.mp4;
This generates output, but slideshow is silent and there is no music in the video.
You need to also map the audio:
ffmpeg -y \
-loop 1 -framerate 24 -i in1.png \
-loop 1 -framerate 24 -i in2.png \
-loop 1 -framerate 24 -i in3.png \
-loop 1 -framerate 24 -i in4.png \
-loop 1 -framerate 24 -i in5.png \
-i music.mp3 \
-filter_complex \
"[0:v]trim=duration=6,fade=t=in:st=0:d=1,fade=t=out:st=5:d=1,setsar=1[v0]; \
[1:v]trim=duration=6,fade=t=in:st=0:d=1,fade=t=out:st=5:d=1,setsar=1[v1]; \
[2:v]trim=duration=6,fade=t=in:st=0:d=1,fade=t=out:st=5:d=1,setsar=1[v2]; \
[3:v]trim=duration=6,fade=t=in:st=0:d=1,fade=t=out:st=5:d=1,setsar=1[v3]; \
[4:v]trim=duration=6,fade=t=in:st=0:d=1,fade=t=out:st=5:d=1,setsar=1[v4]; \
[v0][v1][v2][v3][v4]concat=n=5:v=1:a=0[v]" -map "[v]" -map 5:a shortSlideshow1234.mp4

Import file to script and fill variables inside the file

I have script import.sh
. properties
sql=$(cat sql.sql)
${psql_path}/psql \
-X \
--set ON_ERROR_STOP=on \
--set AUTOCOMMIT=on \
--echo-all \
${sql}
${dbname} > ${log_file} 2>> ${log_file}
and file properties
psql_path="/usr/pgsql-9.6/bin"
dbname="postgres"
path="/opt/files"
log_file="ok.log"
and file sql.sql
-c "truncate table SCHEMA.TABLE1;" \
-c "\\copy SCHEMA.TABLE1 FROM '${path}/TABLE1.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
-c "truncate table SCHEMA.TABLE2;" \
-c "\\copy SCHEMA.TABLE1 FROM '${path}/TABLE2.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
i need to run psql command with importing lines from file sql.sql on the line ${sql} in script import.sh but including text /opt/files instead of the variable itself ${path}, eg:
${psql_path}/psql \
-X \
--set ON_ERROR_STOP=on \
--set AUTOCOMMIT=on \
--echo-all \
-c "truncate table SCHEMA.TABLE1;" \
-c "\\copy SCHEMA.TABLE1 FROM '/opt/files/TABLE1.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
-c "truncate table SCHEMA.TABLE2;" \
-c "\\copy SCHEMA.TABLE2 FROM '/opt/files/TABLE2.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
${dbname} > ${log_file} 2>> ${log_file}
edit: all im getting right now is example below. How do i insert the text of variable ${path} ?
${psql_path}/psql \
-X \
--set ON_ERROR_STOP=on \
--set AUTOCOMMIT=on \
--echo-all \
-c "truncate table SCHEMA.TABLE1;" \
-c "\\copy SCHEMA.TABLE1 FROM '${path}/TABLE1.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
-c "truncate table SCHEMA.TABLE2;" \
-c "\\copy SCHEMA.TABLE2 FROM '${path}/TABLE2.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
${dbname} > ${log_file} 2>> ${log_file}
This line:
sql=$(cat sql.sql)
Will put contents of "sql.sql" into this variable $sql but won't evaluate any variables inside it. The right way to do this is to use a heredoc, instead. But since I figure out you want to keep your script, a simple solution would be:
sql=$(cat sql.sql | sed -e 's#${path}#'"${path}"'#')
This is simple running sed to substitute the contents of "${path}" into the contents of shell variable of the same name. But anyway consider using heredocs, because your "sql" file is obviously not SQL at all.
As advised, the HEREDOC is the best option and then simple parameter substitution can be done:
. properties
sql=$(cat sql.sql)
${psql_path}/psql <<-EOF
-X
--set ON_ERROR_STOP=on
--set AUTOCOMMIT=on
--echo-all
${sql//\$\{path\}/$path}
${dbname} > ${log_file} 2>> ${log_file}
EOF
Notice too that the line extensions are no longer required either. You should be able to remove them from sql.sql file as well

Improve avconv load and speed?

When I convert video through avconv it's take above 95% percentage, is there any way to reduce the converting time?
Try using -threads auto or push it to the number of cores / threads your CPU has.
Here is my full script
#!/bin/sh
infile=$1
tmpfile="$1-tmp.mp4"
outfile="$1-new.mp4"
options="-vcodec libx264 -b 512k -flags +loop+mv4 -cmp 256 \
-partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 \
-me_method hex -subq 7 -trellis 1 -refs 5 -bf 3 \
-flags2 +bpyramid+wpred+mixed_refs+dct8x8 -coder 1 -me_range 16 \
-g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10\
-qmax 51 -qdiff 4"
# Half size
options=$options" -vf scale=iw*0.5:-1"
# Copy audio
options=$options" -codec:a copy"
# Shut up
options=$options" -loglevel info "
# echo "Options : $options"
avconv -y -i "$infile" -threads auto $options "$outfile"
# avconv -y -i "$infile" -an -pass 1 -threads auto $options "$tmpfile"
# avconv -y -i "$infile" -acodec aac -strict experimental -ar 44100 -ab 96k -pass 2 -threads auto $options "$tmpfile"
# qt-faststart "$tmpfile" "$outfile"

RRDTool GPRINT formatting with printf

Closely related to this question: Bash printf prefix
I have the following Bash script that is generating an RRDGraph with RRDTool.
#!/bin/bash
now=$(date +%s)
now_formatted=$(date +%s | awk '{printf "%s\n", strftime("%c",$1)}' | sed -e 's/:/\\:/g')
# create power graph for last week
/usr/bin/rrdtool graph /var/www/power-week.png \
--start end-7d --width 543 --height 267 --end $now-1min --slope-mode \
--vertical-label "Watts" --lower-limit 0 \
--alt-autoscale-max \
--title "Power: Last week vs. week before" \
--watermark "(©) $(date +%Y) Alyn R. Tiedtke" \
--font WATERMARK:8 \
DEF:Power=/root/currentcost/ccdata.rrd:Power:AVERAGE \
DEF:Power2=/root/currentcost/ccdata.rrd:Power:AVERAGE:end=$now-7d1min:start=end-7d \
VDEF:Last=Power,LAST \
VDEF:First=Power,FIRST \
VDEF:Min=Power,MINIMUM \
VDEF:Peak=Power,MAXIMUM \
VDEF:Average=Power,AVERAGE \
CDEF:kWh=Power,1000,/,168,* \
CDEF:Cost=kWh,.1029,* \
SHIFT:Power2:604800 \
LINE1:Power2#00CF00FF:"Last Week\\n" \
HRULE:Min#58FAF4:"Min " \
GPRINT:Power:MIN:"%6.2lf%sW" \
COMMENT:"\\n" \
LINE1:Power#005199FF:"Power " \
AREA:Power#00519933:"" \
GPRINT:Last:"%6.2lf%sW" \
COMMENT:"\\n" \
HRULE:Average#9595FF:"Average" \
GPRINT:Power:AVERAGE:"%6.2lf%sW" \
COMMENT:"\\n" \
HRULE:Peak#ff0000:"Peak " \
GPRINT:Power:MAX:"%6.2lf%sW" \
COMMENT:"\\n" \
GPRINT:kWh:AVERAGE:" total %6.2lfkWh\\n" \
GPRINT:Cost:AVERAGE:" cost %6.2lf £\\n" \
GPRINT:Cost:AVERAGE:"$(printf \\" cost %11s\\" £%.2lf | sed 's/\£/\£ /g')\\n" \
COMMENT:" \\n" \
GPRINT:First:"Showing from %c\\n":strftime \
GPRINT:Last:" to %c\\n":strftime \
COMMENT:" Created at $now_formatted"
Which produces a graph like this (notice the leading \ on the lower cost line in the legend):-
Concentrating specifically on the following line:-
GPRINT:Cost:AVERAGE:"$(printf \\" cost %11s\\" £%.2lf | sed 's/\£/\£ /g')\\n" \
This is the line that is printing out the lower cost line in the legend.
I am passing a GPRINT formatted value of £4.54 to Bash's printf function to be padded out to 11 spaces and a cost label prefixed on it. I am then piping this to sed to add a space between the £ and the actual value.
What I want to know is, why is the escaped \ coming through in the output? If I remove the \\ just after printf bash complains that something is missing.
How would I suppress this \ from coming through in the output.
Try this line:
GPRINT:Cost:AVERAGE:"$(printf ' cost %11s' £%.2lf | sed 's/\£/\£ /g')\\n" \
I changed the inner " marks to ' marks and removed the backslashes.

Resources