render script for chunked recordings v1: it's slow, but it works
This commit is contained in:
		
							parent
							
								
									b89fbc61c8
								
							
						
					
					
						commit
						566d1807fe
					
				| 
						 | 
					@ -0,0 +1,135 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env bash
 | 
				
			||||||
 | 
					set -euxo pipefail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This script requires you to have ffmpeg and fzf installed.
 | 
				
			||||||
 | 
					which ffmpeg >/dev/null || (echo "Please install ffmpeg" ; exit 1)
 | 
				
			||||||
 | 
					which fzf >/dev/null || (echo "Please install fzf" ; exit 1)
 | 
				
			||||||
 | 
					which mpv >/dev/null || (echo "Please install mpv" ; exit 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INTROS_PATH="/Users/j/dhcp24_voc_files/intros"
 | 
				
			||||||
 | 
					OUTROS_PATH="/Users/j/dhcp24_voc_files/outros"
 | 
				
			||||||
 | 
					CHUNKS_PATH="/Users/j/voc_obs/obs_record"
 | 
				
			||||||
 | 
					OUTPUT_PATH="/Users/j/voc_obs/obs_record/rendered"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Select the appropriate files
 | 
				
			||||||
 | 
					SELECTED_INTRO="$(find  "$INTROS_PATH" -type f | sort --reverse --human-numeric-sort | fzf --delimiter / --with-nth -1 --prompt "Intro File:")"
 | 
				
			||||||
 | 
					SELECTED_OUTRO="$(find  "$OUTROS_PATH" -type f | sort --reverse --human-numeric-sort | fzf --delimiter / --with-nth -1 --prompt "Outro File:")"
 | 
				
			||||||
 | 
					SELECTED_CHUNKS="$(find "$CHUNKS_PATH" -type f | sort --reverse | fzf --delimiter / --with-nth -1 -m --prompt "Video Chunks (use tab to select multiple):" | sort )"
 | 
				
			||||||
 | 
					readarray -t CHUNKS_ARRAY < <(echo "$SELECTED_CHUNKS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# find the start-offset for the first chunk
 | 
				
			||||||
 | 
					read -p "Do you want to play the first chunk ${CHUNKS_ARRAY[0]} to find the start-offset? (y/n) [n]: " PLAY_FIRST_CHUNK
 | 
				
			||||||
 | 
					PLAY_FIRST_CHUNK="${PLAY_FIRST_CHUNK:-n}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[ "$PLAY_FIRST_CHUNK" == "y" ]] && mpv "${CHUNKS_ARRAY[0]}" --osd-level=3 --osd-status-msg='${=time-pos}' --really-quiet
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					read -p "Enter the start-offset in seconds for the first chunk ${CHUNKS_ARRAY[0]} [0]: " START_OFFSET
 | 
				
			||||||
 | 
					START_OFFSET="${START_OFFSET:-0}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# find the end-offset for the last chunk
 | 
				
			||||||
 | 
					read -p "Do you want to play the last chunk ${CHUNKS_ARRAY[-1]} to find the end-offset? (y/n) [n]: " PLAY_LAST_CHUNK
 | 
				
			||||||
 | 
					PLAY_LAST_CHUNK="${PLAY_LAST_CHUNK:-n}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[ "$PLAY_LAST_CHUNK" == "y" ]] && mpv "${CHUNKS_ARRAY[-1]}" --osd-level=3 --osd-status-msg='${=time-pos}' --really-quiet
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					read -p "Enter the end-offset in seconds for the last chunk ${CHUNKS_ARRAY[0]} [1]: " END_OFFSET
 | 
				
			||||||
 | 
					END_OFFSET="${END_OFFSET:-1}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cat <<EOT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					I will be rendering with the following configuration:
 | 
				
			||||||
 | 
					    + Selected Intro: ${SELECTED_INTRO}
 | 
				
			||||||
 | 
					    + Selected Outro: ${SELECTED_OUTRO}
 | 
				
			||||||
 | 
					    + Video Chunks:
 | 
				
			||||||
 | 
					        + First chunk: ${CHUNKS_ARRAY[0]}
 | 
				
			||||||
 | 
					          Starting at second ${START_OFFSET}
 | 
				
			||||||
 | 
					        + Last chunk: ${CHUNKS_ARRAY[-1]}
 | 
				
			||||||
 | 
					          Ending at second ${END_OFFSET}
 | 
				
			||||||
 | 
					        + All chunks:
 | 
				
			||||||
 | 
					EOT
 | 
				
			||||||
 | 
					for index in "${!CHUNKS_ARRAY[@]}"
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
					    echo "            + $index: ${CHUNKS_ARRAY[index]}"
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					echo ; echo ; echo
 | 
				
			||||||
 | 
					read -p "Do you want to proceed with this configuration? (y/n) [y]" PROCEED
 | 
				
			||||||
 | 
					PROCEED="${PROCEED:-y}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[ "$PROCEED" == "y" ]] || (echo "aborting"; exit 1)
 | 
				
			||||||
 | 
					echo "doing ffmpeg things here"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ARRAY_LENGTH="${#CHUNKS_ARRAY[@]}"
 | 
				
			||||||
 | 
					if [[ ${ARRAY_LENGTH} -lt 2 ]]
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
					    echo "Too few chunks, this script can't handle this yet. Please do that on your own."
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					#ffmpeg -i "$SELECTED_INTRO" \
 | 
				
			||||||
 | 
					#       -i "$SELECTED_OUTRO" \
 | 
				
			||||||
 | 
					#    -ss "$START_OFFSET" -i "${CHUNKS_ARRAY[0]}" \
 | 
				
			||||||
 | 
					echo    "${CHUNKS_ARRAY[@]:1:-2}"
 | 
				
			||||||
 | 
					#    -t "$END_OFFSET" -i "${CHUNKS_ARRAY[-1]}" \
 | 
				
			||||||
 | 
					# STEP 1
 | 
				
			||||||
 | 
					# temp dir
 | 
				
			||||||
 | 
					WORKDIR=$(mktemp -d)
 | 
				
			||||||
 | 
					# STEP 2
 | 
				
			||||||
 | 
					# introfile with first chunk and crossfade encode
 | 
				
			||||||
 | 
					ffmpeg -i "$SELECTED_INTRO" -ss "$START_OFFSET" -i "${CHUNKS_ARRAY[0]}" \
 | 
				
			||||||
 | 
					-filter_complex \
 | 
				
			||||||
 | 
					"[1:v:0]fade=t=in:st=0:d=0.2[x];
 | 
				
			||||||
 | 
					 [1:a:0]afade=t=in:st=0:d=0.2[a];
 | 
				
			||||||
 | 
					 [0:v:0][0:a:0]
 | 
				
			||||||
 | 
					 [x][a]
 | 
				
			||||||
 | 
					 concat=n=2:v=1:a=1
 | 
				
			||||||
 | 
					 [v0][a0]" \
 | 
				
			||||||
 | 
					-map '[v0]' -map '[a0]' \
 | 
				
			||||||
 | 
					-c:a aac -b:a 192k \
 | 
				
			||||||
 | 
					-c:v libx264 -threads 0 -pix_fmt yuv420p -crf 18 -profile:v high -level 4.1 -disposition default \
 | 
				
			||||||
 | 
					-metadata:s:a:0 language=native \
 | 
				
			||||||
 | 
					"${WORKDIR}/introcombined.mkv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# STEP 3
 | 
				
			||||||
 | 
					# outrofile with last chunk and corssface encode
 | 
				
			||||||
 | 
					ffmpeg -i "$SELECTED_OUTRO" -t "$END_OFFSET" -i "${CHUNKS_ARRAY[-1]}" \
 | 
				
			||||||
 | 
					-filter_complex \
 | 
				
			||||||
 | 
					"[1:v:0]fade=t=out:st=$(($END_OFFSET - 1)):d=1.0[x];
 | 
				
			||||||
 | 
					 [1:a:0]afade=t=out:st=$(($END_OFFSET - 1)):d=1.0[a];
 | 
				
			||||||
 | 
					 [x][a]
 | 
				
			||||||
 | 
					 [0:v:0][0:a:0]
 | 
				
			||||||
 | 
					 concat=n=2:v=1:a=1
 | 
				
			||||||
 | 
					 [v0][a0]" \
 | 
				
			||||||
 | 
					-map '[v0]' -map '[a0]' \
 | 
				
			||||||
 | 
					-c:a aac -b:a 192k \
 | 
				
			||||||
 | 
					-c:v libx264 -threads 0 -pix_fmt yuv420p -crf 18 -profile:v high -level 4.1 -disposition default \
 | 
				
			||||||
 | 
					-metadata:s:a:0 language=native \
 | 
				
			||||||
 | 
					"${WORKDIR}/outrocombined.mkv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# STEP 4
 | 
				
			||||||
 | 
					# encoded intro+outro and all chunks in between with c:v copy and audio dynnorm + encode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FFMPEG_CHUNKS=""
 | 
				
			||||||
 | 
					FFMPEG_CONCAT=""
 | 
				
			||||||
 | 
					if [[ ${ARRAY_LENGTH} -gt 2 ]]
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
					    for index in $(seq 1 $(( ${ARRAY_LENGTH} - 2 )) )
 | 
				
			||||||
 | 
					    do
 | 
				
			||||||
 | 
					        FFMPEG_CHUNKS="${FFMPEG_CHUNKS} -i ${CHUNKS_ARRAY[index]}"
 | 
				
			||||||
 | 
					        FFMPEG_CONCAT="${FFMPEG_CONCAT} [$((index + 1)):v:0][$((index + 1)):a:0]"
 | 
				
			||||||
 | 
					    done
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ffmpeg -i "${WORKDIR}/introcombined.mkv" -i "${WORKDIR}/outrocombined.mkv" \
 | 
				
			||||||
 | 
					    $FFMPEG_CHUNKS -filter_complex \
 | 
				
			||||||
 | 
					    "[0:v:0][0:a:0]
 | 
				
			||||||
 | 
					    $FFMPEG_CONCAT
 | 
				
			||||||
 | 
					    [1:v:0][1:a:0]
 | 
				
			||||||
 | 
					    concat=n=${ARRAY_LENGTH}:v=1:a=1
 | 
				
			||||||
 | 
					    [v][a];[a]dynaudnorm[ad]" \
 | 
				
			||||||
 | 
					    -map '[v]' -map '[ad]' \
 | 
				
			||||||
 | 
					    -c:v libx264 -threads 0 -pix_fmt yuv420p -crf 18 -profile:v high -level 4.1 -disposition default \
 | 
				
			||||||
 | 
					    -c:a aac -b:a 192k \
 | 
				
			||||||
 | 
					    -metadata:s:a:0 language=native \
 | 
				
			||||||
 | 
					    "${OUTPUT_PATH}/combinedrender.mkv"
 | 
				
			||||||
		Loading…
	
		Reference in New Issue