Skip to content

gcomneno/gyte

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GYTE

GiadaWare YouTube Toolkit Extractor — extract transcript, audio e video da YouTube via yt-dlp + bash.

GYTE è una mini–suite da linea di comando per scaricare da YouTube in modo pulito:

  • Trascrizioni testuali (pulite da timestamp e markup)
  • Solo audio (MP3, qualità configurabile)
  • Video completo (MP4, best audio+video uniti)
  • Reflow del testo (una frase per riga, a partire dai transcript)
  • Traduzione assistita via AI dei transcript (tramite comando esterno configurabile)
  • Trascrizione locale di file audio/video via Whisper (opzionale)

Basato su yt-dlp, con script pensati per corsi interi e playlist lunghe.

⚠️ GYTE non aggira alcuna protezione DRM.
Usa YouTube tramite yt-dlp così com'è.
Sta a te rispettare Termini di Servizio e copyright dei contenuti.


Requisiti

  • Linux / macOS (servono: bash, sed, awk, xargs)

  • Python 3 (se usi yt-dlp via pip)
    oppure il binario standalone di yt-dlp per Linux

  • yt-dlp nel PATH, ad esempio:

    pip install yt-dlp

    oppure (esempio binario standalone):

    curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux -o ~/.local/bin/yt-dlp
    chmod +x ~/.local/bin/yt-dlp
  • ffmpeg installato (per l'estrazione audio/video)

  • Per il modulo AI opzionale (gyte-translate + gyte-openai):

    • Python 3

    • libreria openai installata nel tuo ambiente:

      pip install openai
  • Per la trascrizione locale con Whisper (gyte-whisper-local, opzionale):

    • Python 3

    • tool Whisper CLI installato (ad esempio via openai-whisper in un venv):

      python3 -m venv ~/venv/whisper
      source ~/venv/whisper/bin/activate
      pip install -U openai-whisper

🔍 gyte-doctor

Per verificare velocemente se l'ambiente è pronto per usare GYTE:

gyte-doctor

Controlla:

  • presenza di yt-dlp nel PATH
  • presenza di ffmpeg nel PATH
  • $HOME/.local/bin nel PATH
  • eventuale runtime JS (node/deno) come dipendenza opzionale (soft)

Ritorna exit code 0 se le dipendenze essenziali sono OK, 1 altrimenti.


Installazione

Clona il repository:

git clone https://github.com/gcomneno/gyte.git
cd gyte

Installazione rapida (script di install)

Dalla root del progetto:

chmod +x install/install-gyte.sh
./install/install-gyte.sh

Di default gli script verranno symlinkati in:

$HOME/.local/bin

Puoi scegliere una directory diversa usando:

./install/install-gyte.sh --target-dir "/percorso/personalizzato"
# oppure
GYTE_INSTALL_DIR="/percorso/personalizzato" ./install/install-gyte.sh

Assicurati che la directory scelta sia nel tuo PATH.
In caso di dubbi, puoi usare anche:

gyte-doctor

per verificare rapidamente l’ambiente.

Installare ffmpeg

GYTE usa ffmpeg per:

  • estrarre solo l'audio dai video (gyte-audio)
  • unire audio+video nei file (gyte-video)

Esempi di installazione:

Ubuntu / Debian

sudo apt update
sudo apt install ffmpeg
ffmpeg -version

macOS (Homebrew)

brew install ffmpeg
ffmpeg -version

Su altri sistemi operativi puoi installare ffmpeg tramite il gestore di pacchetti distribuzione-specifico oppure scaricare un build precompilato e aggiungerlo al PATH.


🚀 Installazione CLI (user-level, no sudo)

GYTE fornisce una serie di comandi gyte-* accessibili da qualunque directory del sistema. L’installazione è locale all’utente, non richiede privilegi elevati e non modifica componenti globali.

✔ Installazione standard

Dalla root del repository:

./install/install-gyte.sh

Questo installer:

  • individua automaticamente tutti gli script gyte-* nella cartella scripts/,
  • crea i symlink in ~/.local/bin (o nella directory indicata in $GYTE_INSTALL_DIR),
  • non usa sudo e non scrive fuori da $HOME,
  • non scarica né esegue codice remoto.

Al termine, se ~/.local/bin è nel tuo PATH, puoi usare direttamente:

gyte-transcript
gyte-transcript-pl
gyte-audio
gyte-video
gyte-translate
gyte-reflow-text
gyte-merge-pl
gyte-whisper-local
...

✔ Installazione in una directory scelta dall’utente

Puoi scegliere una directory personalizzata, purché sia sotto $HOME:

./install/install-gyte.sh --target-dir "$HOME/bin"

oppure tramite variabile d’ambiente:

export GYTE_INSTALL_DIR="$HOME/bin"
./install/install-gyte.sh

⚠ Nota di sicurezza

L’installer è progettato per ambienti user-level: se scegli cartelle esterne a $HOME, l’operazione potrebbe fallire (e non è consigliata). Nessun file viene mai sovrascritto senza che venga segnalato. Nessuna chiave API viene letta, usata o memorizzata durante l’installazione. Se la directory di destinazione non è nel PATH, lo script mostra un messaggio con la riga da aggiungere al tuo ~/.bashrc.


Comandi disponibili

1. Trascrizioni — gyte-transcript

Video singolo o playlist: scarica sottotitoli (normali o auto–generati) e produce, per ogni video, i file di testo/markup seguenti nella directory di output.

Esempio base:

gyte-transcript 'https://www.youtube.com/watch?v=VIDEO_ID'

Per ogni video ottieni:

  • Uploader - Titolo [VIDEO_ID].en.txt
    → transcript pulito (senza timestamp, numeri di riga, tag HTML, righe vuote / duplicate)
  • Uploader - Titolo [VIDEO_ID].en.srt
    → sottotitoli in formato SRT “classico” (timestamp HH:MM:SS,mmm --> HH:MM:SS,mmm)
  • Uploader - Titolo [VIDEO_ID].en.md
    → versione Markdown, con un # iniziale e il testo del transcript

Di default lo script prova le lingue it,en (prima italiano, poi inglese).
Le lingue sono configurabili via env:

YT_TRANSCRIPT_LANGS="en,fr" gyte-transcript 'https://www.youtube.com/watch?v=VIDEO_ID'

In caso di errori temporanei (es. HTTP 429 da YouTube), lo script prova comunque a pulire i .vtt eventualmente scaricati.

Directory di output

Per default i file vengono creati nella directory corrente.

Puoi cambiare la cartella di output in due modi:

# via variabile d’ambiente
GYTE_OUTDIR="/tmp/gyte-out" gyte-transcript 'https://www.youtube.com/watch?v=VIDEO_ID'

# via flag (ha priorità su GYTE_OUTDIR)
gyte-transcript --outdir "/tmp/gyte-out" 'https://www.youtube.com/watch?v=VIDEO_ID'

Priorità:

  1. --outdir
  2. GYTE_OUTDIR
  3. directory corrente

2. Trascrizioni su playlist — gyte-transcript-pl

Pensato per corsi interi / playlist lunghe.

Esempio:

gyte-transcript-pl 'https://www.youtube.com/playlist?list=PLXXXXX' 4

Oppure partendo da una URL con watch + list=:

gyte-transcript-pl 'https://www.youtube.com/watch?v=AAA&list=PLXXXXX' 4

Cosa fa:

  1. Normalizza l'URL in
    https://www.youtube.com/playlist?list=PLXXXXX

  2. Recupera il titolo della playlist

  3. Crea una cartella:

    yt-playlist-NOME_PLAYLIST
    
  4. Dentro quella cartella:

    • salva urls.txt con tutte le URL dei video
    • lancia fino a MAX_JOBS processi gyte-transcript in parallelo (default: 4)
    • genera, per ogni video, i file .txt, .srt, .md descritti sopra
    • genera playlist.md, con:
      • # Playlist: NOME_PLAYLIST in testa (se disponibile)
      • una sezione ## ... per ogni video, in ordine playlist, con il relativo transcript Markdown

Suggerimento: se YouTube inizia a rispondere con molti HTTP 429 (Too Many Requests), puoi ridurre il parallelismo, ad esempio:

gyte-transcript-pl 'https://www.youtube.com/playlist?list=PLXXXXX' 1

Oppure usare la modalità sequenziale (--no-parallel) con una pausa tra un video e l’altro:

GYTE_SLEEP_BETWEEN=2 gyte-transcript-pl --no-parallel 'https://www.youtube.com/watch?v=AAA&list=PLXXXXX'

3. Merge transcript di playlist — gyte-merge-pl

Dopo aver generato i transcript di una playlist con gyte-transcript-pl, puoi unire tutti i .txt in un unico file “merged” ordinato:

cd yt-playlist-NOME_PLAYLIST
gyte-merge-pl

Cosa fa:

  • cerca tutti i .txt nella directory della playlist,

  • li concatena in:

    NOME_PLAYLIST.merged.txt
    
  • aggiunge, per ogni blocco, un’intestazione del tipo:

    # [N] Titolo video (ID)
    # File: filename.txt
    

Utile per avere un unico “malloppone” di testo per l’intera playlist.


4. Solo audio — gyte-audio

Scarica solo l'audio dei video (o playlist) e lo converte in MP3 (o altro formato supportato da ffmpeg).

Esempio:

gyte-audio 'https://www.youtube.com/watch?v=VIDEO_ID'

Impostazioni di default:

  • formato: mp3
  • qualità target: 192K

Qualità e formato (audio)

Puoi personalizzare il formato / la qualità in due modi.

API storica (ancora supportata):

AUDIO_FORMAT=opus AUDIO_QUALITY=160K gyte-audio 'https://www.youtube.com/watch?v=VIDEO_ID'

API GYTE (ha priorità se impostata):

GYTE_AUDIO_FORMAT=opus GYTE_AUDIO_QUALITY=160K gyte-audio 'https://www.youtube.com/watch?v=VIDEO_ID'

Priorità:

  1. GYTE_AUDIO_FORMAT / GYTE_AUDIO_QUALITY
  2. AUDIO_FORMAT / AUDIO_QUALITY
  3. default interni dello script (mp3 / 192K)

Funziona anche con playlist (--yes-playlist è già attivo), salvando un file audio per ogni video.


5. Video completo — gyte-video

Scarica il miglior video+audio disponibili e li unisce in un unico file.

Esempio:

gyte-video 'https://www.youtube.com/watch?v=VIDEO_ID'

Caratteristiche:

  • usa bv*+ba/best per combinare best video + best audio
  • per default crea file MP4 (remux con ffmpeg, niente ricompressione se non necessario)
  • zero sottotitoli / zero embed

Formato di output (video)

Puoi cambiare il formato container di output (quando supportato da yt-dlp/ffmpeg) impostando:

GYTE_VIDEO_FORMAT=mkv gyte-video 'https://www.youtube.com/watch?v=VIDEO_ID'

Se GYTE_VIDEO_FORMAT non è impostato, lo script usa il formato predefinito (mp4), come nelle versioni precedenti.

Supporta anche playlist:

gyte-video 'https://www.youtube.com/playlist?list=PLXXXXX'

6. Reflow testo — gyte-reflow-text

Normalizza un .txt (ad esempio generato da gyte-transcript) in modo “comodo da leggere / diffare / dare in pasto ad AI”.

Di default fa entrambi:

  • compattazione in paragrafi (righe spezzate riunite),
  • split in frasi: una frase per riga.

Modalità esplicite:

  • --paragraphs → solo compattazione paragrafi (niente split in frasi)
  • --sentences → solo split in frasi (assume input già compattato)

Opzioni utili:

  • --max-width N → wrap dolce a N caratteri (non spezza parole)
  • --stats → statistiche su stderr (stdout resta pulito)

Esempi:

# default: paragraphs + sentences
gyte-reflow-text lecture1.en.txt > lecture1.en.sentences.txt

# solo compattazione
gyte-reflow-text --paragraphs lecture1.en.txt > lecture1.en.paragraphs.txt

# solo split in frasi (input già compattato)
gyte-reflow-text --sentences lecture1.en.paragraphs.txt > lecture1.en.sentences.txt

# output più “terminal/diff friendly”
gyte-reflow-text --max-width 100 lecture1.en.txt > lecture1.en.wrap.txt

# stats (non sporca lo stdout)
gyte-reflow-text --stats lecture1.en.txt > /dev/null

Nota: lo splitter è “smarter” e prova a NON spezzare su abbreviazioni IT/EN (Prof., e.g., Mr.), decimali/versioni (3.14, v1.2) ed enumerazioni (1., A.).

Demo rapida: examples/reflow-splitter-demo.sh (con sample in examples/reflow-splitter-sample.txt).

Preset AI-friendly

# Transcript -> reflow "AI-friendly" -> translate (comando AI esterno)
gyte-transcript URL --outdir out/
gyte-reflow-text --ai-friendly out/video.it.txt > out/video.it.ai.txt
GYTE_AI_CMD='gyte-openai --model gpt-4.1-mini' gyte-translate --to en out/video.it.ai.txt

Sanitizzazione UTF-8 (opt-in)

Esempio file "sporco" (byte non UTF-8)

printf 'ok\xffbad\n' > /tmp/dirty.txt

# Ripulisce e garantisce stdout UTF-8 valido
gyte-reflow-text --strict-utf8 /tmp/dirty.txt > /tmp/dirty.clean.txt

7. Traduzione AI dei transcript — gyte-translate

Usa un comando AI esterno (configurato via GYTE_AI_CMD) per tradurre i transcript generati da GYTE (.txt, .md, ecc.).

Esempio:

export GYTE_AI_CMD='my-ai-wrapper --model gpt4'
gyte-translate --to en lecture.it.txt
# -> produce: lecture.en.txt

Regole di naming default:

  • lecture.it.txtlecture.en.txt
  • notes.mdnotes.en.md
  • raw_transcriptraw_transcript.en

8. Trascrizione locale MP4/audio — gyte-whisper-local

gyte-whisper-local usa un comando di speech-to-text locale (di default whisper) per estrarre transcript da file locali (.mp4, .mp3, ecc.), senza passare da YouTube.

Esempio base:

gyte-whisper-local lesson1.mp4

Cosa fa:

  • verifica che il file esista
  • chiama il comando STT (default: whisper) con:
    • modello configurabile (--model o GYTE_WHISPER_MODEL)
    • lingua opzionale (--lang/--language o GYTE_WHISPER_LANG)
    • output in una directory scelta (--outdir o GYTE_OUTDIR)
  • genera nella directory di output:
    • <basename>.txt – testo puro
    • <basename>.srt – sottotitoli SRT

Opzioni principali:

  • --model MODEL
    Modello Whisper da usare (tiny, base, small, medium, large).
    Default: valore di GYTE_WHISPER_MODEL o "small".

  • --lang LANG / --language LANG
    Lingua di lavoro (es. en, it, fr).
    Default: valore di GYTE_WHISPER_LANG o "auto" (auto-detect lato Whisper).

  • --outdir DIR
    Directory di output.
    Default: GYTE_OUTDIR o directory corrente.

Env utili:

  • GYTE_WHISPER_MODEL – modello di default per gyte-whisper-local
  • GYTE_WHISPER_LANG – lingua di default (o auto)
  • GYTE_OUTDIR – directory di output di default
  • GYTE_STT_BIN – comando STT da usare (default: whisper)

Esempi:

# Modello small, lingua auto, output nella cwd
gyte-whisper-local "Git-GitHub-CrashCourse.mp4"

# Forza lingua inglese e mette tutto in ./transcripts
GYTE_OUTDIR="transcripts" gyte-whisper-local --lang en "Git-GitHub-CrashCourse.mp4"

# Usa un binario STT alternativo (es. wrapper personale)
GYTE_STT_BIN="my-whisper-wrapper" gyte-whisper-local lesson1.mkv

Dopo la generazione puoi combinare con gli altri strumenti GYTE, ad esempio:

gyte-reflow-text "Git-GitHub-CrashCourse.txt"   > "Git-GitHub-CrashCourse.en.sentences.txt"

gyte-translate --from en --to it   "Git-GitHub-CrashCourse.en.sentences.txt"

Modulo AI esterno – gyte-translate

gyte-translate non contiene nessuna logica di AI “interna: si limita a prendere un file di testo e a passarlo a un comando esterno che legge da stdine scrive il risultato sustdout`.

Il comando esterno viene configurato tramite:

export GYTE_AI_CMD='my-ai-wrapper --model gpt4'

Durante l’esecuzione, GYTE imposta due variabili d’ambiente che il comando può usare:

  • SRC_LANG – lingua sorgente (es. auto, it, en)
  • TARGET_LANG – lingua di destinazione (es. en, it, fr)

Uso base

gyte-translate --to en lecture.it.txt
# -> legge lecture.it.txt
# -> invoca: SRC_LANG=auto TARGET_LANG=en bash -c "$GYTE_AI_CMD"
# -> salva il risultato in lecture.en.txt

Opzioni principali

  • --to, --target-lang LANG
    Lingua di destinazione (obbligatoria, oppure via GYTE_AI_TARGET_LANG).

  • --from, --source-lang LANG
    Lingua sorgente (default: auto o GYTE_AI_SOURCE_LANG).

  • --out FILE
    File di output esplicito.
    Se omesso, GYTE costruisce il nome da quello di input inserendo .LANG prima dell’estensione.

  • --dry-run
    Mostra la configurazione risolta (file, lingue, comando AI) senza eseguire la chiamata.

Note su chiavi API e limiti

gyte-translate non gestisce chiavi API, token, retry, throttling, ecc.
Tutta la logica di autenticazione e di gestione errori è a carico del comando configurato in GYTE_AI_CMD.

Questo permette di usare:

  • wrapper personali,
  • CLI ufficiali di provider,
  • script intermedi che spezzano file troppo lunghi, ecc.

Integrazione AI (opzionale)

Alcune funzioni (es. gyte-openai + gyte-translate) richiedono il client Python openai.

Installazione opzionale:

python -m venv .venv
source .venv/bin/activate
pip install -r requirements-optional.txt

Poi esporta:

export OPENAI_API_KEY='sk-...'
export GYTE_AI_CMD='gyte-openai --model gpt-4.1-mini'

Esempio: usare gyte-translate con OpenAI (gyte-openai)

Il repository include un wrapper di riferimento per OpenAI:

  • script: scripts/gyte-openai
  • uso: come valore di GYTE_AI_CMD

⚠️ Sicurezza API key

  • NON salvare mai la tua API key in file, script o repository.
  • Usala solo tramite variabile d'ambiente OPENAI_API_KEY.
  • Non committare mai uno export OPENAI_API_KEY="sk-..." dentro script versionati.

Prerequisiti:

pip install openai
export OPENAI_API_KEY="sk-..."   # NON committare mai questa riga

Poi puoi configurare GYTE così:

export GYTE_AI_CMD='gyte-openai --model gpt-4.1-mini'

# esempio: traduci da italiano a inglese
gyte-translate --from it --to en sample.it.txt
# -> produce: sample.en.txt

Se non specifichi --from, gyte-translate usa auto come lingua sorgente (o GYTE_AI_SOURCE_LANG se impostata).

Puoi verificare la configurazione senza chiamare l’API con --dry-run:

echo "Ciao mondo, questo è un test." > sample.it.txt

SRC_LANG=it TARGET_LANG=en   gyte-openai --model gpt-4.1-mini --dry-run < sample.it.txt

Il wrapper:

  • legge il testo da stdin,
  • usa SRC_LANG / TARGET_LANG (impostate da gyte-translate),
  • chiama il modello OpenAI scelto,
  • scrive SOLO il testo tradotto su stdout (nessun log mischiato ai dati).

Esempi GYTE

La cartella examples contiene esempi pratici di utilizzo di GYTE:

  • basic-usage.sh
    Esempio di utilizzo base su un singolo video: transcript, audio, video e reflow del testo.

  • mit-ocw-python.sh
    Esempio pensato per una playlist di corso (MIT 6.100L) con estrazione transcript.

  • sample-transcript.raw.txt
    Esempio di transcript "grezzo" come potrebbe uscire da gyte-transcript.

  • sample-transcript.sentences.txt
    Lo stesso testo, dopo il passaggio con gyte-reflow-text (una frase per riga).

  • ai-openai-translate.sh
    Esempio di utilizzo combinato di gyte-translate + gyte-openai (senza mai salvare l’API key in chiaro negli script).

Questi file sono solo dimostrativi: sostituisci le URL e i nomi file con quelli che ti servono nel tuo contesto reale.


Come impostare la lingua per le trascrizioni

Per impostazione predefinita, gyte-transcript usa:

YT_TRANSCRIPT_LANGS="it,en"

cioè:

  • prova prima a scaricare i sottotitoli in italiano (it);
  • se non disponibili, ripiega su inglese (en).

Puoi cambiare questo comportamento impostando l'env prima del comando.

# Solo inglese
YT_TRANSCRIPT_LANGS="en" gyte-transcript "https://www.youtube.com/watch?v=VIDEO_ID"

# Francese con fallback su inglese
YT_TRANSCRIPT_LANGS="fr,en" gyte-transcript "https://www.youtube.com/watch?v=VIDEO_ID"

Se vuoi forzare una lingua meno comune (es. tedesco) sapendo che spesso ci sono solo auto–sub:

# Solo tedesco
YT_TRANSCRIPT_LANGS="de" gyte-transcript "https://www.youtube.com/watch?v=VIDEO_ID"

Nota: l’ordine delle lingue in YT_TRANSCRIPT_LANGS è significativo: viene usata la prima disponibile nell’elenco.


🔐 Sicurezza & Privacy

GYTE è progettato secondo i principi DevSecOps minimalisti, con l’obiettivo di evitare rischi comuni nella supply-chain, nell’uso di wrapper AI e negli script shell. Non raccoglie né invia alcun dato proprio: tutto avviene localmente, tramite strumenti standard.

✦ Come GYTE protegge l’utente

Nessuna chiave nel codice o negli script.

Tutti i segreti (es. OPENAI_API_KEY) devono essere forniti solo tramite variabili d’ambiente. GYTE non stampa mai il valore di tali variabili.

Wrapper yt-dlp “blindati”.

Gli script rifiutano opzioni pericolose come: --exec*, --postprocessor-args, --run-postprocessor

impedendo l’esecuzione accidentale di comandi arbitrari.

Validazione input rigorosa.

Le URL devono iniziare con http(s):// (così non possono trasformarsi in opzioni nascoste tipo -someflag).

Nessuna dipendenza remota eseguita automaticamente.

Non esistono sequenze curl | sh, script bootstrap legacy o download silenziosi.

Limitazione volontaria degli input AI.

Gli script di traduzione supportano:

  • GYTE_AI_MAX_INPUT_BYTES / GYTE_AI_MAX_INPUT_CHARS

per evitare di inviare per errore file enormi ai provider AI.

File generati esclusi dal repository.

Il .gitignore protegge il repo da:

  • media scaricati (mp4/mp3/mkv…),
  • sottotitoli, log, tmp,
  • virtualenv e file .env con segreti.

✦ Cosa non fa GYTE (per scelta)

  • Non gestisce chiavi API. Le usa solo se già impostate nell’ambiente dell’utente.
  • Non esegue comandi arbitrari forniti all’interno di URL, alias o variabili.
  • Non modifica il sistema dell’utente (no installazioni, no permessi elevati).

✦ Buone pratiche consigliate

  • Mantieni yt-dlp e ffmpeg aggiornati.
  • Non salvare transcript sensibili nelle cartelle versionate.
  • Usa un .env locale (ignorato dal repo) per configurare API key.
  • Prima di usare provider AI, valuta se il contenuto del transcript è adatto a essere inviato a terze parti.

Roadmap

Vedi il file ROADMAP.md per i dettagli.


Licenza

Rilasciato sotto licenza MIT.
Vedi il file LICENSE per i dettagli.