Perché il mio podcast ha tre feed RSS (e probabilmente dovrebbe averli anche il tuo)

Hygraph, Clever Cloud Cellar, Mux e l'arte di servire Apple Podcasts per primo senza rompere Spotify

Clément Sauvage20 min di lettura
Perché il mio podcast ha tre feed RSS (e probabilmente dovrebbe averli anche il tuo)

Ho costruito lo stack tecnico di ⌘+P: The App Podcast come farebbe uno sviluppatore di app, non come un podcaster che rattoppa Spotify for Podcasters. Ecco cosa succede quando tratti l'RSS come un prodotto.

I primi episodi di ⌘+P li ho registrati da Podspace, a Parigi: una vera cabina, microfoni veri e un vero tecnico del suono, che non finge di capire quando gli parli di bus AES e uscita monitor. Il montaggio lo faccio sul mio Mac con Final Cut Pro. Diciamolo: uno sviluppatore Apple che montasse il suo podcast con Premiere sarebbe come uno chef italiano che mette la panna nella carbonara. Si sente, e la gente ti giudica (giustamente).

Avevo sottovalutato una cosa: registrare e montare rappresenta circa il 20% del lavoro. Il resto è distribuzione. E nel 2026 la distribuzione di un podcast è un terreno molto più insidioso di quanto sembri.

Questo articolo è l'autopsia tecnica dello stack che ho costruito per ⌘+P: tre feed RSS diversi, un CMS headless, un CDN personalizzato, un encoder video adattivo e un'ossessione dichiarata per Apple Podcasts. Se vuoi lanciare un podcast serio senza passare da Acast o Spotify for Podcasters, probabilmente è l'articolo in francese più approfondito che troverai quest'anno sull'argomento.

La scommessa: trattare l'RSS come un prodotto

La domanda che mi ha risparmiato sei mesi di tentativi a vuoto: voglio che il mio podcast viva sulla piattaforma di qualcun altro o voglio che viva a casa mia?

Spotify for Podcasters (in precedenza Anchor) propone un accordo apparentemente imbattibile: carichi il tuo file .wav, loro generano un feed RSS, ospitano l'audio e lo distribuiscono su Apple Podcasts. Gratis. La trappola, ovviamente, è che il feed RSS appartiene a loro. Se un giorno vuoi cambiare hosting, puoi portarti dietro l'archivio, ma perdi le statistiche, i link canonici e a volte la legittimità presso le directory che ti hanno indicizzato dal feed Anchor originale. Acast segue la stessa logica, con un'esperienza più professionale e una fattura mensile.

Io ho scelto il contrario. Il feed RSS è un endpoint che controllo io, sul mio dominio, generato dal mio codice a partire dalla mia unica fonte di verità. Apple, Spotify, Pocket Casts, Castro, Overcast: tutti si abbonano al mio feed. Se domani Spotify diventa ostile, cambio due righe di XML, non il provider.

Questa scelta ha un effetto a cascata: se gestisco l'RSS devo gestire anche tutto ciò che lo circonda. CMS, archiviazione audio e video, encoding, CDN, capitoli, metadati Podcasting 2.0 e varianti per piattaforma. È più lavoro, ma anche infinitamente più formativo, e lo stack che ne è uscito è sorprendentemente leggero.

La fonte di verità: Hygraph

I contenuti vivono in Hygraph, un CMS headless basato su GraphQL. Il modello PodcastEpisode contiene tutto ciò che ti aspetti: stagione, numero di episodio, ospiti, capitoli, URL audio e video, show notes in rich text, date e flag isPrivate e showOnHomepage. Gli ospiti sono entità separate PodcastGuest, con una propria bio rich text e linkedinUrl: lo stesso ospite può tornare, e duplicare una bio in due record diversi è il genere di peccato che si rimpiange sei mesi dopo. Il video vive invece in un'entità Video riutilizzabile, referenziata da PodcastEpisode. Ci torno: è diventata centrale.

