]>
Git — Sourcephile - julm/camera.git/blob - index.sh
2 # Copyright: Julien Moutinho <julm+camera@sourcephile.fr>
3 # License: AGPL-3.0-or-later
5 # $ mv julm/2023/src/02/IMG_20230228_111645{,.fav}.jpg
6 # $ echo >julm/2023/src/02/IMG_20230228_111645.fav.txt "Some HTML <b>comment</b> about the picture"
7 # $ ./index.sh julm/2023/src/02
8 # $ sensible-browser julm/2023/fav/02/index.html
11 # locations."/julm/perso/camera/" = {
12 # alias = "${root}/julm/perso/camera/";
13 # basicAuthFile = "/run/credentials/nginx.service/autogeree.net.www.julm.perso.camera.htpasswd";
15 # # Disable basicAuthFile for by-uuid
16 # locations."~ ^/julm/perso/camera/([0-9]+/[0-9][0-9]/by-uuid/[0-9a-f-]+/.+)$" = {
17 # alias = "${root}/julm/perso/camera/$1";
20 # shellcheck disable=SC2086
26 ffmpeg_
() { local -; set -x ; nice
-19 ffmpeg
</ dev
/ null
-hide_banner -loglevel warning
-stats -y "$@" ; }
27 magick_
() { local -; set -x ; nice
-19 magick
"$@" ; }
28 mv_
() { local -; mv -i >& 2 "$@" ; }
31 IFS
=/ read -r user year x month x
<<< " $dir "
32 test -n " $year " || exec " $0 " " $user " / 2 */ src
/*/
33 test -n " $month " || exec " $0 " " $user " / " $year " / src
/*/
34 pushd " $user / $year " >/ dev
/ null
35 test -d src
|| { popd ; continue ; }
37 # cp, not ln, because in push.sh --copy-links cannot be used for by-uuid/
38 cp -f --remove-destination -t fav ..
/ ..
/ index.css
39 test -d src
/ " $month " || { popd ; continue ; }
46 <!-- Generator: https://git.sourcephile.fr/julm/camera.git -->
47 <!-- GenerationDate: $(date -R -d@"$genDate") -->
51 <meta charset="utf-8">
52 <title>camera/ $user / $year / $month </title>
53 <link rel="stylesheet" href="../index.css? $genDate ">
59 <a href='../../..'>camera</a>/ <a href='../..'> $user </a>/ <a href='..'> $year </a>/
62 if [ " $m " -eq 01 ]; then printf '{ ' ; fi
63 if [ " $m " -eq " $month " ]; then
66 printf % s
"<a href='../ $m '> $m </a>"
68 if [ " $m " -eq 12 ]; then printf ' }' ; else printf ', ' ; fi
76 echo >& 2 " $dir : processing favorites in chronological order"
77 # Time is encoded in filenames like so: {IMG,VID}_YYYYMMDD_hhmmss.*
78 # hence sorting after the underscore (1st field, 5th char).
79 # To support subdirectories, sorting is done on the prefix %f
80 # which is replaced by %p thereafter.
81 ( cd src
; find -L " $month " -name '*.fav.*' -not -name "*.txt" -printf '%f %p \n ' ) | sort -t / -k1 .5
| cut
-f2 -d ' ' |
83 echo >& 2 " $dir : processing $year /src/ $src "
87 creationDate
= $(printf %s "${src##*/???_}" | sed -e 's/\(....\) \
( ..\
) \
( ..\
) _\
( ..\
) \
( ..\
) \
( ..\
) .
*/ \
1 - \
2 - \
3 \
4 : \
5 : \
6 / ')
88 creationDoM= $(date +'%A %_d %B' -d "$creationDate")
89 if test " $creationDoM " != " ${creationDoMOld-} "; then
90 dom= $(date +'%d' -d "$creationDate")
91 echo "<li id=' $dom ' class=' day
'><div>"
92 echo "<a class=' day
-current ' href=' #$dom'>$creationDoM</a>"
94 test ! " ${creationDateOld:+set} " ||
95 echo "<a class='day-previous' href='# $(date +'%d' -d "$creationDateOld") '>^</a>"
98 creationDoMOld
= $creationDoM
99 creationDateOld
= $creationDate
101 test -e fav
/ " $base " .uuid
||
102 uuidgen
--random > fav
/ " $base " .uuid
103 uuid
= $(cat fav/"$base".uuid)
104 mkdir -p fav
/ " ${base%/*} "
105 mkdir -p { tmp
, wip
}/ fav
/ " ${base%/*} "
106 mkdir -p fav
/ " $month " / by
-uuid / " $uuid "
108 test " ${src##*.wow.} " = " ${src} " || wow
= wow
111 echo "<li id=' $id ' class=' $wow '><div class='item'>"
113 printf "<source type='image/avif' srcset='"
114 for w
in { 1200 , 600 , 300 }; do
115 test fav
/ " $base " .
" $w " x.avif
-nt src
/ " $src " || {
117 -sampling-factor 4 : 2 : 0 -colorspace sRGB \
118 -auto-orient -thumbnail " $w " x
-unsharp 0 x
.5 \
119 wip
/ fav
/ " $base " .
" $w " x.avif
120 mv_
{ wip
/,} fav
/ " $base " .
" $w " x.avif
122 printf % s
" $name . ${w} x.avif ${w} w, "
126 test fav
/ " $base " .
" $w " x.jpg
-nt src
/ " $src " || {
127 magick_
-define jpeg
: size
= $((w * 2) ) x src
/ " $src " \
128 -sampling-factor 4 : 2 : 0 -interlace JPEG
-colorspace sRGB \
129 -auto-orient -thumbnail " $w " x
-unsharp 0 x
.5 \
130 wip
/ fav
/ " $base " .
" $w " x.jpg
131 mv_
{ wip
/,} fav
/ " $base " .
" $w " x.jpg
133 echo "<source type='image/jpeg' srcset=' $name . ${w} x.jpg ${w} w' />"
134 echo "<img src=' $name . ${w} x.jpg' alt=' $creationDate ' />"
136 dst
= " $name " .1200 x.avif
137 ln -fs -t fav
/ " $month " / by
-uuid / " $uuid " ..
/ ..
/ " $dst "
140 # Slow, but needed to make wide videos span two columns of the CSS grid
141 orient
= $(ffprobe -v 0 -select_streams v:0 -show_entries stream_side_data=rotation -of default=nw=1:nk=1 src/"$src")
142 if [ -z " $orient " ]; then scale
= "-2:360" ; else scale
= "360:-2" ; fi
143 echo "<li id=' $id ' class=' $wow vid-orient- $orient '><div class='item'>"
144 test fav
/ " $base " .avif
-nt src
/ " $src " || {
145 ffmpeg_
-i src
/ " $src " \
147 -filter : v format
= yuv420p10le
, scale
= " $scale " \
148 -frames : v
1 -crf 35 \
150 mv_
{ wip
/,} fav
/ " $base " .avif
153 test tmp
/ fav
/ " $base " .opus
-nt src
/ " $src " || {
154 ffmpeg_
-i src
/ " $src " \
155 -map 0 : a
-c : a libopus
-b : a
64 k
-application voip \
157 mv_
{ wip
, tmp
}/ fav
/ " $base " .opus
160 test fav
/ " $base " .360 p.av1.webm
-nt src
/ " $src " || {
162 # See https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/Docs/CommonQuestions.md
163 # See https://gist.github.com/BlueSwordM/86dfcb6ab38a93a524472a0cbe4c4100
164 # See https://www.streamingmediaglobal.com/Articles/ReadArticle.aspx?ArticleID=154488
165 # -preset Range from 0 to 13, with higher numbers providing a higher encoding speed;
166 # -crf Range is 0-63, with the default being 50.
167 # Lower values correspond to higher quality and greater file size
169 # yuv420p10le can represent more shades of grey and colors
170 # and is less prone to certain artifacts, such as color
171 # banding and loss of detail in low luma areas,
172 # cost in terms of resulting file size (~5%),
173 # can also be more compute-intensive than 8-bit in some decoders
174 # tune=0 subjective mode often results in an image with greater
175 # sharpness and is intended to produce a result that appears to humans
176 # to be of high quality (as opposed to doing well on basic objective measures,
178 # scd=1 biases the encoders' scene detection to insert more intra refreshes if needed,
179 # and reduce temporal dependencies around scene-changes.
180 # scm=0 screen content mode decision making. 0 is best for live-action.
181 ffmpeg_
-i src
/ " $src " -i tmp
/ fav
/ " $base " .opus \
183 -filter : v format
= yuv420p
, scale
= " $scale " \
184 -c : v libsvtav1
-preset 10 -crf 33 \
185 -svtav1-params keyint
= 10 s
: tune
= 0 : enable-overlays = 1 : scd
= 1 : scm
= 0 : fast
-decode = 1 : tile
-columns = 2 \
187 wip
/ fav
/ " $base " .360 p.av1.webm
188 mv_
{ wip
/,} fav
/ " $base " .360 p.av1.webm
190 dst
= " $name " .360 p.av1.webm
191 ln -fs -t fav
/ " $month " / by
-uuid / " $uuid " ..
/ ..
/ " $dst "
192 #test fav/"$base".360p.vp9.webm -nt src/"$src" || {
194 # # See https://developers.google.com/media/vp9/settings/vod#recommended_settings
195 # # See https://gist.github.com/mrintrepide/3033c35ee9557e66cff7806f48dbd339
197 # -filter:v format=yuv420p10le,scale="$scale" \
198 # -c:v libvpx-vp9 -quality good -crf 20 \
199 # -minrate 138k -b:v 276k -maxrate 400k \
200 # -cpu-used 4 -static-thresh 0 -tile-columns 0 -tile-rows 0 -frame-parallel 0 \
201 # -row-mt 1 -aq-mode 0 -auto-alt-ref 6 -lag-in-frames 25 -enable-tpl 1
202 # test -e tmp/fav/"$base".360p.vp9.webm-0.log || {
203 # # FIXME: how to disable h264 debug log?
204 # ffmpeg 2>/dev/null -i src/"$src" \
205 # -map 0:v "$@" -pass 1 -passlogfile wip/fav/"$base".360p.vp9.webm \
208 # mv_ -t tmp/fav/"${base%/*}" wip/fav/"$base".360p.vp9.webm-*.log
210 # ffmpeg -i src/"$src" -i tmp/fav/"$base".opus \
211 # -map 0:v "$@" -pass 2 -passlogfile tmp/fav/"$base".360p.vp9.webm \
212 # -map 1:a -c:a copy \
213 # wip/fav/"$base".360p.vp9.webm
214 # mkdir -p fav/"$month"/by-uuid/"$uuid"
215 # mv_ wip/fav/"$base".360p.vp9.webm fav/"$base".360p.vp9.webm
216 # rm -fv tmp/fav/"$base".360p.vp9.webm-*.log
218 #test fav/"$base".mp4 -nt src/"$src" || {
219 # ffmpeg -i src/"$src" \
220 # -filter:v format=yuv420p \
221 # -c:v libx264 -preset medium -crf 22 \
222 # -tune zerolatency \
223 # -maxrate 1M -bufsize 2M \
224 # -movflags use_metadata_tags +faststart \
225 # -c:a libopus -base:a 64k -application voip \
226 # -filter:v "scale=iw/2:ih/2" \
227 # wip/fav/"$base".mp4
228 # mv_ wip/fav/"$base".mp4 fav/"$base".mp4
230 # class='orient$orient'
231 echo "<video controls preload=none poster=' $name .avif'>"
232 # See https://jakearchibald.com/2022/html-codecs-parameter-for-av1/
233 # and ffmpeg -i fav/$month/foo.av1.webm -c:v copy -bsf:v trace_headers -f null /dev/null |&
234 # grep -e seq_profile -e seq_level_idx -e seq_tier -e high_bitdepth -e twelve_bit
235 P
= 0 ; LL
= 01 ; T
= M
; DD
= 08
236 echo "<source type='video/webm; codecs=av01. $P . $LL $T . $DD ' src=' $name .360p.av1.webm' />"
237 echo "<p><a href=' $name .360p.av1.webm'> $name .360p.av1.webm</a></p>"
240 touch -a src
/ " $base " .txt
241 printf % s
"<span class='comment'>"
242 sed -e ' $q ;s/$/<br \/> \n /' src
/ " $base " .txt
244 echo "</div>" # class='item'
245 echo "<span class='infos'>"
246 echo " <span class='creationDate'> $creationDate </span>"
248 echo "<span class='links'>"
249 echo " <a class='by-uuid' href='https://autogeree.net/julm/perso/camera/ $year / $month /by-uuid/ $uuid / ${dst##*/} ' title='Lien public vers cette capture' target='_blank'>@</a>"
250 echo " <a class='anchor' href='# $id ' title='Ancre vers cette capture'>#</a>"
262 } > tmp
/ fav
/ " $month " / index.html
263 mv_
-f { tmp
/,} fav
/ " $month " / index.html
265 echo >& 2 " $dir : removing any deleted favorites"
266 ( cd fav
; find -L " $month " -mindepth 1 -not -path '*/by-uuid/*' -type f
-not -name index.html
) |
267 while read -r fav
; do
269 base
= ${base%.300x.avif}
270 base
= ${base%.600x.avif}
271 base
= ${base%.600x.jpg}
272 base
= ${base%.1200x.avif}
274 base
= ${base%.360p.av1.webm}
278 for src
in src
/ " $base " .???
; do hasSrc
= set ; done
279 test " ${hasSrc:+set} " || {
280 echo >& 2 " $dir : removing $year /fav/ $fav "
282 rm -f fav
/ " $month " / by
-uuid /*/ " $name " .
{ 1200 x.avif
, avif
, 360 p.av1.webm
, uuid
}
285 rmdir -p 2 >/ dev
/ null fav
/ " $month " / by
-uuid /*/ || true
286 rmdir -p 2 >/ dev
/ null wip
/ fav
/* || true