+10
-9
AGENTS.md
+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
-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
+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
+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
+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}}