Il sito è sviluppato con Next.js 16 App Router, Turbopack e Tailwind v4, distribuito su Clever Cloud con redeploy automatico a ogni push Git. Il livello GraphQL usa Apollo Client. L'i18n passa da next-intl con sette locale (en, fr, de, it, nl, ar-AE, ar-SA) e localePrefix: 'as-needed'. Un dettaglio importante: il podcast è francofono, quindi anche se il visitatore arriva su /de/podcast, il feed forza locales: ['fr', 'en'] su Hygraph. L'RSS non è multilingue: è bilingue per definizione, come Apple Podcasts si aspetta indipendentemente da dove clicchi.

Lo storage: Clever Cloud Cellar dietro Cloudflare

I file multimediali (audio, video, copertine) vivono su Clever Cloud Cellar, il loro storage compatibile con S3, dietro un CDN Cloudflare su cdn2.clementsauvage.me. La scelta non è ovvia, quindi la spiego.

Mux è allettante per fare tutto: encoding, streaming e distribuzione. Ma con un podcast video che può pesare 250 MB per episodio, i costi di Mux diventano rapidamente insostenibili se moltiplichi i download RSS. Cellar ha un prezzo prevedibile per gigabyte, byte-range nativo (verificato: Range: bytes=0-1023 restituisce HTTP 206) e l'app è già distribuita su Clever Cloud, quindi la latenza tra servizi è trascurabile. Il byte-range è indispensabile: i client podcast non scaricano mai tutto il file in una volta, lo riproducono progressivamente e si aspettano di poter riprendere.

Mux resta in uso, ma solo per lo streaming web: HLS adattivo tramite playbackId, riprodotto con mux-player-react nel browser sulla pagina dell'episodio. Il video incorporato sul sito beneficia di un encoding ladder professionale gestito da Mux; il master MP4 H.264 su Cellar serve esclusivamente per la distribuzione RSS. Due usi, due file, due strategie. Si paga più storage, ma ciascun file fa il suo lavoro senza compromessi.

L'admin d'importazione: prima il contesto, poi il contenuto

Ho un endpoint privato, uno strumento che prende un file .mp3 grezzo esportato da Final Cut e una copertina JPEG, poi crea in Hygraph una bozza di episodio pronta per essere approvata.

La lezione UX che mi è costata una riscrittura: il contesto deve arrivare prima del contenuto. Nella prima versione mettevo i file in alto e i campi Stagione / Episodio / Tipo / Lingua in fondo. Logico per il modulo, disastroso per la pipeline, perché quei quattro campi determinano il percorso di upload su Cellar (cmd-p-podcast/s{n}/episode-{m}/audio.wav). Se carichi i file prima di scegliere la stagione, il server ti respinge o indovina, e ti ritrovi l'episodio 12 nella cartella dell'episodio 11. Ho invertito l'ordine: griglia 2×2 per il contesto, drop zone dopo. Il modulo ora non consente l'upload finché tutti e quattro i campi non sono compilati. Mai più quel bug.

L'upload è un multipart S3 presigned eseguito dal browser: il server genera URL firmati per blocchi da 64 MB, il browser fa PUT direttamente su Cellar e il server riceve gli ETag con cui comporre il multipart alla fine. Un endpoint dedicato configura il CORS del bucket con ExposeHeaders: ETag. Senza, il browser non può leggere gli ETag e il completamento fallisce in silenzio. Un dettaglio che non trovi nella documentazione S3 per il grande pubblico.

Per i teaser uso una convenzione di naming specifica: un suffisso alfanumerico di sette caratteri, scelti da un alfabeto di 55 simboli (escludendo 0, 1, I, O, i, l, o per evitare confusioni visive). La chiave viene rigenerata ogni volta che si attiva la modalità TEASER ed è condivisa tra i tre file dello stesso teaser (audio/video/copertina). Così possono coesistere diversi teaser della stessa stagione/episodio senza sovrascriversi, e l'URL si può dettare al telefono. Tre righe di codice che evitano di dover rimproverare un ospite perché hai sovrascritto il suo teaser con un altro.

