DEV Community

Kirnu (كرنو)
Kirnu (كرنو)

Posted on Fully Autonomous

A daily Arabic health Short with Claude Code, Hugging Face ZeroGPU and three AI reviewers

I run Hakeemly, a small Arabic health-information site. Since this week it publishes one Arabic YouTube Short a day, plus the same video as a Facebook Reel. The series is called «ماذا يحدث لجسمك إذا…؟» ("What happens to your body if…?"): too little sleep, quitting smoking, sitting all day, not drinking water, too much salt, cutting down on sugar.

There's no camera or conventional video editor. Claude Code does the engineering, open models on Hugging Face make the pictures and motion, and a small script turns it all into a 1080×1920 video. This post walks through the pipeline and, more usefully, what broke.

Disclosure: Claude Code wrote most of the pipeline and helped draft this post. Every video is labelled as AI-generated on screen and on YouTube.

The pipeline at a glance

  1. Topic from search data. YouTube autocomplete shows what people actually type («ماذا يحدث لجسمك اذا تركت السكر»…).
  2. Script from sources. Short narration lines checked against NHS and WHO guidance, and primary research where relevant.
  3. Two AI reviewers on the script. ChatGPT and DeepSeek each check the lines against the sources and answer READY or NEEDS CHANGES. Both must say READY.
  4. Stills. FLUX.1 [schnell] on a Hugging Face Space, two seeds per shot.
  5. Motion. Wan 2.2 image-to-video turns some stills into 4-second clips.
  6. Voice. Azure neural text-to-speech, Arabic.
  7. Arabic text. Captions and labels are rendered by a headless browser as transparent PNGs.
  8. Assembly. ffmpeg stitches stills, clips, overlays and narration.
  9. A third AI watches the video. Gemini watches the finished MP4 and flags visual problems.
  10. Scheduling. YouTube and Facebook, 8 PM local time, with the AI label switched on.

GPU time: Hugging Face ZeroGPU

ZeroGPU Spaces lend you a shared GPU per request, with a daily quota that depends on your account: 5 minutes on a free account, 40 minutes on PRO (which we use). A FLUX schnell still takes about 25 seconds of GPU; a 4-second Wan clip about 30 seconds. One episode uses 4–8 GPU minutes, so a free account will not reliably cover an episode a day; PRO does, with room to spare.

Calling a Space from Node is a few lines with @gradio/client. The Space name, endpoint, input fields and output shape are specific to each Space, so copy them from its "Use via API" page. This is the FLUX schnell Space we use, tested with @gradio/client 1.19.1 (newer releases may name the token option differently; check the docs for your version):

import { Client } from "@gradio/client";

const flux = await Client.connect("black-forest-labs/FLUX.1-schnell", {
  hf_token: process.env.HF_TOKEN,
});
const result = await flux.predict("/infer", {
  prompt: "stylised 3D animation, a young Arab office worker at a cafe table...",
  seed: 42,
  randomize_seed: false,
  width: 768,
  height: 1344,
  num_inference_steps: 4,
});
console.log(result.data[0].url); // the generated image
Enter fullscreen mode Exit fullscreen mode

Two practical notes:

  • Check the quota before a batch. It resets about 24 hours after your first GPU use, not at local midnight, so "it's a new day" is not proof you have minutes left.
  • Don't kill the process early. In one run, a shell pipe that kept only the first output line ended the Node process before the clip was written. The GPU time was spent and the video was lost.

A recurring AI character

The first two episodes had no people: organs, clocks, glasses of water. From episode 3 we added «عمر» (Omar), a fictional young man in a light-blue shirt with a short beard, in a stylised 3D look.

We improve consistency by repeating the same character description in every prompt and choosing between two candidate seeds per shot. This helps, but it doesn't guarantee identical details across images. Stylised 3D also keeps him clearly fictional, which matters for health content: Omar only acts out the habit. A separate narrator speaks, and Omar is never dressed or framed as a doctor.

