+9
-2
.github/workflows/status-maintenance.yml
+9
-2
.github/workflows/status-maintenance.yml
···
90
90
91
91
if skip_audio is false:
92
92
1. write a 2-3 minute podcast script to podcast_script.txt
93
-
- two hosts having a casual technical conversation
93
+
- two hosts having a casual conversation
94
94
- focus on shipped features from the top of STATUS.md
95
95
- format: "Host: ..." and "Cohost: ..." lines
96
96
97
+
tone guidelines:
98
+
- accessible to non-technical listeners, but don't dumb it down
99
+
- focus on user impact: what can people do now that they couldn't before?
100
+
- use intuitive analogies to explain technical concepts in terms of everyday experience
101
+
- matter-of-fact delivery, not hype-y or marketing-speak
102
+
- brief, conversational - like two friends catching up on what shipped
103
+
97
104
2. run: uv run scripts/generate_tts.py podcast_script.txt update.wav
98
105
99
-
3. run: uv run --with plyrfm -- plyrfm upload update.wav "plyr.fm update - <today's date>"
106
+
3. run: uv run --with plyrfm -- plyrfm upload update.wav "plyr.fm update - <today's date>" --album "$(date +%Y)"
100
107
101
108
## task 3: open PR with changes
102
109
+20
-3
scripts/generate_tts.py
+20
-3
scripts/generate_tts.py
···
11
11
# dependencies = ["google-genai"]
12
12
# ///
13
13
14
+
import io
14
15
import os
15
16
import sys
17
+
import wave
16
18
from pathlib import Path
17
19
18
20
from google import genai
19
21
from google.genai import types
22
+
23
+
24
+
def pcm_to_wav(
25
+
pcm_data: bytes, sample_rate: int = 24000, channels: int = 1, sample_width: int = 2
26
+
) -> bytes:
27
+
"""wrap raw PCM data in a WAV header."""
28
+
buffer = io.BytesIO()
29
+
with wave.open(buffer, "wb") as wav:
30
+
wav.setnchannels(channels)
31
+
wav.setsampwidth(sample_width)
32
+
wav.setframerate(sample_rate)
33
+
wav.writeframes(pcm_data)
34
+
return buffer.getvalue()
20
35
21
36
22
37
def main() -> None:
···
70
85
),
71
86
)
72
87
73
-
audio_data = response.candidates[0].content.parts[0].inline_data.data
74
-
output_path.write_bytes(audio_data)
75
-
print(f"saved audio to {output_path} ({len(audio_data)} bytes)")
88
+
# gemini returns raw PCM (audio/L16;codec=pcm;rate=24000), wrap in WAV header
89
+
pcm_data = response.candidates[0].content.parts[0].inline_data.data
90
+
wav_data = pcm_to_wav(pcm_data)
91
+
output_path.write_bytes(wav_data)
92
+
print(f"saved audio to {output_path} ({len(wav_data)} bytes)")
76
93
77
94
78
95
if __name__ == "__main__":