Dopo l'upload, la pipeline completa è questa: Mux acquisisce il video e genera un asset, un playback ID e una miniatura a un timestamp scelto. AssemblyAI trascrive l'audio e crea capitoli automatici. Nell'admin appare un'anteprima adatta all'editing, con descrizione breve, show notes e capitoli (titolo / inizio / fine). Tutto si può modificare prima della scrittura in Hygraph. All'approvazione creiamo una bozza PodcastEpisode con episodeGuid UUID stabile, asset Mux referenziato, trascrizione AssemblyAI e capitoli separati dal blocco delle show notes. L'interfaccia del sito e il JSON <podcast:chapters> li espongono separatamente: unirli sarebbe un errore architetturale da pagare a ogni aggiornamento.

L'RSS: tre feed, tre strategie

Qui le cose si fanno interessanti. Apple Podcasts ha la priorità. È il feed principale, l'unico aggiornato in tempo reale e l'unico che riceve tutte le funzionalità Podcasting 2.0. Spotify e gli altri vengono dopo.

In concreto, ho tre endpoint:

  • /podcast/rss — feed principale, episodi pubblicati subito, Podcasting 2.0 completo
  • /podcast/rss/late — stessi contenuti, con tre giorni di ritardo
  • /podcast/rss/spotify — solo audio, ritardo di tre giorni e piena conformità alle regole Spotify

Il ritardo di tre giorni è una scelta editoriale deliberata. Apple Podcasts riceve l'episodio il martedì mattina. Spotify e le directory secondarie lo ricevono il venerdì. Per quelle 72 ore, chi ascolta tramite Apple Podcasts ha un vantaggio temporale esclusivo. È il mio modo di premiare la piattaforma che ha sostenuto l'ecosistema dei podcast per vent'anni e, già che ci sono, di spingere gli ascoltatori verso il client che rispetta meglio la natura di un podcast: un file RSS, non una playlist algoritmica.

Nel codice il filtro è !episode.isPrivate && isVisibleInDelayedFeed(...). Il significato di isPrivate mi è costato mezz'ora di confusione: un episodio privato è nascosto dal feed RSS ma visibile sul sito. È esattamente il contrario di quello che il mio cervello pensa al primo impatto, quindi l'ho annotato nel codice e lo scrivo qui per non sbagliarmi più. Così posso mostrare sul sito un teaser o una puntata riservata ai sostenitori senza riempire Apple o Spotify.

Cosa metto nel feed Apple

Il feed principale usa Podcasting 2.0 senza riserve. Il namespace xmlns:podcast è dichiarato su <channel> e produciamo:

  • <podcast:guid> — UUID stabile dello show, indipendente dall'URL del feed
  • <podcast:updateFrequency rrule="FREQ=WEEKLY;INTERVAL=2;BYDAY=TU" dtstart="2026-05-05T05:00:00Z">Un mardi sur deux</podcast:updateFrequency> — cadenza ufficiale, leggibile dalle macchine
  • <podcast:person> per il conduttore (Clément Sauvage, role="host", href, avatar Cellar) e uno dinamico per ogni ospite (role="guest", immagine Hygraph, nome e azienda nel testo)
  • <podcast:chapters> con un riferimento a JSON esterno di tipo application/json+chapters
  • <podcast:alternateEnclosure> per offrire audio e video nello stesso <item>

Nel namespace Apple iTunes c'è tutto: itunes:author, itunes:type impostato su episodic, itunes:image (l'obbligatoria copertina 3000×3000, ci torno tra poco), itunes:category impostato su Technology, itunes:explicit e itunes:owner con itunes:name e, soprattutto, itunes:email. Negli item ci sono itunes:episodeType (full o trailer), itunes:title, itunes:episode, itunes:season, itunes:duration in secondi e l'immagine dell'episodio, con fallback alla copertina del canale.

L'<enclosure> principale punta al video MP4 H.264 quando l'episodio ne ha uno; l'audio passa in podcast:alternateEnclosure. Senza video, l'audio diventa l'<enclosure> principale. Il MIME type deriva dall'URL tramite mimeTypeFromUrl, che individua l'estensione del percorso ignorando le query string. Apple richiede un'estensione valida, e gli URL Cellar firmati possono avere parametri di query che farebbero fallire il validatore senza questa precauzione.

