-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsplit-media-file.sh
More file actions
executable file
·113 lines (101 loc) · 2.35 KB
/
Copy pathsplit-media-file.sh
File metadata and controls
executable file
·113 lines (101 loc) · 2.35 KB
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
#!/usr/bin/env bash
# Split a video/audio file into many based on a separate timestamps list.
#
# Usage: ./split-media-file.sh input.webm timestamps.txt
#
# The timestamps file should have following format:
#
# 0:00 - Introduction
# 1:23 - Chapter 1
# 34:56 - Chapter 2
# 1:02:34 - The rest of the file
# [...]
#
# author: andreasl
print_help() {
cat <<'EOF'
Usage: split-media-file.sh [OPTIONS] <input-file> <timestamps-file>
Split a media file into multiple chapter files using timestamps.
Options:
-h, --help Show this help message and exit
Timestamps file format:
0:00 - Introduction
1:23 - Chapter 1
34:56 - Chapter 2
1:02:34 - The rest of the file
EOF
}
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
print_help
exit 0
fi
if [[ $# -ne 2 ]]; then
print_help >&2
exit 1
fi
input_file="$1"
timestamps_file="$2"
# Detect audio codec
codec=$(ffprobe \
-v error \
-select_streams a:0 \
-show_entries stream=codec_name \
-of default=noprint_wrappers=1:nokey=1 \
"$input_file")
# Map codec to container/extension
case "$codec" in
opus)
out_ext="opus"
out_fmt="opus"
;;
aac)
out_ext="m4a"
out_fmt="ipod"
;;
mp3)
out_ext="mp3"
out_fmt="mp3"
;;
vorbis)
out_ext="ogg"
out_fmt="ogg"
;;
*)
out_ext="audio"
out_fmt=""
;;
esac
lines=()
# the `-n` test keeps a final line that is not terminated by a newline
while IFS= read -r timestamps_line || [ -n "$timestamps_line" ]; do
lines+=("$timestamps_line")
done <"$timestamps_file"
for ((i = 0; i < ${#lines[@]}; i++)); do
printf -v num "%04d" $((i + 1))
line="${lines[i]}"
start_time="${line%% - *}"
title="${line#* - }"
# Check next line for end timestamp
if ((i + 1 < ${#lines[@]})); then
next_line="${lines[i + 1]}"
next_start_time="${next_line%% - *}"
ffmpeg \
-hide_banner \
-nostdin \
-i "$input_file" \
-ss "$start_time" \
-to "$next_start_time" \
-c copy \
-vn ${out_fmt:+-f "$out_fmt"} \
"${num}_${title}.${out_ext}"
else
ffmpeg \
-hide_banner \
-nostdin \
-i "$input_file" \
-ss "$start_time" \
-c copy \
-vn ${out_fmt:+-f "$out_fmt"} \
"${num}_${title}.${out_ext}"
fi
done