diff options
Diffstat (limited to 'video/d8concat')
| -rwxr-xr-x | video/d8concat | 164 | 
1 files changed, 164 insertions, 0 deletions
diff --git a/video/d8concat b/video/d8concat new file mode 100755 index 0000000..bf8b608 --- /dev/null +++ b/video/d8concat @@ -0,0 +1,164 @@ +#!/bin/sh + +[ -d "$1" ] || exit 1  # Exit with error if not pointing to a directory + +# Misc +duration() { ffprobe -i "$1" -show_entries format=duration -v quiet -of csv="p=0" | tr -d . ; } +timebase="1/1000000"  # duration function gives microseconds + +safename() { echo "$1" | tr -d '<>:"/\|?*' ; } + +# Temp dirs +workdir="$(mktemp -d "${TMPDIR:-/tmp}/combinetapesworkdir.XXXXXX")" + +cleanup() { rm -rf "$workdir" ; } +trap cleanup EXIT INT HUP QUIT TERM ALRM USR1 + +# Loop vars +current_date=0 +duration_total=0 +chapter_start=0 +chapter_time=0 +last_chapter_concurrent=0 + +# TODO this relys on the for loop looping in order + +# Either can be ran on single dv containing directory, or many dv containing directories +for dir in "$1"/ "$1"/*/; do +	dir="${dir%/}"  # Remove trailing slash +	title="" + +	if [ "$dir" != "$1" ]; then +		title="$(basename "$dir")" +	fi +	if echo "$dir" | grep '/\*' >/dev/null; then +		break +	fi + +	for tape in "$dir"/*.dv; do +		date="$(echo "$(basename "$tape")" | grep -o '[0-9]*\.[0-9]*\.[0-9]*' | tr '.' '-')" +		time="$(echo "$(basename "$tape")" | grep -o '[0-9]*-[0-9]*-[0-9]*'   | tr '-' ':')" + +		if [ "$title$date" != "$current_date" ]; then +			# Reset vars +			current_date="$title$date" +			duration_total=0 +			chapter_start=0 +			chapter_time=0 +			last_chapter_concurrent=0 + +			# Create dirs +			date_dir="$workdir/$current_date" +			mkdir -p "$date_dir" + +			files="$date_dir/files" +			chapters="$date_dir/chapters" + +			# Init chapters file +			printf ";FFMETADATA1\n\n" > "$chapters" + +			# title file +			if [ "$title" ]; then +				echo "$title" > "$date_dir/title" +			fi +		fi + +		# Concat files +		echo "file '$(realpath "$tape" | sed "s/'/'\\\\''/g")'" >> "$files" + +		# Chapter marker +		tape_duration=$(duration "$tape" | grep -o "[1-9][0-9]*") +		duration_total=$(( $duration_total + $tape_duration )) + +		# Only insert chapter marker if recordings are not concurrent. dvgrab +		# splits files into 1gb chunks, or 291557933 microseconds of raw dv footage +		# (with digital 8) +		if [ $last_chapter_concurrent = 0 ]; then +			chapter_time=$time +		fi +		if [ $tape_duration = 291557933 ]; then +			last_chapter_concurrent=1 +			continue +		else +			last_chapter_concurrent=0 +		fi + +		echo "[CHAPTER]"                             >> "$chapters" +		echo "TIMEBASE=$timebase"                    >> "$chapters" +		echo "START=$chapter_start"                  >> "$chapters" +		echo "END=$duration_total"                   >> "$chapters" +		echo "title=Section starts at $chapter_time" >> "$chapters" +		echo                                         >> "$chapters" + +		chapter_start=$duration_total +	done +done + + +# ffmpeg combine +out_dir=export +default_title=Untitled +mkdir -p "$out_dir" + +for date_dir in "$workdir"/*; do +	date="$(echo "$date_dir" | grep -o "[0-9][0-9][0-9][0-9]-[0-9]*-[0-9]*")" +	origin_tape="$(basename "$1")" + +	# Files +	title="$date_dir/title" +	files="$date_dir/files" +	chapters="$date_dir/chapters" + +	# Nicely title +	if [ -e "$title" ]; then +		# title file +		output_title="$(cat "$title")" +	#elif echo "$origin_tape" | grep "^[^0-9].*[0-9]*-[0-9]*-[0-9]*" >/dev/null; then +	#	# Beginning descriptor +	#	output_title="$(echo "$origin_tape" | sed 's/ [0-9#].*//')" +	#elif echo "$origin_tape" | grep "$date [A-Z]" >/dev/null; then +	#	# Date range or list of dates with titles (Title must be capitalized, 'to' must be made lowercase +	#	output_title="$(echo "$origin_tape" | sed "s/.*$date //; s/ to [0-9].*//; s/;.*//")" +	else +		# default +		output_title=$default_title +	fi + +	output_title="$(echo "$output_title" | sed 's/\s*#[0-9]*$//')"  # Remove sequence numbers + +	# File name +	if [ "$output_title" = "$default_title" ]; then +		output_name="$date" +	else +		output_name="$date $output_title" +	fi + +	if [ -e "$out_dir/$output_name.mp4" ]; then +		output=$(ls "$out_dir" | grep "$output_name *[0-9]*.mp4" | while read -r file; do +			file_tape="$(mediainfo "$out_dir/$file" | sed -n 's/Comment.* - Origin tape: //p')" +			if [ "$origin_tape" = "$file_tape" ]; then +				echo 0 +				break +			fi +		done) +		if [ "$output" = 0 ]; then +			continue +		fi +		output_name="$output_name $(ls "$out_dir" | grep "$output_name *[0-9]*.mp4" | wc -l)" +	fi + +	# Convert +		#-c copy \ +		#-metadata "title=$output_title" \  # Dont set title since it will be stuck if file is renamed +	ffmpeg -hide_banner -nostdin \ +		-n \ +		-f concat -safe 0 -i "$files" \ +		-i "$chapters" -map_metadata 1 \ +		-c:v libx264 -crf 22 -preset medium -tune grain \ +		-vf yadif \ +		-c:a aac -b:a 320k \ +		-metadata "date=$date" \ +		-metadata "comment=tapes.tjkeller.xyz - Origin tape: $origin_tape" \ +		"$out_dir/$output_name.mp4" +		#"$out_dir/$output_name.mkv" +done  | 
