9:16 video · Football · automatic

What YouTube's football channels said, in 3 minutes

The 10 biggest football channels on YouTube (Brasileirão, European football, the transfer market and controversies), transcribed, checked and summed up in a video with the source on screen and Nei commenting.

FOOTBALL RADAR banner: what the 10 biggest football channels on YouTube said, in 3 minutes
In short

futviral is a system that makes, on its own, vertical videos (9:16) of 2 to 3 minutes summing up what the 10 biggest football channels on YouTube said: Brasileirão, European football, the transfer market, controversies and the business of football. It "watches" the videos through their transcripts, pulls out the facts and numbers with the source of each one, and builds a video with big numbers, stamps (RUMOR, NEGOCIANDO, FECHADO, POLÊMICA — rumor, negotiating, done deal, controversy) and Nei (Nei Maldaner, creator of INEMA) commenting as an avatar. A rumor is treated as a rumor, no club gets a side and betting is left out. It's for anyone who wants to know, in a few minutes, what the main channels are talking about. It runs on a computer with a GPU, using the Claude Code and HeyGen subscriptions.

What it is

A football radar that builds itself

futviral reads what the channels published, checks every fact against the transcript and publishes a finished video. The video reports what each channel said, always with the source, without rooting for anyone.

futviral flow: collection, transcription, script, check, avatar and publishing

🔎 Only facts with a source

Every fact or number must be in the transcript, with the literal excerpt. Channel, date and title appear on screen. Scores, transfer fees and release clauses only go in if the channel said them.

📰 A rumor is a rumor

A signing, departure or coach sacking only becomes "fechado" (done deal) when the club confirms it; before that it's "rumor" or "negociando" (negotiating). Everything is attributed to whoever said it, with no rooting. Betting is left out.

🔒 All through the subscription

Script with claude -p (subscription, no API), local transcription with Whisper and avatar through the HeyGen studio. HeyGen's plan-change offer is always declined.

How it works

From transcript to YouTube, with no human hand in between

Steps chained by auto/rodar.sh. If the check fails twice, the video is not made. A slow day doesn't become a video either: the bot gets "sem pauta" (nothing to report).

Collection→ Transcription→ Script→ Check→ Avatar→ Video→ YouTube + bot
1

Collection and transcription

Lists the videos from the channels in canais.json (metadata only, yt-dlp), picks the most viewed from each channel first (up to 3 per channel, never repeating a video already used and skipping videos/lives over 75 min), takes the YouTube caption and, if there isn't one, downloads the audio and transcribes it locally (inemavox, Whisper large-v3; in English for Fabrizio Romano).

2

Script

claude -p reads the transcripts and writes base.md (each fact, who said it, the video and the literal excerpt), roteiro.json (lines and visuals) and legenda.txt.

3

Check

auto/checar.py checks the excerpts against the transcript, numbers spelled out in words in the speech, at least 5 topics, the notice "Rumor só vale quando o clube confirma." (A rumor only counts when the club confirms it.), the inema.club CTA, and rejects any line about betting. If it fails: it goes back once for correction.

4

Avatar

HeyGen generates Nei's avatar through the studio (subscription). If it fails, a version with Nei's photo and voice comes out, which only goes to the bot.

5

Video

motor/palco.html is rendered frame by frame by Playwright, with counters, stamps and the source on screen. The image is the thumbnail of the channel's video: plays, goals and club crests are left out.

6

Publishing

On the schedule, the finished video first goes to bot v3 as a preview; at noon auto/publicar-pendente.sh publishes it to YouTube Inema Club24 (lives24) through yt-pubx and sends the link to the bot.

Runs

Three kinds of run

Each run is a mode of auto/rodar.sh. The schedule (timers in systemd/) is on: generation runs at 09:00 and publishing at 12:00, outside the hours of the sibling projects that use the same GPU and the same HeyGen.

Daily
diario runThe summary of the ten, 2 to 3 minutes: yesterday's and the day before's videos not used yet, with at least five topics (one per channel whenever possible). If fewer than five channels published in those two days, the window widens to five days.
Saturday
semanal runReview of the week (the 7 days up to yesterday), 2 to 3 minutes. Then the long 16:9 "A semana explicada" (The week explained) (5.5 to 7 minutes).
Sunday
domingo runWhat the channels expect for the coming week (big derbies, deciding matches, coaches under pressure, negotiations), 2 to 3 minutes. Then the long 16:9 explained video (5.5 to 7 minutes).
The 10 channels

Who futviral follows

Chosen on 10/26/2026 by our own measurement (yt-dlp, median views of the last 15 videos, active channel with spoken content). Highlight channels, fan-reaction channels and betting channels were left out. Details in pesquisa/canais.md (in Portuguese).

🌍 European football and the global market

Eurão (recaps and stories from European football), Fabrizio Romano (global transfer market, in English) and Fred Caldeira (European football and opinion).

📺 News, debate and opinion

Jovem Pan Esportes (news and debate), Jozão (opinion on the matches), Chico Garcia (Brasileirão) and Mauro Cezar (opinion and controversy).

💼 Transfer market and business

Tode (daily transfer market), Canal do Nicola (Brazilian market and behind the scenes) and TiaGOL (analysis and the business of football).

Prerequisites

What needs to be on the machine

futviral is not a standalone app: it uses other tools from the INEMA ecosystem, all in ~/projetos/, on a computer with a GPU. The repository lives in ~/projetos/futviral (the systemd timers and the links point there).

Collection and transcription

