{"slug": "how-to-build-a-podcast-intro-generator", "title": "How to Build a Podcast Intro Generator", "summary": "A developer has published a walkthrough for building a Podcast Intro Generator that combines Jinja2 script templating with ElevenLabs' text-to-speech API to produce branded episode intros as MP3 files. The pipeline injects podcast name, tagline and episode details into a template, sends the text to ElevenLabs' REST endpoint with configurable stability and similarity-boost voice settings, then post-processes the audio with fades and normalization.", "body_md": "Every podcast needs a hook—a short, memorable intro that sets the tone, tells listeners what they’re about to hear, and builds brand consistency. Recording a fresh intro for each episode can be tedious, especially for solo creators juggling editing, publishing, and promotion. With modern **voice AI** and **text‑to‑speech (TTS)** technology, you can automate that process and generate a polished intro in seconds.\n\nIn this post I’ll walk you through building a **Podcast Intro Generator** that takes a few lines of script, injects your podcast name, and spits out a high‑quality audio file ready for your editing workflow. The core of the solution relies on **ElevenLabs**, a state‑of‑the‑art TTS service that offers realistic voice cloning and easy API access. Let’s dive in!\n\n```\n+-------------------+      +--------------------+      +-------------------+\n|   User Input      | ---> |  Script Builder    | ---> |  ElevenLabs TTS   |\n| (title, tagline) |      | (template + data)  |      |  API (audio file) |\n+-------------------+      +--------------------+      +-------------------+\n                                      |\n                                      v\n                              +-----------------+\n                              |   Post‑process  |\n                              | (fade‑in/out,   |\n                              |  normalization)|\n                              +-----------------+\n                                      |\n                                      v\n                              +-----------------+\n                              |   Output File   |\n                              +-----------------+\n```\n\nElevenLabs provides a free tier that’s generous enough for testing, and a paid plan for high‑volume production. The API uses a simple REST interface and returns audio in MP3 format by default.\n\n**Quick link:** Sign up and grab your API key here → [https://try.elevenlabs.io/kr07zfuqn1bp](https://try.elevenlabs.io/kr07zfuqn1bp)\n\nOnce you have the key, you can start sending requests. Below is a minimal Python wrapper that handles authentication, voice selection, and audio retrieval.\n\n``` python\nimport requests\nimport json\nfrom pathlib import Path\n\nELEVEN_API_KEY = \"YOUR_ELEVENLABS_API_KEY\"\nBASE_URL = \"https://api.elevenlabs.io/v1\"\n\ndef generate_speech(text: str, voice_id: str = \"default\", output_path: Path = Path(\"intro.mp3\")):\n    \"\"\"Send a TTS request to ElevenLabs and save the resulting audio.\"\"\"\n    url = f\"{BASE_URL}/text-to-speech/{voice_id}\"\n    headers = {\n        \"xi-api-key\": ELEVEN_API_KEY,\n        \"Content-Type\": \"application/json\"\n    }\n    payload = {\n        \"text\": text,\n        \"model_id\": \"eleven_monolingual_v1\",\n        \"voice_settings\": {\n            \"stability\": 0.75,\n            \"similarity_boost\": 0.85\n        }\n    }\n\n    response = requests.post(url, headers=headers, json=payload)\n    response.raise_for_status()\n\n    # The API returns raw audio bytes\n    output_path.write_bytes(response.content)\n    print(f\"✅ Intro saved to {output_path}\")\n\n# Example usage\nif __name__ == \"__main__\":\n    script = \"Welcome to TechTalk, the podcast where we decode the latest in software engineering. Today we explore serverless architectures.\"\n    generate_speech(script, voice_id=\"YOUR_CLONED_VOICE_ID\")\n```\n\n**Tip:** If you don’t have a cloned voice yet, create one in the ElevenLabs dashboard. Upload a few seconds of your own voice, and the service will generate a `voice_id` you can reuse across episodes.\n\nHard‑coding the script defeats the purpose of a generator. Instead, use Python’s f‑strings or a small templating engine like **Jinja2** to inject episode‑specific data.\n\n``` python\nfrom jinja2 import Template\n\nINTRO_TEMPLATE = \"\"\"\nWelcome to {{ podcast_name }}, the show that {{ tagline }}.\nIn today's episode, \"{{ episode_title }}\", we'll dive into {{ episode_topic }}.\nStay tuned!\n\"\"\"\n\ndef build_intro(podcast_name, tagline, episode_title, episode_topic):\n    tmpl = Template(INTRO_TEMPLATE.strip())\n    return tmpl.render(\n        podcast_name=podcast_name,\n        tagline=tagline,\n        episode_title=episode_title,\n        episode_topic=episode_topic\n    )\n```\n\nNow you can call `build_intro()` with data from a CSV, a content management system, or even a simple CLI prompt.\n\n```\nscript = build_intro(\n    podcast_name=\"DevBytes\",\n    tagline=\"break down complex dev topics into bite‑size episodes\",\n    episode_title=\"Zero‑Trust Security\",\n    episode_topic=\"how to implement zero‑trust in cloud-native apps\"\n)\nprint(script)\n```\n\nThe output will be a ready‑to‑speak string that you feed into `generate_speech()` from the previous section.\n\nMost podcasts prefer a 0.5‑second fade‑in and fade‑out to smooth the transition. The **pydub** library makes this trivial.\n\n``` python\nfrom pydub import AudioSegment\n\ndef add_fade(audio_path: Path, fade_ms: int = 500) -> Path:\n    audio = AudioSegment.from_file(audio_path)\n    faded = audio.fade_in(fade_ms).fade_out(fade_ms)\n    out_path = audio_path.with_name(f\"{audio_path.stem}_faded{audio_path.suffix}\")\n    faded.export(out_path, format=\"mp3\")\n    return out_path\n\n# After generating the raw intro:\nraw_path = Path(\"intro.mp3\")\nfaded_path = add_fade(raw_path)\nprint(f\"✅ Faded intro saved to {faded_path}\")\n```\n\nCombine the steps into a single function for convenience:\n\n``` python\ndef generate_podcast_intro(data: dict, voice_id: str, out_dir: Path = Path(\".\")):\n    script = build_intro(**data)\n    raw_file = out_dir / \"intro_raw.mp3\"\n    generate_speech(script, voice_id=voice_id, output_path=raw_file)\n    final_file = add_fade(raw_file)\n    return final_file\n```\n\nIf you like the terminal, here’s a tiny click‑based CLI that ties everything together.\n\n``` python\nimport click\nfrom pathlib import Path\n\n@click.command()\n@click.option(\"--podcast\", prompt=\"Podcast name\", help=\"Your podcast's name\")\n@click.option(\"--tagline\", prompt=\"Tagline\", help=\"A short description of your show\")\n@click.option(\"--title\", prompt=\"Episode title\", help=\"Current episode's title\")\n@click.option(\"--topic\", prompt=\"Episode topic\", help=\"What you’ll discuss\")\n@click.option(\"--voice-id\", prompt=\"ElevenLabs voice ID\", help=\"Your cloned voice\")\ndef main(podcast, tagline, title, topic, voice_id):\n    data = {\n        \"podcast_name\": podcast,\n        \"tagline\": tagline,\n        \"episode_title\": title,\n        \"episode_topic\": topic,\n    }\n    out_file = generate_podcast_intro(data, voice_id, out_dir=Path(\"outputs\"))\n    click.echo(f\"✅ Your intro is ready: {out_file}\")\n\nif __name__ == \"__main__\":\n    main()\n```\n\nRun it with:\n\n``` bash\n$ python generate_intro.py\n```\n\nYou’ll be prompted for the details, and within seconds a polished intro file lands in the `outputs/` folder.\n\nA subtle music bed can elevate the vibe. Grab a royalty‑free loop (e.g., from **Free Music Archive**) and mix it with the spoken intro using pydub’s `overlay`:\n\n``` php\ndef add_music(intro_path: Path, music_path: Path, music_volume_db: int = -15) -> Path:\n    intro = AudioSegment.from_file(intro_path)\n    music = AudioSegment.from_file(music_path).apply_gain(music_volume_db)\n    # Loop music if shorter than intro\n    if len(music) < len(intro):\n        repeats = (len(intro) // len(music)) + 1\n        music = music * repeats\n    mixed = intro.overlay(music[:len(intro)])\n    out_path = intro_path.with_name(f\"{intro_path.stem}_with_music{intro_path.suffix}\")\n    mixed.export(out_path, format=\"mp3\")\n    return out_path\n```\n\nNow you can call `add_music(faded_path, Path(\"assets/loop.mp3\"))` to produce a final, broadcast‑ready intro.\n\n| Tip | Why it matters | \n|---|---|\n| **Use a consistent voice** | Listeners associate a particular timbre with your brand. Clone your own voice once and stick to that `voice_id` . | \n| **Keep scripts under 30 seconds** | Longer TTS runs increase latency and can sound less natural. Short intros stay punchy. | \n| **Normalize loudness to -16 LUFS** | Most podcast platforms target -16 LUFS; use `pydub` or`ffmpeg` to batch‑normalize if you have many episodes. | \n| **Cache generated intros** | If you re‑run the same script, store the MP3 locally to avoid unnecessary API calls (and save credits). | \n\nYou now have a complete, end‑to‑end pipeline:\n\nAll of this can be automated in a CI/CD job, a GitHub Action, or a simple cron script—so each new episode gets a fresh intro without you lifting a finger.\n\nIf you’re curious about how realistic voice cloning can streamline your podcast production, head over to ElevenLabs and grab your API key: **[https://try.elevenlabs.io/kr07zfuqn1bp](https://try.elevenlabs.io/kr07zfuqn1bp)**.  \n\nPlug the key into the snippets above, and you’ll have a custom intro generator up and running in minutes. Happy coding, and may your podcasts always start with a bang!", "url": "https://wpnews.pro/news/how-to-build-a-podcast-intro-generator", "canonical_source": "https://dev.to/voice_developer/how-to-build-a-podcast-intro-generator-56bd", "published_at": "2026-11-13 01:42:06+00:00", "updated_at": "2026-11-13 01:49:36.386982+00:00", "lang": "en", "topics": ["ai-tools", "generative-ai", "ai-products"], "entities": ["ElevenLabs", "Jinja2", "Python"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/how-to-build-a-podcast-intro-generator", "markdown": "https://wpnews.pro/news/how-to-build-a-podcast-intro-generator.md", "text": "https://wpnews.pro/news/how-to-build-a-podcast-intro-generator.txt", "jsonld": "https://wpnews.pro/news/how-to-build-a-podcast-intro-generator.jsonld"}}