scripts: add transcoder verification script (#335)

* scripts: add transcoder verification script

* chore: use sandbox for test files in verify script

* chore: remove old script and update justfile

* docs: update AGENTS.md

authored by zzstoatzz.io and committed by GitHub e618a026 967b6ec5

Changed files
+113 -48
scripts
transcoder
+10 -9
AGENTS.md
··· 18 18 * **Backend:** FastAPI, Neon (Postgres), Cloudflare R2, Fly.io. 19 19 * **Frontend:** SvelteKit (Svelte 5 Runes), Bun, Cloudflare Pages. 20 20 * **Observability:** Logfire. 21 - * **`just` use the justfile! 22 - * **use MCPs for access to external systems, review docs/tools when needed 21 + * **`just` use the justfiles!** 22 + * **use MCPs** for access to external systems, review docs/tools when needed 23 23 24 24 ## ๐Ÿ’ป Development Commands 25 25 * **Setup:** `uv sync && just frontend install` ··· 31 31 32 32 ## ๐Ÿ“‚ Project Structure 33 33 ``` 34 - plyr/ 35 - โ”œโ”€โ”€ src/backend/ 36 - โ”‚ โ”œโ”€โ”€ api/ # Public endpoints 37 - โ”‚ โ”œโ”€โ”€ _internal/ # Auth, PDS, Uploads logic 38 - โ”‚ โ”œโ”€โ”€ models/ # SQLAlchemy schemas 39 - โ”‚ โ”œโ”€โ”€ storage/ # R2 and filesystem adapters 40 - โ”‚ โ””โ”€โ”€ utilities/ # Config, helpers 34 + plyr.fm/ 35 + โ”œโ”€โ”€ backend/ 36 + โ”‚ โ””โ”€โ”€ src/backend/ 37 + โ”‚ โ”œโ”€โ”€ api/ # Public endpoints 38 + โ”‚ โ”œโ”€โ”€ _internal/ # Auth, PDS, Uploads logic 39 + โ”‚ โ”œโ”€โ”€ models/ # SQLAlchemy schemas 40 + โ”‚ โ”œโ”€โ”€ storage/ # R2 and filesystem adapters 41 + โ”‚ โ””โ”€โ”€ utilities/ # Config, helpers 41 42 โ”œโ”€โ”€ frontend/ # SvelteKit app 42 43 โ”‚ โ”œโ”€โ”€ src/routes/ # Pages (+page.svelte, +page.server.ts) 43 44 โ”‚ โ””โ”€โ”€ src/lib/ # Components & State (.svelte.ts)
-32
scripts/test-transcoder.sh
··· 1 - #!/usr/bin/env bash 2 - # Simple helper to POST an audio file to the local transcoder API and save the result. 3 - set -euo pipefail 4 - 5 - if [[ $# -lt 1 ]]; then 6 - echo "usage: $(basename "$0") <input-file> [output-file]" >&2 7 - exit 1 8 - fi 9 - 10 - INPUT_FILE="$1" 11 - OUTPUT_FILE="${2:-$(basename "${INPUT_FILE%.*}")}.mp3" 12 - PORT="${TRANSCODER_PORT:-8082}" 13 - AUTH_TOKEN="${TRANSCODER_AUTH_TOKEN:-}" 14 - 15 - CURL_ARGS=( 16 - --fail 17 - --silent 18 - --show-error 19 - -X POST 20 - -F "file=@${INPUT_FILE}" 21 - ) 22 - 23 - # add auth header if token is set 24 - if [[ -n "${AUTH_TOKEN}" ]]; then 25 - CURL_ARGS+=(-H "X-Transcoder-Key: ${AUTH_TOKEN}") 26 - fi 27 - 28 - curl "${CURL_ARGS[@]}" \ 29 - "http://127.0.0.1:${PORT}/transcode?target=mp3" \ 30 - --output "${OUTPUT_FILE}" 31 - 32 - echo "wrote ${OUTPUT_FILE}" >&2
+36
scripts/transcoder/test-local.sh
··· 1 + #!/usr/bin/env bash 2 + # Simple helper to POST an audio file to the local transcoder API and save the result. 3 + set -euo pipefail 4 + 5 + if [[ $# -lt 1 ]]; then 6 + echo "usage: $(basename "$0") <input-file> [output-file]" >&2 7 + exit 1 8 + fi 9 + 10 + INPUT_FILE="$1" 11 + if [[ $# -ge 2 ]]; then 12 + OUTPUT_FILE="$2" 13 + else 14 + OUTPUT_FILE="$(basename "${INPUT_FILE%.*}").mp3" 15 + fi 16 + PORT="${TRANSCODER_PORT:-8082}" 17 + AUTH_TOKEN="${TRANSCODER_AUTH_TOKEN:-}" 18 + 19 + CURL_ARGS=( 20 + --fail 21 + --silent 22 + --show-error 23 + -X POST 24 + -F "file=@${INPUT_FILE}" 25 + ) 26 + 27 + # add auth header if token is set 28 + if [[ -n "${AUTH_TOKEN}" ]]; then 29 + CURL_ARGS+=(-H "X-Transcoder-Key: ${AUTH_TOKEN}") 30 + fi 31 + 32 + curl "${CURL_ARGS[@]}" \ 33 + "http://127.0.0.1:${PORT}/transcode?target=mp3" \ 34 + --output "${OUTPUT_FILE}" 35 + 36 + echo "wrote ${OUTPUT_FILE}" >&2
+61
scripts/transcoder/verify-local.sh
··· 1 + #!/usr/bin/env bash 2 + set -euo pipefail 3 + 4 + # Clean up any previous runs 5 + mkdir -p sandbox/test-files 6 + rm -f sandbox/test-files/test.aiff sandbox/test-files/test.mp3 transcoder_output.log 7 + 8 + echo "Building transcoder..." 9 + cd transcoder 10 + cargo build --quiet 11 + cd .. 12 + 13 + echo "Starting transcoder..." 14 + export TRANSCODER_PORT=8083 15 + export TRANSCODER_HOST=127.0.0.1 16 + # We use 8083 to avoid conflict with any previous zombies on 8082 17 + 18 + ./transcoder/target/debug/transcoder > transcoder_output.log 2>&1 & 19 + PID=$! 20 + echo "Transcoder started with PID $PID" 21 + 22 + # Cleanup function 23 + cleanup() { 24 + echo "Stopping transcoder..." 25 + kill $PID || true 26 + wait $PID || true 27 + } 28 + trap cleanup EXIT 29 + 30 + # Wait for health check 31 + echo "Waiting for transcoder to be ready..." 32 + for i in {1..30}; do 33 + if curl -s "http://127.0.0.1:8083/health" > /dev/null; then 34 + echo "Transcoder is ready!" 35 + break 36 + fi 37 + sleep 0.5 38 + done 39 + 40 + if ! curl -s "http://127.0.0.1:8083/health" > /dev/null; then 41 + echo "Transcoder failed to start. Log output:" 42 + cat transcoder_output.log 43 + exit 1 44 + fi 45 + 46 + echo "Generating sample AIFF..." 47 + uv run scripts/generate_audio_sample.py sandbox/test-files/test.aiff --waveform sine --duration 2 48 + 49 + echo "Testing transcoding..." 50 + # Override port for the test script 51 + export TRANSCODER_PORT=8083 52 + ./scripts/transcoder/test-local.sh sandbox/test-files/test.aiff sandbox/test-files/test.mp3 53 + 54 + # test-local.sh doesn't append .mp3 if output file is provided 55 + if [[ -f sandbox/test-files/test.mp3 ]]; then 56 + SIZE=$(wc -c < sandbox/test-files/test.mp3) 57 + echo "Success! generated MP3 size: $SIZE bytes" 58 + else 59 + echo "Failure! MP3 file not created." 60 + exit 1 61 + fi
+6 -7
transcoder/Justfile
··· 5 5 alias b := build 6 6 7 7 run: 8 - cd {{justfile_directory()}}/transcoder && \ 9 8 TRANSCODER_HOST="${TRANSCODER_HOST:-127.0.0.1}" \ 10 9 TRANSCODER_PORT="${TRANSCODER_PORT:-8082}" \ 11 10 cargo watch -x run 12 11 13 12 build: 14 - cd {{justfile_directory()}}/transcoder && cargo build --release 13 + cargo build --release 15 14 16 15 check: 17 - cd {{justfile_directory()}}/transcoder && cargo check 16 + cargo check 18 17 19 18 fmt: 20 - cd {{justfile_directory()}}/transcoder && cargo fmt 19 + cargo fmt 21 20 22 21 clippy: 23 - cd {{justfile_directory()}}/transcoder && cargo clippy --all-targets --all-features 22 + cargo clippy --all-targets --all-features 24 23 25 24 image tag="plyr-transcoder:local": 26 - cd {{justfile_directory()}}/transcoder && docker build -t {{tag}} . 25 + docker build -t {{tag}} . 27 26 28 27 docker-run TAG="plyr-transcoder:local" PORT="8082": 29 28 docker run --rm -p {{PORT}}:8080 {{TAG}} 30 29 31 30 fly ARGS="": 32 - cd {{justfile_directory()}}/transcoder && fly deploy --config fly.toml {{ARGS}} 31 + fly deploy --config fly.toml {{ARGS}}