summaryrefslogtreecommitdiffstats
path: root/roles
diff options
context:
space:
mode:
authorSacha Chua <sacha@sachachua.com>2026-05-10 15:07:33 -0400
committerSacha Chua <sacha@sachachua.com>2026-05-10 15:07:33 -0400
commit4e3d5bde72f4c3843e006ab7283b328098642929 (patch)
tree9962486a6025f34eb3fc6e1abeccd71f069858e0 /roles
parenta030065f6dc040f127633523d8d3789201ec81c1 (diff)
downloademacsconf-ansible-4e3d5bde72f4c3843e006ab7283b328098642929.tar.xz
emacsconf-ansible-4e3d5bde72f4c3843e006ab7283b328098642929.zip
makefile changes
Diffstat (limited to 'roles')
-rw-r--r--roles/prerec/templates/Makefile88
-rwxr-xr-xroles/prerec/templates/reencode-in-screen.sh6
-rwxr-xr-xroles/prerec/templates/thumbnail.sh2
3 files changed, 90 insertions, 6 deletions
diff --git a/roles/prerec/templates/Makefile b/roles/prerec/templates/Makefile
index f58c5d6..778ae3e 100644
--- a/roles/prerec/templates/Makefile
+++ b/roles/prerec/templates/Makefile
@@ -2,21 +2,41 @@
# To recreate this file, use ansible-playbook -i inventory.yml prod-playbook.yml --tags prerec-make
-VIDEO_EXTS = mp4 mkv webm mov mpv
+.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_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 main
+all: reencoded opus main main-opus waveforms.png
reencoded: $(PRERECS_REENCODED)
@@ -26,6 +46,17 @@ 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)))))
@@ -38,7 +69,12 @@ emacsconf-%--reencoded.webm:
reencode-in-screen.sh "$(SOURCE)"
emacsconf-%--reencoded.opus: emacsconf-%--reencoded.webm
- ffmpeg -y -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 "$@"
@@ -60,11 +96,20 @@ emacsconf-%--main.webm: emacsconf-%--reencoded.webm emacsconf-%--normalized.opus
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
- ffmpeg -y -i "$<" -c:a copy "$@"
+ 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-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\`." "$<"
@@ -116,3 +161,38 @@ live-dormant:
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/reencode-in-screen.sh b/roles/prerec/templates/reencode-in-screen.sh
index 5c12203..7119572 100755
--- a/roles/prerec/templates/reencode-in-screen.sh
+++ b/roles/prerec/templates/reencode-in-screen.sh
@@ -1,7 +1,11 @@
#!/bin/bash
ORIGINAL=$1
BASE="${ORIGINAL%--original.*}"
-REENCODED="${BASE}--reencoded.webm"
+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"
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/ )