summaryrefslogtreecommitdiffstats
path: root/roles/prerec/templates
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--roles/prerec/templates/Makefile146
-rwxr-xr-xroles/prerec/templates/copy-original.sh24
-rwxr-xr-xroles/prerec/templates/get-file-prefix10
-rwxr-xr-xroles/prerec/templates/process-prerec.sh6
-rwxr-xr-xroles/prerec/templates/reencode-in-screen.sh20
-rwxr-xr-xroles/prerec/templates/reencode.sh6
-rwxr-xr-xroles/prerec/templates/talk3
-rwxr-xr-xroles/prerec/templates/thumbnail.sh2
-rwxr-xr-xroles/prerec/templates/upload.sh4
9 files changed, 205 insertions, 16 deletions
diff --git a/roles/prerec/templates/Makefile b/roles/prerec/templates/Makefile
index 709a069..778ae3e 100644
--- a/roles/prerec/templates/Makefile
+++ b/roles/prerec/templates/Makefile
@@ -1,31 +1,62 @@
# {{ ansible_managed }}
-VIDEO_EXTS = mp4 mkv webm mov
+# To recreate this file, use ansible-playbook -i inventory.yml prod-playbook.yml --tags prerec-make
+
+.ONESHELL:
+SHELL := /bin/bash
+# --- Shell Function Definition ---
+# This function checks a given file ($1) for an audio stream.
+# It returns the string "audio" if found, or nothing if not found.
+# This makes the conditional check cleaner.
+define IS_AUDIO_PRESENT_SCRIPT
+ ffprobe -loglevel error -select_streams a:0 \
+ -show_entries stream=codec_type \
+ -of default=noprint_wrappers=1:nokey=1 "$1"
+endef
+IS_AUDIO_PRESENT = $(IS_AUDIO_PRESENT_SCRIPT)
+
+source_patterns = $(foreach ext,$(VIDEO_EXTS),$(1)--original.$(ext))
+ANSWER_EXTS = mp4 mkv mov mpv m4v
source_patterns = $(foreach ext,$(VIDEO_EXTS),$(1)--original.$(ext))
+answer_patterns = $(foreach ext,$(ANSWER_EXTS),$(1)--answers.$(ext))
PRERECS_ORIGINAL := $(wildcard emacsconf-*--original.*)
+ANSWERS_ORIGINAL := $(wildcard emacsconf-*--answers.*)
+ANSWER_PREFIXES := $(shell for f in $(ANSWERS_ORIGINAL); do echo "$${f%--answers.*}"; done)
PREFIXES := $(shell for f in $(PRERECS_ORIGINAL); do echo "$${f%--original.*}"; done)
+ANSWERS_REENCODED := $(addsuffix --answers--reencoded.webm, $(ANSWER_PREFIXES))
PRERECS_REENCODED := $(addsuffix --reencoded.webm, $(PREFIXES))
PRERECS_OPUS := $(addsuffix --reencoded.opus, $(PREFIXES))
-PRERECS_NORMAL := $(addsuffix --normalized.opus, $(PREFIXES))
+PRERECS_MAIN_OPUS := $(addsuffix --main.opus, $(PREFIXES))
PRERECS_MAIN := $(addsuffix --main.webm, $(PREFIXES))
PRERECS_CAPTIONS := $(addsuffix --reencoded.vtt, $(PREFIXES))
PRERECS_FINAL := $(wildcard emacsconf-*--final.webm)
+WAVEFORMS := $(addsuffix --backstage--waveform.png, $(PREFIXES))
+LINODE_BBB_ID := 67329098
.PHONY: all
-all: reencoded opus normal main
+all: reencoded opus main main-opus waveforms.png
reencoded: $(PRERECS_REENCODED)
opus: $(PRERECS_OPUS)
-normal: $(PRERECS_NORMAL)
-
captions: $(PRERECS_CAPTIONS)
main: $(PRERECS_MAIN)
+main-opus: $(PRERECS_MAIN_OPUS)
+
+waveforms: $(WAVEFORMS)
+
+answers: $(ANSWERS_REENCODED)
+
+emacsconf-%--answers--reencoded.webm: SOURCES = $(call answer_patterns, emacsconf-$*)
+emacsconf-%--answers--reencoded.webm:
+ $(eval SOURCE := $(lastword $(sort $(wildcard $(SOURCES)))))
+ @echo $(SOURCE) $@
+
emacsconf-%--reencoded.webm: SOURCES = $(call source_patterns, emacsconf-$*)
emacsconf-%--reencoded.webm:
$(eval SOURCE := $(lastword $(sort $(wildcard $(SOURCES)))))
@@ -35,13 +66,21 @@ emacsconf-%--reencoded.webm:
exit 1; \
fi
@echo "Using source: $(SOURCE)"
- ./reencode-in-screen.sh "$(SOURCE)"
+ reencode-in-screen.sh "$(SOURCE)"
emacsconf-%--reencoded.opus: emacsconf-%--reencoded.webm
- ffmpeg -i "$<" -c:a copy "$@"
+ AUDIO_CHECK=$$( $(call IS_AUDIO_PRESENT, "$<") )
+ if [ ! -z "$$AUDIO_CHECK" ]; then
+ ffmpeg -y -i "$<" -c:a copy "$@"
+ else
+ ffmpeg -y -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=48000 -t 1 -c:a libopus "$@"
+ fi
+
+emacsconf-%--answers.opus: emacsconf-%--answers.webm
+ ffmpeg -y -i "$<" -c:a copy "$@"
-emacsconf-%--normalized.opus: emacsconf-%--reencoded.opus
- ffmpeg-normalize "$<" -ofmt opus -c:a libopus -o "$@"
+# emacsconf-%--normalized.opus: emacsconf-%--reencoded.opus
+# ffmpeg-normalize "$<" -ofmt opus -c:a libopus -o "$@"
emacsconf-%--main.webm: emacsconf-%--reencoded.webm emacsconf-%--normalized.opus emacsconf-%--main.vtt
ffmpeg -i emacsconf-$*--reencoded.webm -i emacsconf-$*--normalized.opus -i emacsconf-$*--main.vtt \
@@ -49,14 +88,34 @@ emacsconf-%--main.webm: emacsconf-%--reencoded.webm emacsconf-%--normalized.opus
-map 2 -c:s webvtt -y \
$@
+emacsconf-%--main.webm: emacsconf-%--reencoded.webm emacsconf-%--normalized.opus
+ ffmpeg -i emacsconf-$*--reencoded.webm -i emacsconf-$*--normalized.opus \
+ -map 0:v -map 1:a -c:v copy -c:a copy \
+ -y $@
+
emacsconf-%--main.webm: emacsconf-%--reencoded.webm
cp "$<" "$@"
+emacsconf-%--main.webm: emacsconf-%--reencoded.webm emacsconf-%--main.vtt
+ cp "$<" "$@"
+ ffmpeg -i emacsconf-$*--reencoded.webm -i emacsconf-$*--main.vtt \
+ -c:v copy -c:a copy \
+ -y $@
+
emacsconf-%--final.webm: emacsconf-%--main.vtt
mux-subs.sh "$@" "$<"
+emacsconf-%--main.opus: emacsconf-%--main.webm
+ AUDIO_CHECK=$$( $(call IS_AUDIO_PRESENT, "$<") )
+ if [ ! -z "$$AUDIO_CHECK" ]; then \
+ ffmpeg -y -i "$<" -c:a copy "$@"; \
+ fi
+
emacsconf-%--reencoded.vtt: emacsconf-%--reencoded.opus
- whisperx --model large-v2 --align_model WAV2VEC2_ASR_LARGE_LV60K_960H --compute_type int8 --print_progress True --max_line_width 50 --segment_resolution chunk --max_line_count 1 --language en "$<"
+ whisperx --model large-v3 --align_model WAV2VEC2_ASR_LARGE_LV60K_960H --compute_type int8 --print_progress True --max_line_width 50 --segment_resolution chunk --max_line_count 1 --language en --initial_prompt "Transcribe this talk about Emacs. It may mention Emacs keywords such as Org Mode, Org Roam, Magit, gptel, or chatgpt-shell, or tech keywords such as LLMs. Format function names and keyboard shortcut sequences according to Emacs conventions using Markdown syntax. For example: control h becomes \`C-h\`." "$<"
+
+emacsconf-%--backstage--silences.csv: emacsconf-%--reencoded.opus
+ ffmpeg -i "$<" -af silencedetect=noise=-30dB:d=0.5 -f null - 2>&1 | awk '/silence_start/ {start=$$NF} /silence_end/ {print start "," (start + $$NF)}' > "$@"
show-files:
@echo "Original $(words $(PRERECS_ORIGINAL)):"
@@ -68,5 +127,72 @@ show-files:
@echo "Opus $(words $(PRERECS_OPUS)):"
@echo "$(PRERECS_OPUS)"
+bbb-testing:
+ @echo "Resizing BBB node to 8GB 4 core for testing"
+ linode-cli linodes resize $(LINODE_BBB_ID) --type g6-standard-4 --allow_auto_disk_resize false
+ sleep 2m
+ @echo "Booting up"
+ linode-cli linodes boot $(LINODE_BBB_ID)
+ ssh root@bbb.emacsverse.org "cd ~/greenlight-v3; docker compose restart"
+
+bbb-dormant:
+ @echo "Shutting down"
+ ssh root@bbb.emacsverse.org "/usr/sbin/shutdown -h now &" || true
+ sleep 30
+ @echo "Powering off BBB node"
+ linode-cli linodes shutdown $(LINODE_BBB_ID)
+ sleep 30
+ @echo "Resizing BBB node to nanode, dormant"
+ linode-cli linodes resize $(LINODE_BBB_ID) --type g6-nanode-1 --allow_auto_disk_resize false
+
+bbb-prod:
+ @echo "Resizing BBB node to production size"
+ linode-cli linodes resize $(LINODE_BBB_ID) --type g6-dedicated-8 --allow_auto_disk_resize true
+ sleep 2m
+ @echo "Booting up"
+ linode-cli linodes boot $(LINODE_BBB_ID)
+
+live-dormant:
+ @echo "Resizing live0 node to nanode, dormant"
+ linode-cli linodes resize 17921960 --type g6-nanode-1 --allow_auto_disk_resize false
+ sleep 120
+ linode-cli linodes boot 17921960
+
+
rsync:
rsync -avzue ssh {{ emacsconf_caption_dir }}/cache/ orga@media.emacsconf.org:/var/www/media.emacsconf.org/{{ emacsconf_year }}/backstage/
+
+
+WAVEFORM_HEIGHT := 240
+WAVEFORM_WIDTH := 400
+WAVEFORM_VOLUME := 3.0
+WAVEFORM_FILTER := "[0:a]aformat=channel_layouts=mono[b];[b]volume=$(WAVEFORM_VOLUME)[a];[a]compand=attacks=0:points=-90/-90|0/0,showwavespic=s=$(WAVEFORM_WIDTH)x$(WAVEFORM_HEIGHT):colors=\#9cf42f[fg];color=s=$(WAVEFORM_WIDTH)x$(WAVEFORM_HEIGHT):color=\#44582c,drawgrid=width=iw/10:height=ih/5:color=\#9cf42f@0.1[bg];[bg][fg]overlay=format=auto[comp];[comp]drawtext=text='$$ID':fontcolor=white:fontsize=24:x=10:y=10:box=1:boxcolor=\#44582c@0.5:boxborderw=5"
+
+emacsconf-%--backstage--waveform.png: emacsconf-%--normalized.opus
+ AUDIO_CHECK=$$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_type -of default=noprint_wrappers=1:nokey=1 "$<"); \
+ ID=$$(echo "$<" | sed 's/--.*//'); \
+ if [ ! -z "$$AUDIO_CHECK" ]; then \
+ ffmpeg -i "$<" \
+ -filter_complex $(WAVEFORM_FILTER) \
+ -frames:v 1 \
+ -c:v png \
+ -update 1 \
+ -y \
+ "$@"; \
+ fi
+
+emacsconf-%--backstage--waveform.png: emacsconf-%--reencoded.opus
+ AUDIO_CHECK=$$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_type -of default=noprint_wrappers=1:nokey=1 "$<"); \
+ ID=$$(echo "$<" | sed 's/--.*//'); \
+ if [ ! -z "$$AUDIO_CHECK" ]; then \
+ ffmpeg -i "$<" \
+ -filter_complex $(WAVEFORM_FILTER) \
+ -frames:v 1 \
+ -c:v png \
+ -update 1 \
+ -y \
+ "$@"; \
+ fi
+
+waveforms.png: $(WAVEFORMS)
+ convert $^ +append "$@"
diff --git a/roles/prerec/templates/copy-original.sh b/roles/prerec/templates/copy-original.sh
new file mode 100755
index 0000000..854bdb8
--- /dev/null
+++ b/roles/prerec/templates/copy-original.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# {{ ansible_managed }}
+# Usage: rename-original.sh $slug $file [$extra]
+SLUG=$1
+FILE=$2
+EXTRA=""
+if [ -z ${3-unset} ]; then
+ EXTRA=""
+elif [ -n "$3" ]; then
+ EXTRA="$3"
+elif echo "$FILE" | grep -e '\(webm\|mp4\|mov\)'; then
+ EXTRA="--original"
+fi
+filename=$(basename -- "$FILE")
+extension="${filename##*.}"
+filename="${filename%.*}"
+FILE_PREFIX=$(get-file-prefix $SLUG)
+if echo "$FILE" | grep -q \\. ; then
+ cp "$FILE" $FILE_PREFIX$EXTRA.$extension
+ echo $FILE_PREFIX$EXTRA.$extension
+else
+ cp "$FILE" $FILE_PREFIX$EXTRA
+ echo $FILE_PREFIX$EXTRA
+fi
diff --git a/roles/prerec/templates/get-file-prefix b/roles/prerec/templates/get-file-prefix
new file mode 100755
index 0000000..0240b99
--- /dev/null
+++ b/roles/prerec/templates/get-file-prefix
@@ -0,0 +1,10 @@
+#!/bin/bash
+# {{ ansible_managed }}
+# Usage: get-file-prefix $slug [talks.json]
+# You can also set the TALKS_JSON environment variable
+
+SLUG=$1
+if [ -z "$TALKS_JSON" ]; then
+ TALKS_JSON=${2:-~orga/current/talks.json}
+fi
+jq -r '.talks[] | select(.slug=="'$SLUG'")["file-prefix"]' < $TALKS_JSON
diff --git a/roles/prerec/templates/process-prerec.sh b/roles/prerec/templates/process-prerec.sh
index d98337f..4347576 100755
--- a/roles/prerec/templates/process-prerec.sh
+++ b/roles/prerec/templates/process-prerec.sh
@@ -5,9 +5,11 @@ ORIGINAL=$1
REENCODED=$(echo "$ORIGINAL" | perl -pe 's/^(emacsconf-[0-9]*-.*?--.*?--.*?--).*/$1reencoded.webm/')
SLUG=$(echo "$ORIGINAL" | perl -ne '/^emacsconf-[0-9]*-(.*?)--/ && print $1')
MAIN=$(echo "$ORIGINAL" | perl -pe 's/^(emacsconf-[0-9]*-.*?--.*?--.*?--).*/$1main.webm/')
+VTT=$(echo "$ORIGINAL" | perl -pe 's/^(emacsconf-[0-9]*-.*?--.*?--.*?--).*/$1reencoded.vtt/')
# ( cd /data/emacsconf/cache; ./update-cache )
# /data/emacsconf/admin/{{ emacsconf_year }}/scripts/talk $SLUG "WAITING_FOR_PREREC" "PROCESSING"
if [[ ! -f "$REENCODED" ]]; then
- screen -dmS reencode-$SLUG /bin/bash -c "reencode.sh \"$ORIGINAL\" \"$REENCODED\" && upload.sh $REENCODED $MAIN && thumbnail.sh \"$MAIN\" && upload.sh $(echo "$MAIN" | sed s/webm$/png/); echo $(date -Iminutes) $SLUG reencoded >> ~/emacsconf.log && exec /bin/bash" &
+ screen -dmS reencode-$SLUG /bin/bash -c "reencode.sh \"$ORIGINAL\" \"$REENCODED\" && make $MAIN && upload.sh $REENCODED $MAIN && thumbnail.sh \"$MAIN\" && upload.sh $(echo "$MAIN" | sed s/webm$/png/); echo $(date -Iminutes) $SLUG reencoded >> ~/emacsconf.log && make $VTT; echo $(date -Iminutes) $SLUG captioned >> ~/emacsconf.log; exec /bin/bash" &
+else
+ screen -dmS captions-$SLUG /bin/bash -c "make $VTT; echo $(date -Iminutes) $SLUG captioned >> ~/emacsconf.log; exec /bin/bash"
fi
-screen -dmS captions-$SLUG /bin/bash -c "/data/emacsconf/admin/{{ emacsconf_year }}/scripts/process-captions.py $(dirname $ORIGINAL); echo $(date -Iminutes) $SLUG captioned >> ~/emacsconf.log; exec /bin/bash"
diff --git a/roles/prerec/templates/reencode-in-screen.sh b/roles/prerec/templates/reencode-in-screen.sh
new file mode 100755
index 0000000..7119572
--- /dev/null
+++ b/roles/prerec/templates/reencode-in-screen.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+ORIGINAL=$1
+BASE="${ORIGINAL%--original.*}"
+if [ -n "$2" ]; then
+ REENCODED=$2
+else
+ REENCODED="${BASE}--reencoded.webm"
+fi
+SLUG=$(echo "$ORIGINAL" | perl -ne '/^emacsconf-[0-9]*-(.*?)--/ && print $1')
+LOCK=".lock-$SLUG"
+
+if [ ! -f "$REENCODED" ]; then
+ if [ -f "$LOCK" ]; then
+ echo "$LOCK already exists, waiting for it"
+ else
+ touch "$LOCK"
+ screen -dmS reencode-$SLUG /bin/bash -c "reencode.sh \"$ORIGINAL\" \"$REENCODED\" && thumbnail.sh \"$MAIN\" && rm \"$LOCK\""
+ echo "Processing $REENCODED in reencode-$SLUG"
+ fi
+fi
diff --git a/roles/prerec/templates/reencode.sh b/roles/prerec/templates/reencode.sh
index 665fee2..ac5309a 100755
--- a/roles/prerec/templates/reencode.sh
+++ b/roles/prerec/templates/reencode.sh
@@ -10,6 +10,9 @@ print_only=false
limit_resolution={{ res_y }}
limit_fps={{ fps }}
+output_final="${2:-$(echo $input | sed 's/--original.*/--reencoded.webm/')}"
+output_temp="partial--${output_final}" # <-- New temporary name
+
while getopts :q:c:t:s OPT; do
case $OPT in
q|+q)
@@ -47,7 +50,7 @@ ffmpeg -y -i "$input" $time_limit \
fps='$limit_fps'" \
-c:v libvpx-vp9 -b:v 0 -crf $q -c:a libopus \
-row-mt 1 -tile-columns 2 -tile-rows 2 -cpu-used $cpu \
- -pass 2 -threads $cpu -- "$output"
+ -pass 2 -threads $cpu -- "$output_temp"
EOF
)"
@@ -55,4 +58,5 @@ if [ $print_only == true ]; then
echo "$command"
else
eval "$command"
+ mv "$output_temp" "$output_final"
fi
diff --git a/roles/prerec/templates/talk b/roles/prerec/templates/talk
index fa2e5f0..a9d4cb0 100755
--- a/roles/prerec/templates/talk
+++ b/roles/prerec/templates/talk
@@ -3,6 +3,9 @@
# How to use: talk slug from-status-regexp to-status
# or talk slug to-status
+# Statuses:
+# PLAYING:
+
SLUG="$1"
FROM_STATUS="$2"
TO_STATUS="$3"
diff --git a/roles/prerec/templates/thumbnail.sh b/roles/prerec/templates/thumbnail.sh
index 436979d..1cf7372 100755
--- a/roles/prerec/templates/thumbnail.sh
+++ b/roles/prerec/templates/thumbnail.sh
@@ -1,3 +1,3 @@
#!/bin/bash
# {{ ansible_managed }}
-ffmpeg -i "$1" -vf "thumbnail,scale=400:225" -frames:v 1 $(echo "$1" | sed s/webm/png/ )
+ffmpeg -y -i "$1" -vf "thumbnail,scale=400:225" -frames:v 1 $(echo "$1" | sed s/webm/png/ )
diff --git a/roles/prerec/templates/upload.sh b/roles/prerec/templates/upload.sh
index fbf3025..03cc66a 100755
--- a/roles/prerec/templates/upload.sh
+++ b/roles/prerec/templates/upload.sh
@@ -2,5 +2,5 @@
# {{ ansible_managed }}
scp $* orga@media.emacsconf.org:~/backstage
-/data/emacsconf/admin/{{ emacsconf_year }}/scripts/publish-backstage-index.sh
-rsync -avze ssh orga@media.emacsconf.org:~/backstage/ /data/emacsconf/admin/cache/
+# /usr/local/bin/publish-backstage-index.sh
+rsync -avze ssh orga@media.emacsconf.org:~/backstage/ /data/emacsconf/shared/{{ emacsconf_year }}/cache/