diff --git a/ffmpeg-cut-list.sh b/ffmpeg-cut-list.sh new file mode 100755 index 0000000..c91ff10 --- /dev/null +++ b/ffmpeg-cut-list.sh @@ -0,0 +1,13 @@ +#!/bin/bash +chanid=$1 +starttime=$2 +skip_or_cutlist=${3:-"cutlist"} +logdir="/mnt/lvraid5/ffmpeg-cut-list.d" +logfile="$logdir/user-job-${chanid}-${starttime}.log" + +if ! test -d $logdir; then + mkdir -p $logdir; +fi + +ionice -c 3 ffmpeg-cut-list0.sh $chanid $starttime $skip_or_cutlist 2>> $logfile >> $logfile + diff --git a/ffmpeg-cut-list0.sh b/ffmpeg-cut-list0.sh new file mode 100755 index 0000000..25b4ffd --- /dev/null +++ b/ffmpeg-cut-list0.sh @@ -0,0 +1,130 @@ +#!/bin/bash +set -e +set -x +chanid=$1 +starttime=$2 +skip_or_cutlist=$3 +if test "$skip_or_cutlist" = "cutlist" -o "$skip_or_cutlist" = "skiplist"; then + echo skip_or_cutlist set to ${skip_or_cutlist} by "\$3" +else + if test "$A1" = "cutlist" -o "$A1" = "skiplist"; then + skip_or_cutlist="$A1" + else + echo Setting skip_or_cutlist to cutlist + skip_or_cutlist="cutlist" + fi +fi +overwrite=${overwrite:-1} +updatedb=${updatedb:-1} + +# 1071_20190127040000.ts +function get_cut_list { + cmd="mythutil --quiet --get${skip_or_cutlist} --chanid $chanid --starttime $starttime | awk -v RS=': +' -v OFS=' ' '/^[0-9]/{gsub(/-/,\",\"); print \$1}'" + $debug $cmd +} +function ffmpeg_concat { + ## use solution from stackoverflow ffmpeg concat video and audio out of sync + ## this may be overkill and unneeded? + outsave_ffconcat="$1" + files=$(tail -n +2 "$outsave_ffconcat" | cut -d' ' -f 2) + for f in $files; do + outf=${workdir}/${f/.${ending}/_tmp.${ending}} + inf=${workdir}/$f + $ffmpeg -y -i "$inf" -map 0 -c:a ac3 -af apad -c:v copy -shortest -avoid_negative_ts make_zero -fflags +genpts "$outf" + if test $? -eq 0; then + mv "$outf" "$inf" + else + echo Error generating $outf. Halt + exit 10 + fi + done + $ffmpeg -y -f concat -safe 0 -i $outsave_ffconcat -codec copy -map 0 -metadata \"service_name=$0\" $outfile +} + +framelist="$(get_cut_list)" +if test -z "$framelist"; then + echo Empty frame list with skip_or_cutlist=$skip_or_cutlist. Stop. + exit 0 +else + echo Frame list: $framelist. +fi +framelist0=${framelist:0:1} +if test "0" = "$framelist0"; then + inclbeginning=1 + framelist=${framelist:2} +else + inclbeginning=0 +fi +echo Cutting every other window beginning with $((1-inclbeginning)). +echo Frame list: $framelist + +if ! test -d $workdir; then + mkdir $workdir + chmod 1777 $workdir +fi +fileroot="${chanid}_${starttime}" +# should get infile from recorded.basename in db +infile=$(ls ${recordingsdir}/${fileroot}.{mpg,ts,mkv,mp4} 2>/dev/null | sort -u | head -n 1) +out_ffconcat="${workdir}/${fileroot}.ffconcat" +outsave_ffconcat="${workdir}/${fileroot}-save.ffconcat" +ending=$(echo "$infile" | awk -v FS='.' '{print $NF}') +outfile_tmp="${workdir}/${fileroot}_%05d.${ending}" +outfile="${workdir}/${fileroot}.${ending}" + +if test -z "$infile"; then + echo Did not find input file. Stop. + exit 8 +fi +if ! test -r "$infile"; then + echo File "$infile" is not readable. Stop. + exit 8 +fi +if test -z "$ending"; then + echo Did not find file ending. Stop. + exit 9 +fi + +## https://superuser.com/questions/710008/how-to-get-rid-of-ffmpeg-pts-has-no-value-error/ +ffmpegcut="$ffmpeg -fflags '+genpts' -ignore_unknown -y -i \"$infile\" -codec copy -map 0 -map -0:d -f segment -segment_list \"$out_ffconcat\" -segment_frames \"$framelist\" \"${outfile_tmp}\"" +echo $ffmpegcut +eval $ffmpegcut + +if test $? -ne 0; then + echo "Error in ffmpeg command. Halt." + exit 2 +fi +match="1{p};" +n=$(cat $out_ffconcat | wc -l) +for((i=$((inclbeginning+2));i<$n;i=i+2)); do + match="${match}$i{p};" +done +echo $match +sed -n -e "${match}" $out_ffconcat > $outsave_ffconcat +if ! test -r $outsave_ffconcat; then + echo File $outsave_ffconcat not created. Halt. + exit 3 +fi +nlines=$(wc -l $outsave_ffconcat | cut -d' ' -f 1) +if test "x$nlines" = "x2"; then + mv $workdir/$(tail -n 1 $outsave_ffconcat | cut -d' ' -f 2) $outfile +else + ffmpeg_concat "$outsave_ffconcat" +fi + +if test $? -ne 0; then + echo Concat failed. Halt. + exit 4 +else + touch --reference="$infile" "$outfile" + if test $overwrite -ne 0; then + mv $outfile $destdir/. + # only update the db if we overwrite the recording + if test $updatedb -ne 0; then + myth-rebuild-seektable.sh $chanid $starttime $workdir + fi + fi +fi +exit 0 + +## (export path=/var/lib/mythtv/recordings/; export file=1031_20181128070100.ts; /usr/local/bin/ffmpeg -y -i ${path}/${file} -f lavfi -i movie=${path}/${file}[out0+subcc] -preset slow -crf 21 -map 0:a -map 1 -map_metadata 1:s:0 -metadata:s:s "language=fre" ${file/.ts/1.mkv}) +##