Arabic text: let the browser do it

Drawing Arabic with ffmpeg's text filter is painful: letters must join, run right to left, and mix with Latin digits. A browser already does all of that well. So each caption is a tiny HTML page rendered to a transparent PNG:

import { chromium } from "playwright";

const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1080, height: 1920 } });
// In the real page the font is embedded with @font-face (a base64 woff2).
await page.setContent(`
  <body style="margin:0;background:transparent;direction:rtl;font-family:'IBM Plex Sans Arabic'">
    <div style="position:absolute;top:1240px;left:80px;right:80px;text-align:center;
                color:#fff;font-size:56px;font-weight:700">
      الإكثار من الملح قد يرفع ضغط الدم.
    </div>
  </body>`);
await page.evaluate(async () => {
  await document.fonts.ready;
  return true;
});
await page.screenshot({ path: "caption.png", omitBackground: true });
Enter fullscreen mode Exit fullscreen mode

ffmpeg then overlays the PNG at the right time. Embed the font, and wait for document.fonts.ready, or the first render may fall back to a system font.

Assembly with ffmpeg

Each shot is either a still with a slow zoom (zoompan) or a Wan clip. Wan's 4 seconds rarely match the narration, so clips are slowed 1.5–2.5× and then hold their last frame (tpad=stop_mode=clone:stop_duration=…) for the rest of the line. Shots meet with hard cuts, and the end card lists the sources and the AI disclosure.

What broke, and what fixed it

Most of the work went here. Gemini found several of these; we checked every claim against the actual frames, because it is not always right.

  • Double face in crossfades. Fading between two poses of the same character shows two overlapping faces. Fix: no crossfades on the character; hold the last frame, then cut.
  • Melting hands. Wan sometimes morphs fingers around a salt shaker or spoon. Fix: trim the clip to its clean first second, or use the still.
  • Invented labels. FLUX writes fake text on bottles and packets. Fix: no labelled objects in prompts.
  • Misread numbers. The Arabic-Indic zero (٠) is a small dot; at Shorts size, "١٥٠" read as 15. Fix: Western digits in on-screen labels, and fractions written in words.
  • Flaky DNS. The home router failed lookups for Azure and Hugging Face mid-build. Fix: a small preload that resolves through public DNS servers.
  • A reviewer's false alarm. Gemini once reported "chopsticks with an extra finger" on a frame it had passed before. It was a normal spoon grip. Video reviewers are non-deterministic, so check the flagged frames yourself.

Why three AI reviewers

Health content is easy to get subtly wrong. Examples from this week:

  • DeepSeek noticed that "salt in foods we buy ready-made" narrowed the NHS wording ("already in everyday foods"); we reverted it.
  • ChatGPT pointed out that the 30 g sugar limit is a UK guideline the NHS reports, not "the NHS recommends", and that "free sugars" includes syrups and juices.
  • Both rejected unsourced thresholds that had crept into drafts.

Each reviewer gets the script, the sources and a request for a short READY / NEEDS CHANGES answer. Both script reviewers must say READY before production starts, and Gemini then checks the finished video. These AI reviews are editorial checks, not clinical review or a guarantee of medical accuracy; every medical claim is checked against its cited source, which may include NHS or WHO guidance and primary research.

Is this better than an off-the-shelf tool?

Open-source projects like OpenMontage and MoneyPrinterTurbo automate script → visuals → voice → edit, and they're worth a look. For Arabic health content we needed three things they don't focus on: correct right-to-left text, a consistent fictional character, and a source-checking step before anything is published. Building it with Claude Code took a few sessions, and the per-episode cost is mostly GPU minutes from the PRO quota.

If you build something similar for another right-to-left language, start with the browser-rendered text and the review step. The models will keep changing; source checking and human review remain necessary.

The series is on the Hakeemly YouTube channel and Facebook Page. Questions about the pipeline are welcome in the comments.

Top comments (0)