Puedes crear un proyecto completo subiendo un fichero JSON en el modal «Importar proyecto». El fichero describe el título del proyecto, sus personajes y sus clips de diálogo. A continuación tienes la estructura exacta que se espera.
Campos del fichero
Campo
Tipo
Obligatorio
Descripción
title
texto
Sí
Título del proyecto. Debe tener al menos un carácter. Si ya tienes un proyecto con el mismo título, la importación activará el flujo de sobrescritura.
description
texto
No
Descripción opcional del proyecto.
language
texto (BCP-47)
No
Código de idioma BCP-47 (por ejemplo, es-ES o en-US). Si lo omites, se usa es-ES por defecto.
characters[]
lista
Sí
Lista de personajes del proyecto. Debe incluir al menos uno.
characters[].name
texto
Sí
Nombre del personaje. Debe tener al menos un carácter y es el valor que referencian los clips.
characters[].voiceDescription
texto
No
Pista textual sobre cómo debería sonar la voz. Es solo orientativa: no asigna ninguna voz.
clips[]
lista
Sí
Lista de clips de diálogo. Puede ir vacía: importarás los personajes y añadirás los clips más tarde.
clips[].character
texto
Sí
Nombre del personaje que dice el clip. Debe coincidir exactamente con el name de uno de los personajes.
clips[].text
texto
Sí
Texto que se leerá en este clip. Debe tener al menos un carácter.
Cosas importantes
Las voces no van en el JSON
El fichero no contiene voces ni proveedores. El campo voiceDescription es solo una pista textual. La voz real y el proveedor (Gemini, ElevenLabs o Local) se asignan a cada personaje en la configuración del proyecto, después de importar.
Importar sobre un título existente
Si importas un fichero cuyo título coincide con el de un proyecto que ya tienes, se activa el flujo de sobrescritura. Si el proyecto de destino ya tiene clips con audio generado, la aplicación te pedirá confirmación antes de continuar.
Los nombres de personaje deben coincidir exactamente
Cada clip apunta a su personaje por el nombre y la comparación es literal: «Marta» y «marta» son distintos, y un espacio de más al final también rompe la correspondencia. Si un clip cita un nombre que no está en characters, no se importa nada: la operación se cancela entera y el aviso indica cuál falla, con el texto en inglés «Clip references unknown character». Revisa mayúsculas, tildes y espacios antes de subir el fichero.
El campo «force»
Déjalo siempre en false en tu JSON. Sirve para confirmar la sobrescritura de un proyecto que ya tiene clips, pero la aplicación lo activa automáticamente cuando aceptas el aviso de sobrescritura; no es un campo que debas poner en true a mano.
Ejemplo válido
Este ejemplo cumple el formato y puedes subirlo tal cual en el modal de importar.
{
"title": "Mi primer podcast",
"description": "Un episodio de ejemplo con dos personajes.",
"language": "es-ES",
"characters": [
{
"name": "NARRADOR",
"voiceDescription": "Voz cálida y pausada, tono divulgativo."
},
{
"name": "INVITADA",
"voiceDescription": "Voz enérgica y cercana."
}
],
"clips": [
{
"character": "NARRADOR",
"text": "Bienvenidos a un nuevo episodio del podcast."
},
{
"character": "INVITADA",
"text": "Gracias por la invitación, me hace mucha ilusión estar aquí."
},
{
"character": "NARRADOR",
"text": "Empecemos por el principio de la historia."
}
]
}
Generar el JSON con un LLM
Si no quieres escribir el JSON a mano, pega el guion de tu episodio en un asistente de IA (ChatGPT, Claude, Gemini…) usando este prompt: te devolverá un JSON válido listo para importar. Sustituye «[PASTE THE PODCAST TEXT HERE]» por el texto de tu podcast antes de enviarlo.
You are a podcast-script-to-JSON converter. You will receive the text of a podcast episode in any format (named-speaker dialogue, stage-play script, transcript, narrated prose, etc.) and you must return ONLY a valid JSON object in the format described below. Write NOTHING before or after the JSON: no explanations, no comments, no code fences (```). Your reply must start with { and end with }.
========================
OUTPUT FORMAT (exact)
========================
{
"title": "string",
"description": "string",
"language": "es-ES",
"force": false,
"characters": [
{ "name": "Name", "voiceDescription": "[tag] [tag] ..." }
],
"clips": [
{ "character": "Name", "text": "clip text" }
]
}
========================
ROOT FIELDS
========================
- title (REQUIRED, min. 1 char): the episode title. If the source text has a title, use it; otherwise generate a short, descriptive one.
- description (optional): 1-2 sentences summarizing the episode.
- language (optional): language code. Set it to the ORIGINAL language of the source text you are converting — detect it from the content, do NOT translate. Use a BCP-47-style code: e.g. "es-ES" (Spanish), "en-US" (English), "fr-FR" (French), "de-DE" (German), "it-IT" (Italian), "pt-BR" (Portuguese). If you can detect the language but not the region, use the most common region for that language.
- force: ALWAYS leave it as false.
- characters (REQUIRED, min. 1 entry).
- clips (REQUIRED): each clip is ONE voice line. The ORDER of the array IS the position (1, 2, 3…). Do NOT add any position field.
There is NO "meta" object and NO "author" field. title, description, language and force live at the root.
========================
CHARACTERS
========================
- One entry per voice that speaks in the podcast, INCLUDING the narrating voice (call it "Narrador").
- name: unique within the project, with an initial capital (e.g. "Narrador", "Luna", "Ogro"). It must match CHARACTER FOR CHARACTER (same letters, same upper/lowercase) the "character" of its clips.
- voiceDescription: optional but recommended. ALWAYS in ENGLISH, with audio-tags in brackets (max. 4-5): age, energy, timbre, base emotion. Examples: "[warm] [slow] [storytelling]", "[energetic] [young] [curious]", "[raspy] [old] [wise]". Infer it from cues in the source text; if there are none, give a reasonable description or leave it as "".
========================
CLIPS — conversion rules
========================
1. Each spoken line (narration or dialogue) → one object { "character": ..., "text": ... }.
2. VOICE ONLY. NEVER put into clips: music, sound effects, pauses, ambiences, stage directions, or production notes. All of that is OMITTED from the JSON (it gets added later in the app). Discard lines such as: [MUSIC: …], [SOUND: …], [SFX], [PAUSE: N], (wind blows), [intro music], *laughter in background*, etc.
3. There are NO type, mood, duration, position or per-clip description fields. Each clip has EXACTLY two fields: "character" and "text".
4. text: the clean text of the line, WITHOUT the character name in front and WITHOUT sound directions.
5. Keep the EXACT order of the source script.
========================
EMOTION / TONE (inline, optional)
========================
Emotion is NOT a separate field: if a line has a clear emotion, place it at the START of "text", in brackets and in English. Use at most ONE tag per clip and only when it adds value; if the line is neutral, leave the text clean.
Use ONLY these tags (map the source emotion to the closest one; if none fits, use no tag). Keep the tag in English even when the line itself is in another language:
[whispers] [excited] [trembling] [serious] [giggles] [shouting] [tired] [curious] [amazed] [crying] [sighs] [gasp] [laughs] [mischievously] [panicked] [sarcastic]
Example: { "character": "Luna", "text": "[whispers] ¿Quién anda por aquí tan tarde?" }
========================
MERGE RULE
========================
If the SAME character speaks two or more lines IN A ROW with nothing in between (no other character, no music/sound/pause), merge them into ONE clip joining the texts with a space, and do NOT add an inline emotion tag.
If between two lines of the same character there was an effect, music, pause or another voice, KEEP them as separate clips (this leaves a natural point to insert that effect later in the app).
========================
FINAL VALIDATION (before replying)
========================
- Every "character" in clips exists in characters, with the same upper/lowercase.
- characters has ≥ 1 entry and clips has ≥ 1.
- No music, sounds or pauses inside clips.
- No clip has extra fields: only "character" and "text".
- "language" reflects the source text's original language.
- The JSON is syntactically valid and is the ONLY thing you return.
========================
PODCAST TO CONVERT
========================
[PASTE THE PODCAST TEXT HERE]
Pruébalo con tu propio guion
El plan gratuito genera audio con voces de IA sin tarjeta y sin instalar nada.