blob: bf8b60881035cb3cab612816fc0c96fe5aacce39 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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
|