-
Notifications
You must be signed in to change notification settings - Fork 2
/
dump-streams
executable file
·153 lines (135 loc) · 4.13 KB
/
dump-streams
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
#!/bin/bash
# SPDX-FileCopyrightText: 2021 - 2023 sudorook <daemon@nullcodon.com>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
set -euo pipefail
ROOT="$(dirname "${0}")"
source "${ROOT}"/globals
! check_command ffmpeg ffprobe sed && exit 3
function get_stream_count {
ffprobe -analyzeduration 1G -probesize 1G -v error -show_format file:"${1}" |
sed -n "s/nb_streams=\([0-9]\+\)/\1/p" 2> /dev/null
}
function pick_container {
local format
local format_name
local container_type
format="$(ffprobe -analyzeduration 1G -probesize 1G -v error -show_format file:"${1}")"
format_name="$(echo "${format}" | sed -n "s/^format_name=\(.*\)/\1/p")"
if [[ "${format_name}" =~ matroska ]]; then
container_type=mkv
elif [[ "${format_name}" =~ mp4 ]]; then
container_type=mp4
else
container_type=avi
fi
echo "${container_type}"
}
function dump_stream {
local info
local codec_name
local codec_type
local container
local font_file
local in
in="$(basename "${1}")"
local name=${in%.*}
local idx="${2}"
local out
local cmd="ffmpeg -analyzeduration 1G -probesize 1G -v warning"
info="$(ffprobe -analyzeduration 1G -probesize 1G -v error -show_entries stream -select_streams "${idx}" file:"${1}")"
codec_name="$(echo "${info}" | sed -n "s/^codec_name=\(.*\)/\1/p")"
codec_type="$(echo "${info}" | sed -n "s/^codec_type=\(.*\)/\1/p")"
case "${codec_type}" in
video)
container="$(pick_container "${1}")"
out="${name}_${idx}.${container}"
cmd="${cmd} -i file:${1@Q} -map 0:${idx} -c copy file:${out@Q} -y"
show_listitem "${cmd}"
eval "${cmd}"
return
;;
subtitle)
cmd="${cmd} -i file:${1@Q} -map 0:${idx}"
case "${codec_name}" in
ass)
out="${name}_${idx}.ass"
cmd="${cmd} -c copy file:${out@Q} -y"
;;
dvd_subtitle)
container="$(pick_container "${1}")"
if [[ "${container}" = mp4 ]]; then
out="${name}_${idx}.mp4"
else
out="${name}_${idx}.mkv"
fi
cmd="${cmd} -c copy file:${out@Q} -y"
;;
mov_text | srt | subrip)
out="${name}_${idx}.srt"
cmd="${cmd} -c subrip file:${out@Q} -y"
;;
hdmv_pgs_subtitle)
out="${name}_${idx}.sup"
cmd="${cmd} -c copy file:${out@Q} -y"
;;
*)
show_warning "Format ${codec_name@Q} not supported. Skipping."
return
;;
esac
show_listitem "${cmd}"
eval "${cmd}"
return
;;
audio)
out="${name}_${idx}.${codec_name}"
cmd="${cmd} -i file:${1@Q} -map 0:${idx} -c copy file:${out@Q} -y"
show_listitem "${cmd}"
eval "${cmd}"
return
;;
attachment)
if [[ "${codec_name}" =~ ^[o|t]tf ]]; then
mkdir -p "${name}_fonts"
font_file="$(echo "${info}" | sed -n "s/^TAG:filename=\(.*\)/\1/p")"
cmd="${cmd} -dump_attachment:${idx} \"\" -i file:${1@Q} -y"
show_listitem "${cmd}"
eval "${cmd}" || true # FIXME: override return false for attachments
mv "${font_file}" "${name}_fonts"
fi
return
;;
esac
}
#
# Main
#
if [ ${#} -eq 0 ]; then
show_error "ERROR: No input given. Exiting."
exit 3
fi
if [ ${#} -gt 1 ]; then
show_warning "WARNING: skipping inputs ${*:2}."
fi
if ! [ -f "${1}" ]; then
show_error "ERROR: invalid input ${1@Q}. Exiting."
exit 3
fi
STREAM_N="$(get_stream_count "${1}")"
for i in $(seq 1 "${STREAM_N}"); do
dump_stream "${1}" "$((i - 1))"
done