{"id":80,"date":"2026-07-28T12:34:44","date_gmt":"2026-07-28T12:34:44","guid":{"rendered":"https:\/\/www.dobryakov.net\/blog\/80\/"},"modified":"2026-07-28T12:34:44","modified_gmt":"2026-07-28T12:34:44","slug":"hybrid-reels-pipeline","status":"publish","type":"post","link":"https:\/\/www.dobryakov.net\/blog\/80\/","title":{"rendered":"How we built a hybrid reels pipeline: a real expert plus AI B-roll"},"content":{"rendered":"<p>The brief sounded deceptively simple: short vertical clips where a real-estate expert talks to camera, and between his points sit clean AI cutaways \u2014 construction sites, transit, a document in close-up, a phone in hand. The face is filmed by a human; the atmosphere is generated by a neural net. What started as a one-off generation script grew into a five-stage pipeline, and along the way we collected nearly every gotcha this kind of build has to offer.<\/p>\n<p><!--more--><\/p>\n<p>Below is how it&#x27;s wired, why there are exactly five stages, and the order in which they broke before we lined them up correctly. This is for people who stitch external models \u2014 text-to-video, TTS, LLM \u2014 into one pipeline and want a predictable cost per second of footage instead of a &quot;magic button.&quot;<\/p>\n<h2>Why hybrid, and not &quot;generate everything&quot;<\/h2>\n<p>The temptation was obvious: synthesize the talking-head end to end and never send a human to a shoot. But a fully synthetic talking-head today is expensive, the face drifts frame to frame, and for real estate \u2014 an offer where words carry legal weight \u2014 an avatar won&#x27;t do. The client needs a recognizable expert people trust, not a digital double who gets asked next month where he pulled &quot;guaranteed returns&quot; from.<\/p>\n<p>Shooting every cutaway is expensive too: a site trip for three seconds of mood. Hence the hybrid. The expert speaks the scaffold himself \u2014 that&#x27;s the face and the trust. Between his paragraphs go the AI bridges: faceless generated video plus synthesized speech.<\/p>\n<p>One decision was firm from the start and stayed that way: <strong>we do not generate the face.<\/strong> The system prompt and the brief explicitly forbid faces in text-to-video. AI handles only atmospheric B-roll \u2014 where the shoot is expensive and face fidelity doesn&#x27;t matter, because there&#x27;s no face in frame.<\/p>\n<h2>Five stages and a strict order<\/h2>\n<p>The stack is deliberately boring: plain Node ESM, no Python, a hand-rolled <code>.env<\/code> parser, <code>fetch<\/code> against HTTP APIs, local ffmpeg from npm packages. No orchestrator, no queues, no UI \u2014 every step is a readable <code>.mjs<\/code> of tens to hundreds of lines you can run by hand.<\/p>\n<p>The order: an LLM fills the scenario slots \u2192 TTS voices the cutaways \u2192 text-to-video renders the picture \u2192 mux lays speech over video \u2192 the final concat interleaves live footage with AI inserts. Here&#x27;s what turned out to be non-obvious at each step.<\/p>\n<h3>Stage 1. The script: what the model writes, and what we never touch<\/h3>\n<p>The script splits into two parts that must not mix. There&#x27;s the <strong>scaffold<\/strong> \u2014 the fixed paragraphs the expert has already spoken to camera. You can&#x27;t touch them: shift a word and the baseline clip on disk stops matching the text. Between the paragraphs sit placeholders <code>&lt;CUT 1&gt;<\/code>, <code>&lt;CUT 2&gt;<\/code> \u2014 the slots for AI inserts.<\/p>\n<p>The first thing we tripped over: we asked the model to &quot;fill the slots,&quot; and it rewrote the entire script. All of it. Fluent, coherent \u2014 and out of sync with the footage already shot. Turns out &quot;fill the slots&quot; reads to an LLM as &quot;write a good script from scratch,&quot; especially when it dislikes something about the one it&#x27;s given.<\/p>\n<p>Coaxing the model in the prompt \u2014 &quot;don&#x27;t touch the fixed paragraphs&quot; \u2014 is pointless; it&#x27;s under no obligation to obey prose in the prompt. It&#x27;s the same lesson as <a href=\"https:\/\/www.dobryakov.net\/blog\/63\/\">a security perimeter that can&#x27;t rest on a system prompt<\/a>: a constraint holds when it&#x27;s wired into code, not into a polite request. So we changed the contract: <strong>the model returns CUT blocks only, and the script does the merge with the scaffold.<\/strong> A deterministic merge gives idempotent re-runs, a byte-for-byte match on the baseline text, and a clean diff \u2014 only the inserts change. The raw model response is also saved separately, so you can rebuild the script without a fresh API call when you&#x27;re editing merge logic rather than content.<\/p>\n<p>Every slot is described in a brief: its role in the funnel (pain \/ method \/ trust \/ call-to-action boost), the intent of the line (no ready wording \u2014 the LLM writes that), the shot type, and how it joins the neighboring paragraphs. Global constraints \u2014 vertical 9:16, three to five seconds spoken, no prices, no named developments, no promises of returns or mortgage guarantees. That&#x27;s both compliance and insurance against the model inventing a number.<\/p>\n<p>This stage costs pennies: about $0.009 per run on a cheap chat model. Dust next to the video.<\/p>\n<h3>Stage 2. Speech first, and take the length from the file, not from your head<\/h3>\n<p>Here&#x27;s the rule that governs the whole pipeline: <strong>speech first, video second.<\/strong> From each CUT block we take the line, send it to ElevenLabs (multilingual model, a premade voice), and get <code>cut-N.mp3<\/code>.<\/p>\n<p>And here&#x27;s the subtlety that later saved the whole edit. We take the clip duration <strong>not from the API response and not from a &quot;roughly five seconds&quot; estimate<\/strong>, but by measuring the finished mp3 with local <code>ffprobe<\/code>. The source of the length goes straight into the manifest: <code>&quot;duration_source&quot;: &quot;ffprobe&quot;<\/code>. Same instinct as <a href=\"https:\/\/www.dobryakov.net\/blog\/76\/\">treating a measurable result over a gut feel<\/a>: there it&#x27;s about gauging an agent with a harness rather than by eye, here it&#x27;s about measuring a line by probing the file rather than guessing. In a real run, four lines came out at 6.0 \/ 4.6 \/ 6.3 \/ 5.1 seconds. Not &quot;all five,&quot; as the brief promised.<\/p>\n<p>That measured length is what drives the video duration downstream. Trust the estimate instead and you get drift on every other insert.<\/p>\n<h3>Stage 3. Text-to-video, and a Seedance that won&#x27;t do three seconds<\/h3>\n<p>The picture is generated by Seedance 1.5 Pro via OpenRouter: vertical 9:16, 480p, audio generation off \u2014 the audio already exists from TTS, and the model&#x27;s native audio just makes a second more expensive for nothing.<\/p>\n<p>The first surprise here: order a three-second clip and you get HTTP 400. Seedance, it turns out, accepts a duration only in the <strong>4\u201312 second<\/strong> range, and none of the marketing &quot;short clips&quot; copy says so. Which is where this formula came from \u2014 the one that doubles as the main cost-versus-quality lever:<\/p>\n<pre><code>requested = max(4, min(10, ceil(speech_duration_sec)))<\/code><\/pre>\n<p>The lower four is the API requirement. The upper ten is a hard <strong>cost guard<\/strong>: the API formally allows up to 12 seconds, but every extra second of video costs money, and we decided to pay for no more than ten. <code>ceil<\/code> keeps the clip from ending before the speech does when the line spills just past a whole number of seconds.<\/p>\n<h3>Stage 4. Mux: speech over video, and the hypnotic loop<\/h3>\n<p>For each &quot;video + speech&quot; pair the script probes both durations and, if the video is shorter than the audio, loops the picture to the end of the line. A 50-millisecond margin in the condition kills false loops from probe rounding. Then ffmpeg lays the speech on top, trims to the length of the line, and encodes to H.264 + AAC.<\/p>\n<p>And this is where a symptom from the early run surfaced \u2014 the one we nicknamed hypnotic: a four-second B-roll spinning two or three times under one long line, the insert looking like a stuck GIF. The cause was exactly that the video was requested at a fixed short length while the model wrote long speech \u2014 nobody enforced the brief&#x27;s &quot;three to five seconds.&quot;<\/p>\n<p>The fix took three moves at once: TTS first with length from ffprobe; <code>ceil(speech)<\/code> into Seedance with a ten-second cap; and shortening the speech itself in the brief to one or two sentences. We kept the loop \u2014 but as a safety net for the rare case, not as the normal mode.<\/p>\n<p>Comparing the two generations of the pipeline turned out instructive:<\/p>\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>Early run<\/th>\n<th>After tightening<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Speech per slot<\/td>\n<td>long paragraphs (up to ~13s)<\/td>\n<td>1\u20132 short sentences (~5\u20136s)<\/td>\n<\/tr>\n<tr>\n<td>Video duration<\/td>\n<td>fixed 4s<\/td>\n<td>from TTS: 6 \/ 5 \/ 7 \/ 6s<\/td>\n<\/tr>\n<tr>\n<td>Looping<\/td>\n<td>all 4 clips<\/td>\n<td>none<\/td>\n<\/tr>\n<tr>\n<td>Video cost<\/td>\n<td>~$0.18<\/td>\n<td>~$0.28<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The paradox is right there: tightening made it more expensive. But more honest \u2014 no triple-spin of one clip under a long line. Those ten cents of difference buy back an insert that no longer hypnotizes the viewer.<\/p>\n<h3>Stage 5. Splicing phone footage with a neural net<\/h3>\n<p>The final reel is assembled from <code>timeline.json<\/code> \u2014 a plain list interleaving baseline clips from the phone with AI-insert numbers. The link between speech and clips rests on <strong>order<\/strong>, not on timecodes inside one file: any piece can be reshot without rebuilding the timing.<\/p>\n<p>The last gotcha waited at the seam between two worlds. iPhone <code>.MOV<\/code> and Seedance <code>.mp4<\/code> are almost always incompatible in codec, resolution, and frame rate \u2014 trying to splice them by stream-copy gives black frames or audio drift. So for the full reel we go straight to re-encode with a single canvas: scale + pad to a common size, 30 fps, yuv420p, AAC. Clips without an audio track get silence padded in, so the sound doesn&#x27;t jump at the seams. One such reel \u2014 six live shots plus four inserts \u2014 came out around 81 seconds and 113 MB. About right for vertical phone HD.<\/p>\n<h2>Manifests as an accounting ledger<\/h2>\n<p>Every paid or measurable stage writes a JSON next to its artifacts: speech durations and quota spent, the jobId and cost of each clip, whether the video looped. It sounds like bureaucracy, but it pays off immediately. From these files you can explain the OpenRouter and ElevenLabs bill clip by clip, rebuild a single insert instead of the whole reel, debug &quot;why did the video loop,&quot; and stop guessing where the Seedance length came from.<\/p>\n<p>The media itself (mp3, mp4, the source <code>.MOV<\/code>) sits in <code>.gitignore<\/code>. What stays in the repo is scripts, briefs, timeline, and manifests \u2014 reproducibility without gigabytes in the history.<\/p>\n<h2>The gotchas that didn&#x27;t make the main plot<\/h2>\n<p>A couple of stories worth their own paragraph, because each ate an evening.<\/p>\n<p><strong>A &quot;free&quot; voice that costs 402.<\/strong> We grabbed a library voice in ElevenLabs with an honest-looking &quot;available to free users&quot; tag \u2014 and got <code>paid_plan_required<\/code>. As it turns out, on the free tier the API only serves premade voices; shared\/library ones need a paid plan even when the catalog hints otherwise. <code>free_users_allowed: true<\/code> in the catalog does not mean the right to synthesize with a free key. For a &quot;native&quot; Russian timbre you need a paid plan or a different provider.<\/p>\n<p><strong><code>ffprobe-static<\/code> is not <code>ffmpeg-static<\/code>.<\/strong> One npm package exports a string path, the other an object <code>{ path }<\/code>. Mix them up and <code>spawn<\/code> falls over with <code>undefined<\/code> instead of a path. The cure is one line everywhere you call a binary: <code>typeof mod === &quot;string&quot; ? mod : mod?.path<\/code>.<\/p>\n<p><strong>Windows with no ffmpeg and a fake Python.<\/strong> On the test machine the system <code>python<\/code> opened the app store (a <code>WindowsApps<\/code> stub), and <code>ffmpeg<\/code> wasn&#x27;t in PATH at all. A Node-only pipeline plus static binaries pulled in by <code>npm install<\/code> into the skills closed the question without any &quot;please install ffmpeg for us.&quot;<\/p>\n<h2>Where the money is<\/h2>\n<p>The economics of one run over four inserts, 480p, short lines:<\/p>\n<table>\n<thead>\n<tr>\n<th>Stage<\/th>\n<th>Order of magnitude<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Slot fill (cheap chat model)<\/td>\n<td>~$0.01<\/td>\n<\/tr>\n<tr>\n<td>ElevenLabs TTS (free quota)<\/td>\n<td>$0 (or cents on paid)<\/td>\n<\/tr>\n<tr>\n<td>Seedance \u00d7 4<\/td>\n<td>~$0.20\u20130.35<\/td>\n<\/tr>\n<tr>\n<td>Mux and concat<\/td>\n<td>$0 (local CPU)<\/td>\n<\/tr>\n<tr>\n<td><strong>API total<\/strong><\/td>\n<td><strong>~$0.25\u20130.40<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The expensive part here isn&#x27;t the API \u2014 it&#x27;s the human: filming the live scaffold, the edit review, the legal read of the offer. The pipeline cheapens exactly the insert iterations \u2014 regenerating one CUT is cheaper than reshooting the whole reel. Which is precisely why the ten-second cap per clip and the ban on the model&#x27;s native audio aren&#x27;t micro-optimizations but product decisions. The OpenRouter video-model collection, by the way, sorts by popularity, not by price \u2014 it&#x27;s easy to pick an expensive model by not paying attention.<\/p>\n<h2>What carries over to other builds<\/h2>\n<p>Three takeaways transfer almost verbatim to any multimodal pipeline, not just reels.<\/p>\n<p>First: <strong>separate the immutable scaffold from the generated slots<\/strong> \u2014 in the data, in the code, and in the model&#x27;s permissions. Let an LLM rewrite everything and it will rewrite everything.<\/p>\n<p>Second: <strong>the duration of a multimodal clip is measured, not guessed.<\/strong> TTS \u2192 ffprobe \u2192 video length is the only order that doesn&#x27;t collapse into drift.<\/p>\n<p>Third: <strong>model constraints are part of the product design, not an integration bug.<\/strong> The 4\u201312 second range, free versus library voices, the cost of native audio \u2014 you bake these into the schema up front, not catch them at runtime on an HTTP 400.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The expert films the talking-head himself; the cutaways between his points are AI-generated \u2014 faceless video under synthesized speech. The story of how a one-off script grew into a five-stage pipeline, with the gotchas: hypnotic loops, &#8216;free&#8217; voices that answer 402, and a Seedance that refuses to shoot 3 seconds.<\/p>\n","protected":false},"author":0,"featured_media":79,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[65,66,67,63,64],"class_list":["post-80","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-engineering","tag-ffmpeg","tag-openrouter","tag-pipeline","tag-text-to-video","tag-tts"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.dobryakov.net\/blog\/80\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Grigoriy Dobryakov - IT+AI Blog - Grigoriy Dobryakov&#039;s blog: management, development and testing\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Building a hybrid reels pipeline: talking-head + AI B-roll\" \/>\n\t\t<meta property=\"og:description\" content=\"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.dobryakov.net\/blog\/80\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-07-28T12:34:44+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-07-28T12:34:44+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Building a hybrid reels pipeline: talking-head + AI B-roll\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/#blogposting\",\"name\":\"Building a hybrid reels pipeline: talking-head + AI B-roll\",\"headline\":\"How we built a hybrid reels pipeline: a real expert plus AI B-roll\",\"author\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/author\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/hybrid-reels-pipeline.jpg\",\"width\":1200,\"height\":630,\"caption\":\"How we built a hybrid reels pipeline: a real expert plus AI B-roll\"},\"datePublished\":\"2026-07-28T12:34:44+00:00\",\"dateModified\":\"2026-07-28T12:34:44+00:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/#webpage\"},\"articleSection\":\"AI Engineering, ffmpeg, OpenRouter, pipeline, text-to-video, TTS\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/category\\\/ai-engineering\\\/#listItem\",\"name\":\"AI Engineering\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/category\\\/ai-engineering\\\/#listItem\",\"position\":2,\"name\":\"AI Engineering\",\"item\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/category\\\/ai-engineering\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/#listItem\",\"name\":\"How we built a hybrid reels pipeline: a real expert plus AI B-roll\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/#listItem\",\"position\":3,\"name\":\"How we built a hybrid reels pipeline: a real expert plus AI B-roll\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/category\\\/ai-engineering\\\/#listItem\",\"name\":\"AI Engineering\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/#organization\",\"name\":\"Grigoriy Dobryakov - IT+AI Blog\",\"description\":\"Grigoriy Dobryakov's blog: management, development and testing\",\"url\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/#webpage\",\"url\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/\",\"name\":\"Building a hybrid reels pipeline: talking-head + AI B-roll\",\"description\":\"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/author\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/author\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/hybrid-reels-pipeline.jpg\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/#mainImage\",\"width\":1200,\"height\":630,\"caption\":\"How we built a hybrid reels pipeline: a real expert plus AI B-roll\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/80\\\/#mainImage\"},\"datePublished\":\"2026-07-28T12:34:44+00:00\",\"dateModified\":\"2026-07-28T12:34:44+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/\",\"name\":\"Grigoriy Dobryakov - IT+AI Blog\",\"description\":\"Grigoriy Dobryakov's blog: management, development and testing\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.dobryakov.net\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Building a hybrid reels pipeline: talking-head + AI B-roll","description":"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on.","canonical_url":"https:\/\/www.dobryakov.net\/blog\/80\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/www.dobryakov.net\/blog\/80\/#blogposting","name":"Building a hybrid reels pipeline: talking-head + AI B-roll","headline":"How we built a hybrid reels pipeline: a real expert plus AI B-roll","author":{"@id":"https:\/\/www.dobryakov.net\/blog\/author\/#author"},"publisher":{"@id":"https:\/\/www.dobryakov.net\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/www.dobryakov.net\/blog\/wp-content\/uploads\/2026\/07\/hybrid-reels-pipeline.jpg","width":1200,"height":630,"caption":"How we built a hybrid reels pipeline: a real expert plus AI B-roll"},"datePublished":"2026-07-28T12:34:44+00:00","dateModified":"2026-07-28T12:34:44+00:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.dobryakov.net\/blog\/80\/#webpage"},"isPartOf":{"@id":"https:\/\/www.dobryakov.net\/blog\/80\/#webpage"},"articleSection":"AI Engineering, ffmpeg, OpenRouter, pipeline, text-to-video, TTS"},{"@type":"BreadcrumbList","@id":"https:\/\/www.dobryakov.net\/blog\/80\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog#listItem","position":1,"name":"Home","item":"https:\/\/www.dobryakov.net\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog\/category\/ai-engineering\/#listItem","name":"AI Engineering"}},{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog\/category\/ai-engineering\/#listItem","position":2,"name":"AI Engineering","item":"https:\/\/www.dobryakov.net\/blog\/category\/ai-engineering\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog\/80\/#listItem","name":"How we built a hybrid reels pipeline: a real expert plus AI B-roll"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog\/80\/#listItem","position":3,"name":"How we built a hybrid reels pipeline: a real expert plus AI B-roll","previousItem":{"@type":"ListItem","@id":"https:\/\/www.dobryakov.net\/blog\/category\/ai-engineering\/#listItem","name":"AI Engineering"}}]},{"@type":"Organization","@id":"https:\/\/www.dobryakov.net\/blog\/#organization","name":"Grigoriy Dobryakov - IT+AI Blog","description":"Grigoriy Dobryakov's blog: management, development and testing","url":"https:\/\/www.dobryakov.net\/blog\/"},{"@type":"WebPage","@id":"https:\/\/www.dobryakov.net\/blog\/80\/#webpage","url":"https:\/\/www.dobryakov.net\/blog\/80\/","name":"Building a hybrid reels pipeline: talking-head + AI B-roll","description":"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.dobryakov.net\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.dobryakov.net\/blog\/80\/#breadcrumblist"},"author":{"@id":"https:\/\/www.dobryakov.net\/blog\/author\/#author"},"creator":{"@id":"https:\/\/www.dobryakov.net\/blog\/author\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/www.dobryakov.net\/blog\/wp-content\/uploads\/2026\/07\/hybrid-reels-pipeline.jpg","@id":"https:\/\/www.dobryakov.net\/blog\/80\/#mainImage","width":1200,"height":630,"caption":"How we built a hybrid reels pipeline: a real expert plus AI B-roll"},"primaryImageOfPage":{"@id":"https:\/\/www.dobryakov.net\/blog\/80\/#mainImage"},"datePublished":"2026-07-28T12:34:44+00:00","dateModified":"2026-07-28T12:34:44+00:00"},{"@type":"WebSite","@id":"https:\/\/www.dobryakov.net\/blog\/#website","url":"https:\/\/www.dobryakov.net\/blog\/","name":"Grigoriy Dobryakov - IT+AI Blog","description":"Grigoriy Dobryakov's blog: management, development and testing","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.dobryakov.net\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Grigoriy Dobryakov - IT+AI Blog - Grigoriy Dobryakov's blog: management, development and testing","og:type":"article","og:title":"Building a hybrid reels pipeline: talking-head + AI B-roll","og:description":"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on.","og:url":"https:\/\/www.dobryakov.net\/blog\/80\/","article:published_time":"2026-07-28T12:34:44+00:00","article:modified_time":"2026-07-28T12:34:44+00:00","twitter:card":"summary_large_image","twitter:title":"Building a hybrid reels pipeline: talking-head + AI B-roll","twitter:description":"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on."},"aioseo_meta_data":{"post_id":"80","title":"Building a hybrid reels pipeline: talking-head + AI B-roll","description":"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on.","keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":"Building a hybrid reels pipeline: talking-head + AI B-roll","og_description":"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on.","og_object_type":"default","og_image_type":"default","og_image_custom_url":null,"og_image_custom_fields":null,"og_image_url":null,"og_image_width":null,"og_image_height":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_image_url":null,"twitter_title":"Building a hybrid reels pipeline: talking-head + AI B-roll","twitter_description":"Hybrid reels: a real expert on camera plus faceless AI cutaways under TTS. Five Node stages, clip length measured from ffprobe, a cost guard on Seedance, and the eight gotchas the pipeline broke on.","schema_type":"default","schema_type_options":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null,"created":"2026-07-28 12:35:02","updated":"2026-07-28 12:41:29"},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.dobryakov.net\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.dobryakov.net\/blog\/category\/ai-engineering\/\" title=\"AI Engineering\">AI Engineering<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tHow we built a hybrid reels pipeline: a real expert plus AI B-roll\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.dobryakov.net\/blog"},{"label":"AI Engineering","link":"https:\/\/www.dobryakov.net\/blog\/category\/ai-engineering\/"},{"label":"How we built a hybrid reels pipeline: a real expert plus AI B-roll","link":"https:\/\/www.dobryakov.net\/blog\/80\/"}],"_links":{"self":[{"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/posts\/80","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/comments?post=80"}],"version-history":[{"count":0,"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/posts\/80\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/media\/79"}],"wp:attachment":[{"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/media?parent=80"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/categories?post=80"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dobryakov.net\/blog\/wp-json\/wp\/v2\/tags?post=80"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}