This repository has been archived by the owner on Aug 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
entrypoint
executable file
·88 lines (79 loc) · 3.23 KB
/
entrypoint
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
#!/bin/sh
set -e
log() {
>&2 echo "${@}"
}
cancel() {
log "Error: ${@}"
return 1
}
find_language() {
allowed_languages="${1}"
input_file="${2}"
[ "${input_file}" ] || cancel "Missing input file."
ffprobe_output=$(ffprobe -loglevel level+error -show_entries stream=index:stream_tags=language -select_streams a -of compact=p=0:nk=1 "${input_file}") \
|| { return_code="$?"; log "${ffprobe_output}"; return "${return_code}"; }
available_languages=$(printf "${ffprobe_output}" | cut -d '|' -f 2 | xargs | tr ' ' ',')
for allowed_language in $(echo "${allowed_languages}" | tr ',' '\n'); do
for available_language in $(echo "${available_languages}" | tr ',' '\n'); do
if [ "${available_language}" = "${allowed_language}" ]; then
echo "${available_language}"
return 0
fi
done
done
[ "${allowed_languages}" ] && log "None of the requested languages [${allowed_languages}] are available."
cancel "Please provide at least one of the available languages: [${available_languages}]"
}
input_file="${1}"
output_file="${2}"
language=$(find_language "${AUDIO_LANGUAGES}" "${input_file}")
#
# first ffmpeg call: retain only
# - the first video and
# - all streams (video, audio, subtitles, whatever) that match the language,
# then create a MKV container and hand over to the second ffmpeg,
# suppressing statistics (so that only statistics of the second call are shown)
#
# second ffmpeg call:
# - configure vaapi to use hardware de- & encoding
# decoding:
# * '-hwaccel vaapi': use vaapi to decode input in hardware instead of software
# * '-hwaccel_device foo' use device 'foo' for decoding
# * '-hwaccel_output_format vaapi': keep decoded data in hardware (vaapi) format
# encoding:
# * 'format=nv12|vaapi,hwupload':
# accept either hardware (vaapi) format or software (nv12) as input formats for encoding.
# If 'vaapi': 'hwupload' is a null transformation.
# If 'nv12': 'hwupload' converts data to 'vaapi'.
# * '-filter_hw_device foo' and 'scale_vaapi=w=$VIDEO_WIDTH:h=-1': use hardware encoder to scale
# - take input from stdin
# - pick only the first video stream and the first audio stream, discard all other streams
# - scale to $VIDEO_WIDTH width and appropriate height keeping aspect ratio
# - limit video bitrate
# - set audio format to stereo $AUDIO_CODEC with audio bitrate
# - remove all audio metadata and set audio language
#
nice ffmpeg -hide_banner \
-nostats \
-i "${input_file}" \
-map 0:v -map "0:m:language:${language}" \
-c copy \
-f matroska - \
| nice ffmpeg \
-hide_banner \
-init_hw_device "vaapi=foo:${VAAPI_DEVICE}" \
-hwaccel vaapi \
-hwaccel_device foo \
-hwaccel_output_format vaapi \
-filter_hw_device foo \
-i - \
-map 0:v:0 -map 0:a:0 \
-map_metadata:s:a -1 -metadata:s:a "language=${language}" \
-vf "format=nv12|vaapi,hwupload,scale_vaapi=w=${VIDEO_WIDTH}:h=-1" \
-c:v "$VIDEO_CODEC" \
-b:v "$VIDEO_BITRATE" \
-c:a "$AUDIO_CODEC" \
-b:a "$AUDIO_BITRATE" \
-ac "$AUDIO_CHANNELS" \
"${output_file}"