Puoi creare un progetto completo caricando un file JSON nella finestra «Importa progetto». Il file descrive il titolo del progetto, i suoi personaggi e i suoi clip di dialogo. Di seguito trovi la struttura esatta che ci si aspetta.
Le voci non vanno nel JSON
Il file non contiene voci né fornitori. Il campo voiceDescription è solo un'indicazione testuale. La voce reale e il fornitore (Gemini, ElevenLabs o Local) si assegnano a ogni personaggio nella configurazione del progetto, dopo l'importazione.
Importare su un titolo già esistente
Se importi un file il cui titolo coincide con quello di un progetto che hai già, si attiva il flusso di sovrascrittura. Se il progetto di destinazione ha già clip con audio generato, l'applicazione ti chiederà conferma prima di continuare.
I nomi dei personaggi devono coincidere esattamente
Ogni clip punta al suo personaggio tramite il nome e il confronto è letterale: «Marta» e «marta» sono diversi, e anche uno spazio di troppo alla fine rompe la corrispondenza. Se un clip cita un nome che non sta in characters, non si importa niente: l'operazione viene annullata per intero e l'avviso indica quale fallisce, con il testo in inglese «Clip references unknown character». Controlla maiuscole, accenti e spazi prima di caricare il file.
Il campo «force»
Lascialo sempre su false nel tuo JSON. Serve per confermare la sovrascrittura di un progetto che ha già clip, ma l'applicazione lo attiva automaticamente quando accetti l'avviso di sovrascrittura; non è un campo che devi impostare su true manualmente.
Questo esempio rispetta il formato e puoi caricarlo così com'è nella finestra di importazione.
{
"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."
}
]
}
Se non vuoi scrivere il JSON a mano, incolla il copione del tuo episodio in un assistente IA (ChatGPT, Claude, Gemini…) usando questo prompt: ti restituirà un JSON valido pronto da importare. Sostituisci «[PASTE THE PODCAST TEXT HERE]» con il testo del tuo podcast prima di inviarlo.
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]