La trappola della copertina: 3000×3000 o niente

Ho disegnato la copertina in Figma, ormai il mio strumento predefinito per quasi tutti gli asset visivi statici: vettori puliti, esportazioni semplici in più risoluzioni e varianti (copertina dello show, dell'episodio e miniature dei capitoli) sincronizzate tramite componenti. Ed è qui che arriva la trappola.

Apple Podcasts vuole una copertina quadrata, JPEG, minimo 3000×3000. Primo export da Figma, primo upload, rifiuto di Apple: 3000×3004. Quattro pixel in più in altezza. Un frame Figma con un padding interno non perfettamente pari non si nota a occhio, ma basta a mandare in errore il validatore. Il feed è stato rifiutato. Ho ritagliato l'immagine in Figma esattamente a 3000×3000, esportato di nuovo e ricaricato su cdn2.clementsauvage.me/cmd-p-podcast/cmdp-cover.jpg, verificando con curl che accept-ranges: bytes venisse restituito, poi ho inviato di nuovo tutto. Approvato.

Se da questo articolo impari una cosa sola: controlla le dimensioni al pixel prima di inviare. Apple non dà un messaggio d'errore chiaro, solo un rifiuto e poi devi cercare il problema. E imposta il frame Figma esplicitamente a 3000×3000, non “più o meno quadrato”.

I capitoli in JSON esterno

Invece di inserire i capitoli direttamente nell'XML, lo standard Podcasting 2.0 raccomanda un JSON esterno. Ho un endpoint /podcast/{slug}/chapters.json che restituisce la specifica PodcastIndex 1.2.0:

{
  "version": "1.2.0",
  "title": "...",
  "podcastName": "⌘+P: The App Podcast",
  "author": "Clément Sauvage",
  "chapters": [
    {
      "startTime": 0,
      "endTime": 90,
      "title": "Intro",
      "img": "...",
      "url": "..."
    }
  ]
}

Fallback per le immagini dei capitoli, in cascata: chapter.imageUrl da Hygraph, altrimenti miniatura Mux al timestamp t=startTime, infine la copertina dell'episodio. Il Content-Type è impostato esplicitamente su application/json+chapters; charset=utf-8, perché il default Next application/json non viene riconosciuto da tutti i client. Cache s-maxage=900, stale-while-revalidate=3600 per non richiamare Hygraph a ogni tap in Castro.

Il doppio <description> e <content:encoded>

La maggior parte dei provider si limita a un <description> essenziale. Io emetto entrambi: un <description> in testo semplice per la compatibilità universale (anche con i vecchi client che non leggono HTML) e un <content:encoded> con una versione HTML pulita dello stesso contenuto. Entrambi contengono le show notes, una sezione Timeline con timestamp nel formato MM:SS o H:MM:SS oltre l'ora, una bio breve del conduttore e una bio per ogni ospite con intestazione Avec {nom} — {role} chez {company}.

Un dettaglio che mi ha fatto perdere tempo: il rich text di Hygraph estratto come .text restituiva \n letterali (la sequenza backslash-n, non un vero ritorno a capo) perché era memorizzato codificato in JSON. Una funzione unescapeNewlines lo converte prima del rendering. Senza, il feed mostrava \n come testo visibile in tutti i client podcast. Ottimo per la credibilità.

Il feed Spotify: tutto quello che piace ad Apple, escluso

Spotify è esigente e particolare. La sua specifica ufficiale vieta o ignora alcune cose che Apple adora. Il mio feed /podcast/rss/spotify è quindi una variante rigorosa:

  • Nessun namespace podcast:* — Spotify non sa che farsene e preferisce che non ci sia
  • Nessun podcast:alternateEnclosure — stesso motivo
  • Nessun atom:link — Spotify lo preferisce così
  • itunes:owner con itunes:email — richiesto dal supporto per verificare il feed
  • Nessun itunes:title ridondante negli item
  • Solo audio — Spotify non supporta il video via RSS, quindi <enclosure> contiene sempre MP3 o WAV
  • Capitoli nel formato Podlove Simple Chapters, non Podcasting 2.0:
<psc:chapters version="1.1">
  <psc:chapter start="0:00" title="..." href="..." image="..." />
</psc:chapters>

Il namespace xmlns:psc="http://podlove.org/simple-chapters" viene aggiunto solo se l'episodio ha capitoli, perché alcuni validatori si lamentano dei namespace dichiarati ma mai usati.

Tutto questo è gestito dal parametro mediaMode: 'default' | 'audio' passato a getPodcastRss(...). Il builder è uno solo; i feed sono proiezioni diverse. Niente codice duplicato e nessuna divergenza tra le due varianti.

Encoding video per l'RSS: H.264 e basta

Volevo usare HEVC perché è più efficiente, il mio Mac Studio lo codifica in hardware e i file pesano il 40% in meno. Errore. HEVC non funziona nel percorso RSS. Pocket Casts, Overcast e Castro non decodificano HEVC nel contesto di un podcast. Apple Podcasts lo accetta con l'upload diretto in Podcasts Connect, ma non via RSS. Risultato: un file che metà degli ascoltatori non riesce a riprodurre, senza un messaggio d'errore chiaro.

La regola per l'RSS è: MP4 H.264, AAC stereo, punto. Ecco la ricetta ffmpeg che uso:

ffmpeg -i source.mov \
  -c:v libx264 -profile:v high -preset slow -crf 23 \
  -vf "scale=1280:720" -pix_fmt yuv420p -movflags +faststart \
  -c:a aac -b:a 256k -ar 48000 \
  out.mp4

Alcune scelte meno ovvie:

  • 720p, non 1080p né 4K. Per persone che parlano in una conversazione con pochi movimenti, 1280×720 è il punto giusto. Il 4K è sprecato, il 1080p aggiunge peso senza un beneficio percettibile.
  • CRF 23 + preset slow invece di un bitrate fisso. L'encoding è più lento, ma il rate control è migliore e le scene statiche vengono compresse automaticamente.
  • AAC stereo a 256 kbps — è la raccomandazione Apple; a 128 kbps si sente la differenza sulle voci.
  • -movflags +faststart sposta l'atomo moov all'inizio del file. Senza, il client deve scaricare tutto prima di avviare la riproduzione. Con, lo streaming progressivo funziona dai primi kilobyte.
  • -pix_fmt yuv420p — senza questo flag ffmpeg può produrre yuv444p, rifiutato da alcuni player. Sei caratteri risparmiano ore di debug.

Risultato concreto: un teaser è passato da 120 MB (export FCP H.264 a 9,8 Mbps) a 26,4 MB, senza differenze visibili. Un episodio di 22 minuti pesa circa 250 MB: ragionevole per un download RSS in rete mobile.

E se usi Permute per elaborare gli encoding in batch: disattiva sempre “Allow copying of HEVC tracks”. Altrimenti il programma copia lo stream e ti ritrovi un MP4 con HEVC, proprio quello che volevi evitare.

La dimensione del file nell'RSS e perché Video.sourceSizeBytes

Un piccolo dettaglio che cambia tutto per i client podcast: l'attributo length di <enclosure> deve indicare la dimensione esatta del file in byte. Apple Podcasts la usa per calcolare la barra di avanzamento del download. Se il valore è errato o manca, alcuni client mostrano un progresso sballato o rifiutano il download.

Su PodcastEpisode avevo già audioSizeBytes, calcolato durante l'upload. Quando ho aggiunto il video all'<enclosure> principale, ho dovuto aggiungere il corrispettivo all'entità Video: il nuovo campo opzionale Video.sourceSizeBytes. PodcastEpisode aveva già la relazione video con Video, così ho aggiunto anche Video.sourceUrl a quell'entità, invece di duplicare l'URL su PodcastEpisode. Quando un episodio ha un video, il generatore RSS usa video.sourceUrl e video.sourceSizeBytes; altrimenti ripiega su URL audio e audioSizeBytes.

Dopo ogni migrazione Hygraph rigenero i tipi GraphQL (src/gql/graphql.ts e src/gql/gql.ts), e il codice RSS gestisce correttamente entrambi i casi. Sono cinque righe in più nel builder, ma sono quelle che trasformano “funziona sul mio computer” in “funziona su Castro con il 4G”.

Produzione assistita dall'IA: intro video, trailer, RSS

Ci sono tre parti del lavoro in cui ho lasciato che i modelli generativi facessero il loro mestiere, sapendo che è anche ciò che rende sostenibile uno stack da solo.

La video intro dello show, il pre-roll che apre ogni episodio, è nata da una semplice foto scattata con l'iPhone, animata con il modello video Happy Horse 1.0. Dura pochi secondi ma dà allo show una firma visiva, cosa che non sarei mai riuscito a fare bene in un weekend con After Effects. Il costo marginale è irrisorio, il risultato è coerente con l'identità e nessuno chiede “chi ha fatto la tua intro”: ed è proprio questo il punto.

Il trailer audio che gira sui social e compare nel feed con <itunes:episodeType>trailer</itunes:episodeType> è stato prodotto con Suno. Non per la solita musica di sottofondo (che preferisco ancora comporre o licenziare correttamente), ma per creare un breve teaser musicale calibrato sul formato trailer podcast: energico, riconoscibile, con i diritti chiari. La sigla principale segue una logica diversa, più artigianale; per un trailer utile solo poche settimane, Suno è lo strumento giusto.

E poi soprattutto Codex. La parte RSS di questo stack — in particolare la convivenza dei tre feed, la gestione di mediaMode, le varianti dei capitoli tra Podcasting 2.0 e Podlove Simple Chapters, il namespace dinamico in base agli episodi e la gestione dei newline — è stata scritta insieme a Codex in pair programming. Non generata e incollata: co-scritta. Io definisco il contratto (cosa deve produrre ogni feed, cosa accetta Podbase, cosa rifiuta Spotify), Codex propone la meccanica XML, io verifico i casi limite che solo chi ha già visto rifiutare il proprio feed conosce. Rileggo tutto il codice e me ne assumo la responsabilità, ma da solo non l'avrei scritto così in fretta. Dire il contrario sarebbe disonesto. E sto perdendo la pazienza con gli sviluppatori che nel 2026 sostengono ancora che l'IA li rallenti.

È anche per questo che lo stack richiede tre weekend e costa 12 € al mese. Non perché siamo diventati più intelligenti, ma perché gli strumenti rendono sostenibile il lavoro artigianale individuale dove cinque anni fa serviva un team.

Validazione e debugging: cosa mi ha salvato

Tre strumenti che consiglio senza esitazione:

Podbase verifica il feed rispetto alle specifiche Apple, Spotify e Podcasting 2.0. All'inizio mi ha segnalato l'assenza del namespace podcast: (avevo dimenticato di dichiararlo), un falso positivo sul byte-range “non supportato” (il validatore testava un feed vuoto mentre tutti gli episodi avevano isPrivate attivo) e un altro falso positivo sullo “0% di enclosure con estensione valida”, per lo stesso motivo. Morale: valida con almeno un episodio pubblico, altrimenti insegui bug inesistenti.

curl + ffprobe + MediaInfo per controllare gli enclosure: HTTP 200, content-type, accept-ranges, codec video (H.264 contro HEVC), dimensioni precise (1280×720, non una misura a caso). Un curl -I sull'URL dell'enclosure ti dice in tre secondi se Cellar risponde bene. Un ffprobe -v error -show_entries stream=codec_name,width,height mostra in due secondi se il file è conforme.

Log di Clever Cloud + bun build in locale per riprodurre i crash runtime. Due esempi che mi sono costati una serata ciascuno:

  • Un errore DYNAMIC_SERVER_USAGE di Apollo eseguiva una fetch non memorizzata nella cache durante il rendering di una route SSG. Soluzione: Promise.allSettled sulla query Hygraph nella route dell'immagine OG, così un 5xx Hygraph non fa saltare la generazione della card.
  • Un crash Satori Cannot read properties of undefined (reading '256') mentre generava l'immagine OG dinamica con il font variabile Rethink Sans. Satori non supporta i font variabili. Lezione da ricordare: niente font variabili in next/og. Ho sostituito il simbolo ⌘ disegnato come testo con un SVG inline e il crash è sparito.

Decisioni strutturali, col senno di poi

Se dovessi riassumere la filosofia in cinque punti:

SSG ovunque tranne nel player. La pagina /podcast e ogni /podcast/[slug] sono generate staticamente con generateStaticParams. Il player video Mux e il tag <audio> sono gli unici componenti client che fanno streaming on demand. SEO al massimo, pagine memorizzabili nella cache CDN e time-to-first-byte sotto i 100 ms.

Hygraph come fonte unica. Nessun database separato, nessuna migrazione di schema da gestire, nessun pannello admin personalizzato da mantenere. L'admin d'importazione crea la bozza, io approvo manualmente ogni episodio e Hygraph lo pubblica. Un solo stato canonico.

Cellar come storage primario, Mux come lusso opzionale. Il master video MP4 H.264 vive su Cellar e alimenta l'RSS. Mux crea una versione HLS adattiva dello stesso video per il web. Se domani Mux sparisce, il sito perde lo streaming adattivo ma il podcast continua senza interruzioni.

Podcasting 2.0 come elemento di prima classe, non opzionale. Namespace podcast:, tag person, JSON dei capitoli, updateFrequency, alternateEnclosure. L'investimento è minimo visto che generiamo già da soli l'XML. Il vantaggio su Castro, Pocket Casts e Fountain è enorme.

Apple Podcasts per primo, in modo consapevole e concreto. Tre giorni di anticipo su Spotify. Tutti i tag Podcasting 2.0. Copertina 3000×3000 al pixel. La piattaforma che ha inventato il formato merita un vero sforzo tecnico, non solo un tweet gentile (Cupertino, ti costerà un biglietto per la Dubdub. Un bacio).

Dove porta tutto questo

⌘+P non è un esperimento di marketing per vendere consulenza, anche se faccio il consulente. È il progetto di un artigiano che voleva scoprire se fosse possibile costruire una pipeline podcast moderna e pulita, senza dipendere da nessuno e usando gli strumenti del 2026 invece di quelli del 2018. Dopo due mesi di lavoro intenso, la risposta è sì, ma solo accettando due cose. L'RSS è un prodotto a sé, non un file generato alla fine. E la produzione assistita dall'IA non è una scorciatoia di cui vergognarsi, ma una parte essenziale di ciò che rende sostenibile il lavoro individuale: Figma per le immagini, Happy Horse per animare una foto dell'iPhone nell'intro, Suno per il trailer, Codex per metà del codice RSS. Senza questi strumenti non farei questo podcast. Con loro, lo faccio bene.

La prossima iterazione probabilmente includerà le trascrizioni via <podcast:transcript> (ho già i file SRT di AssemblyAI, sono tre righe XML), una versione inglese del feed per raggiungere il pubblico anglofono e una dashboard di analytics che analizzi le richieste Range a Cellar per ricostruire le curve d'ascolto episodio per episodio. Niente Spotify Wrapped, niente Chartable: solo i miei log.

Se stai costruendo un podcast e sei indeciso tra Acast e il fai-da-te: lo stack che ho appena descritto mi è costato circa tre weekend di codice e circa 12 € al mese di infrastruttura (Clever Cloud + Cellar + tier gratuito di Hygraph + tier gratuito di Mux fino a un certo volume). Costa più di zero. È anche la differenza tra affittare il tuo feed e possederlo.

Il primo episodio di ⌘+P esce martedì 5 maggio 2026. Se ti interessano tecnologia, prodotto, artigianato software o semplicemente le persone che fanno bene le cose, iscriviti prima su Apple Podcasts: non perché sia migliore, ma perché lì esce tre giorni prima.

E se hai un progetto eccezionale, contattami. Innovare è ciò che mi fa vibrare.

Blog

Articoli correlati