]> git.plutz.net Git - rawnet/blob - transcoding.sh
For progress frame use chunked encoding instead of long poll
[rawnet] / transcoding.sh
1 #!/bin/sh
2
3 . "${_EXEC}"/cgilite/storage.sh
4
5 transq="$_DATA/transcoding.queue"
6 tpid="$_DATA/transcoding.pid"
7
8 transcode(){
9   local file="$1"
10   if LOCK "$transq"; then
11     printf %s\\n "$file" >>"$transq"
12     RELEASE "$transq"
13   fi
14   ( exec >"$_DATA/debug" 2>&1; "$_EXEC/transcoding.sh" run & ) &
15 }
16
17 transcode_resolutions(){
18   local width="$1" height="$2"
19   resNative='' res1080='' res720='' res480='' res240=''
20
21   if [ $width -lt 426 -a $height -lt 240 ]; then
22     resNative="${width}x${height}"
23   elif [ $width -lt 852 -a $height -lt 480 -a \( $width -gt 460 -o $height -gt 260 \) ]; then
24     resNative="${width}x${height}"
25   elif [ $width -lt 1280 -a $height -lt 720 -a \( $width -gt 920 -o $height -gt 520 \) ]; then
26     resNative="${width}x${height}"
27   elif [ $width -lt 1920 -a $height -lt 1080 -a \( $width -gt 1400  -o $height -gt 790 \) ]; then
28     resNative="${width}x${height}"
29   elif [ $width -gt 2200 -o $height -gt 1200 ]; then
30     resNative="${width}x${height}"
31   fi
32   if [ $width -ge 1920 -o $height -ge 1080 -a $((1080 * width / height)) -gt 2048 ]; then
33     res1080="1920x$((1920 * height / width))"
34     [ $((${res1080#*x} % 2)) -eq 1 ] && res1080="${res1080%x*}x$((${res1080#*x} + 1))"
35   elif [ $width -ge 1920 -o $height -ge 1080 ]; then
36     res1080="$((1080 * width / height))x1080"
37     [ $((${res1080%x*} % 2)) -eq 1 ] && res1080="$((${res1080%x*} + 1))x${res1080#*x}"
38   fi
39   if [ $width -ge 1280 -o $height -ge 720 -a $((720 * width / height)) -gt 1280 ]; then
40     res720="1280x$((1280 * height / width))"
41     [ $((${res720#*x} % 2)) -eq 1 ] && res720="${res720%x*}x$((${res720#*x} + 1))"
42   elif [ $width -ge 1280 -o $height -ge 720 ]; then
43     res720="$((720 * width / height))x720"
44     [ $((${res720%x*} % 2)) -eq 1 ] && res720="$((${res720%x*} + 1))x${res720#*x}"
45   fi
46   if [ $width -ge 852 -o $height -ge 480 -a $((480 * width / height)) -gt 854 ]; then
47     res480="854x$((854 * height / width))"
48     [ $((${res480#*x} % 2)) -eq 1 ] && res480="${res480%x*}x$((${res480#*x} + 1))"
49   elif [ $width -ge 852 -o $height -ge 480 -a $((480 * width / height)) -ge 850 ]; then
50     res480="854x480"
51   elif [ $width -ge 852 -o $height -ge 480 ]; then
52     res480="$((480 * width / height))x480"
53     [ $((${res480%x*} % 2)) -eq 1 ] && res480="$((${res480%x*} + 1))x${res480#*x}"
54   fi
55   if [ $width -ge 426 -o $height -ge 240 -a $((240 * width / height)) -gt 426 ]; then
56     res240="426x$((426 * height / width))"
57     [ $((${res240#*x} % 2)) -eq 1 ] && res240="${res240%x*}x$((${res240#*x} + 1))"
58   elif [ $width -ge 426 -o $height -ge 240 ]; then
59     res240="$((240 * width / height))x240"
60     [ $((${res240%x*} % 2)) -eq 1 ] && res240="$((${res240%x*} + 1))x${res240#*x}"
61   fi
62 }
63
64 transcode_run(){
65   local file="$1" meta width height cli
66   resNative='' res1080='' res720='' res480='' res240=''
67
68   meta="$(echo; ffprobe -show_entries stream=width,height "$file" 2>&-)"
69    width="${meta#*width=}";   width="${width%%${BR}*}"
70   height="${meta#*height=}"; height="${height%%${BR}*}"
71
72   [ "$width" -a "$height" ] || return 1
73
74   transcode_resolutions "$width" "$height"
75
76   file="$(printf %s "$file" |sed "s;';'\\\\'';g")"
77   cli="-y -nostdin -i '$file'"
78   [ "$resNative" ] && cli="$cli \\
79     -c:v libx264 -vf scale=$resNative -crf 21 -maxrate 20M -c:a aac       -q:a 4 '${file%.upload.*}'.native.mp4 \\
80     -c:v libvpx  -vf scale=$resNative -crf 30 -b:v 0       -c:a libvorbis -q:a 7 '${file%.upload.*}'.native.webm"
81   [ "$res1080" ] && cli="$cli \\
82     -c:v libx264 -vf scale=$res1080   -crf 21 -maxrate 12M -c:a aac       -q:a 4 '${file%.upload.*}'.1080p.mp4 \\
83     -c:v libvpx  -vf scale=$res1080   -crf 30 -b:v 0       -c:a libvorbis -q:a 7 '${file%.upload.*}'.1080p.webm"
84   [ "$res720" ] && cli="$cli \\
85     -c:v libx264 -vf scale=$res720    -crf 20 -maxrate  7M -c:a aac       -q:a 3 '${file%.upload.*}'.720p.mp4 \\
86     -c:v libvpx  -vf scale=$res720    -crf 28 -b:v 0       -c:a libvorbis -q:a 6 '${file%.upload.*}'.720p.webm"
87   [ "$res480" ] && cli="$cli \\
88     -c:v libx264 -vf scale=$res480    -crf 20 -maxrate  4M -c:a aac       -q:a 3 '${file%.upload.*}'.480p.mp4 \\
89     -c:v libvpx  -vf scale=$res480    -crf 28 -b:v 0       -c:a libvorbis -q:a 6 '${file%.upload.*}'.480p.webm"
90   [ "$res240" ] && cli="$cli \\
91     -c:v libx264 -vf scale=$res240    -crf 19 -maxrate  1M -c:a aac       -q:a 2 '${file%.upload.*}'.240p.mp4 \\
92     -c:v libvpx  -vf scale=$res240    -crf 25 -b:v 0       -c:a libvorbis -q:a 5 '${file%.upload.*}'.240p.webm"
93
94   if eval "ffmpeg $cli"; then
95     return 0
96   else
97     echo == FFMPEG ERROR ==
98     echo FFMPEG CLI was:
99     echo ffmpeg "$cli"
100     echo
101     return 1
102   fi
103 }
104
105 transcode_link(){
106   local file="$1"
107   if [ "$resNative" ]; then
108     ln -rs "${file%.upload.*}.native.mp4"  "${file%.upload.*}.mp4"
109     ln -rs "${file%.upload.*}.native.webm" "${file%.upload.*}.webm"
110   elif [ "$res1080" ]; then
111     ln -rs "${file%.upload.*}.1080p.mp4"  "${file%.upload.*}.mp4"
112     ln -rs "${file%.upload.*}.1080p.webm" "${file%.upload.*}.webm"
113   elif [ "$res720" ]; then
114     ln -rs "${file%.upload.*}.720p.mp4"  "${file%.upload.*}.mp4"
115     ln -rs "${file%.upload.*}.720p.webm" "${file%.upload.*}.webm"
116   elif [ "$res480" ]; then
117     ln -rs "${file%.upload.*}.480p.mp4"  "${file%.upload.*}.mp4"
118     ln -rs "${file%.upload.*}.480p.webm" "${file%.upload.*}.webm"
119   elif [ "$res240" ]; then
120     ln -rs "${file%.upload.*}.240p.mp4"  "${file%.upload.*}.mp4"
121     ln -rs "${file%.upload.*}.240p.webm" "${file%.upload.*}.webm"
122   fi
123 }
124
125 if [ "$1" = run ] && LOCK "$tpid"; then
126   read pid <"$tpid"
127   if [ "$pid" -a -d "/proc/$pid/" ]; then
128     RELEASE "$tpid"
129     exit 0
130   else
131     printf "%i\n" $$ >"$tpid"
132     RELEASE "$tpid"
133   fi
134
135   while read file <"$transq"; do
136     transcode_run "$file" \
137     && transcode_link "$file"
138     if LOCK "$transq"; then
139       sed -ni '2,$p' "$transq"
140       RELEASE "$transq"
141     fi
142   done
143
144   rm -- "$tpid"
145   exit 0
146 fi