yt-dlp to list and download. inemavox (~/projetos/inemavox, with baixar_v1.py and transcrever_v1.py) is the local download and transcription kit with Whisper.

Render

Node with Playwright and ffmpeg. motor/node_modules is a link to ~/projetos/eventosextremospub/motor/node_modules; without that project, run npm install playwright in motor/.

Script

claude (Claude Code logged in with the subscription, called as claude -p). The weekend long video uses the ~/projetos/explicavideos/engine/v2 engine.

Avatar and voice

The HeyGen studio open in a browser on a virtual screen (Xvfb :99), with the explicavideos project's already logged-in profile. Without it, the run comes out with Nei's photo and cloned voice (Chatterbox, voice nei, through the ~/projetos/cardshorts project).

Publishing

yt-pubx (~/projetos/yt-pubx), the tool that publishes to YouTube; lives24 is its name for the Inema Club24 channel.

Telegram notice

bot v3 is Nei's Telegram bot that receives every video and notice, through the script ~/projetos/refazvideo/ferramentas/enviar_bot_v3.mjs.

User guide · step by step

Install, choose the channels, test and run

Real commands from the repository, run from the project root.

1

Download the project and its siblings

futviral lives in ~/projetos/futviral and uses public INEMA projects next to it. It also needs yt-dlp, ffmpeg, node and claude logged in with the subscription.

cd ~/projetos
git clone https://github.com/inematds/futviral
for r in inemavox yt-pubx cardshorts explicavideos refazvideo eventosextremospub; do
  git clone https://github.com/inematds/$r
done

Each sibling has its own README with the setup: the channel credentials in yt-pubx, the Telegram bot in refazvideo, the HeyGen studio profile and the virtual screen in explicavideos, transcription in inemavox and the voice in cardshorts. The test in step 3 already needs inemavox, cardshorts and refazvideo; publishing needs all of them.

2

Choose the channels

The list is in canais.json. To pause a channel without deleting it, use "ativo": false. The handle is the channel's path on YouTube, rk is the label shown on screen and lang is the channel's language for Whisper (default pt).

{"handle": "channel/UCX1em-uaFMS02Rrk_Bowyng", "nome": "Fabrizio Romano", "rk": "MERCADO MUNDIAL", "lang": "en", "ativo": true}

If another established football channel stands out, the system suggests adding it in the bot message (never an up-and-coming channel or a betting one). It only goes in with Nei's OK.

3

Test without the avatar and without publishing

Do a run without HeyGen, without the long video and without sending to the bot or to YouTube. It still uses claude -p (subscription quota), downloads the audio and keeps the GPU busy with Whisper. The terminal stays quiet: the output goes to the edition's log.

SEM_AVATAR=1 SEM_BOT=1 SEM_LONGO=1 auto/rodar.sh diario   # test: no HeyGen, no long video and nothing sent
tail -f edicoes/$(date +%F)-diario/rodada.log              # follow along

The edicoes/AAAA-MM-DD-diario/ folder holds base.md, roteiro.json, legenda.txt, checar.log and the finished video (video.mp4).

4

Run by hand

Pass the mode and the date. The full run generates the avatar, publishes to lives24 and sends to the bot.

auto/rodar.sh diario 2026-10-26                   # full run (avatar + lives24 + bot)
SEM_AVATAR=1 auto/rodar.sh diario 2026-10-26      # photo version, bot only
REUSAR_ROTEIRO=1 auto/rodar.sh diario 2026-10-26  # redo avatar/video/publishing with the script already approved
VALIDAR=1 auto/rodar.sh diario 2026-10-26        # test edition (-validacao folder), never goes to YouTube
5

Skip a run

Add the date and the mode to auto/pular.txt.

echo "2026-11-01 semanal" >> auto/pular.txt   # skip a run
6

Turn on the schedule and hold a publication

Generation at 09:00 (diario Monday to Friday, semanal on Saturday, domingo on Sunday) and publishing at 12:00. Copy the units to the user systemd and enable the four timers. To hold the publication of a video that already went to the bot as a preview, create the file SEGURAR (hold) in the edition folder.

cp systemd/futviral-* ~/.config/systemd/user/ && systemctl --user daemon-reload
systemctl --user enable --now futviral-diario.timer futviral-semanal.timer futviral-domingo.timer futviral-publicar.timer
systemctl --user list-timers 'futviral-*'
touch edicoes/2026-10-27-diario/SEGURAR   # don't publish this edition at 12:00
7

Follow along on Telegram and YouTube

On the schedule, bot v3 gets the preview at 09:00 and the Inema Club24 (lives24) link after noon. A run by hand (step 4) publishes right away. If there's nothing to report or something fails, the bot gets the notice.

Rules for every video

What every video follows

The script and the check gate follow these rules.

📌 Source on screen

Only facts that are in the transcript go in, with channel, date and title on screen and the literal excerpt in base.md.

📰 A rumor is a rumor

"Rumor só vale quando o clube confirma." (A rumor only counts when the club confirms it.) in every video; a transfer is "rumor" or "negociando" (negotiating) until the club confirms it.

⚖️ No rooting

Everything is attributed to whoever said it. A controversy is what THEY said; no club gets a side.

🚫 No betting

No bets, odds or tips. The gate rejects the line.

📺 No match footage

Plays, goals, match images and club crests are left out (broadcast rights). The screen uses numbers, tables, stamps and the thumbnail of the channel's video.

🗣️ Nei's tone and CTA

Spoken in Nei's tone (addressing the viewer as "você"), with numbers spelled out in words. At the end, a question to comment on and the inema.club CTA.