
我给AI打工蓝耘元生代 Remotion 全自动生产每日技术新闻视频一条命令出成片实战视频每天花 30 分钟刷 HackerNews / GitHub Trending再用剪映剪一条技术日报视频要 1 小时。我用蓝耘元生代 MaaS 把「选题、写稿、分镜」压缩成一次 API 调用配上 Edge TTS 配音和 Remotion 渲染现在npm run pipeline一条命令5 分钟出一条 1080P 成片。这篇文章把完整工程拆开讲清楚。一、为什么我要做这件事做技术自媒体最消耗人的不是写观点而是重复的体力活环节传统做法耗时刷新闻选题HN / GitHub / 公众号来回切20 min写口播稿每条新闻组织语言30 min配音自己录 / 配音工具逐条对20 min剪辑剪映拖素材、对字幕40 min合计≈ 2 小时/天我的目标很明确把「创意」留给自己把「体力」全交给流水线。整条链路里只有一步真正需要大模型——从 25 条原始新闻里挑出 5 条并写成带分镜的口播脚本。这一步我选了蓝耘元生代 MaaS原因有三个OpenAI 兼容协议openaiSDK 直接复用只改baseURL和apiKey迁移成本为零支持response_format: json_object能强制模型输出合法 JSON这是整个流水线能自动跑起来的关键控制台能看到每次调用的 token 消耗和首 token 延迟调试 prompt 时能精确算账后面有截图二、整体架构一条流水线四个环节技术栈选型蓝耘元生代 MaaSdeepseek-v4-flash— 新闻筛选 口播稿 分镜 JSON 生成msedge-tts— 微软 Edge 神经网络语音免费、中文自然Remotion 4— 用 React 写视频数据驱动画面帧数由配音时长决定tsx TypeScript— 全流程类型安全三、核心实现蓝耘一次调用顶一个编辑部3.1 蓝耘客户端带 JSON 自愈重试这是整个项目唯一接大模型的地方。关键点有三个// scripts/lanyun-client.tsimportOpenAIfromopenai;exportconstlanyunnewOpenAI({apiKey:process.env.LANYUN_API_KEY,baseURL:process.env.LANYUN_BASE_URL??https://maas-api.lanyun.net/v1,});exportasyncfunctionchatJSONT(systemPrompt:string,userPrompt:string):PromiseT{constcallasync(extraInstruction){constresawaitlanyun.chat.completions.create({model:LANYUN_MODEL,// deepseek-v4-flashmessages:[{role:system,content:systemPromptextraInstruction},{role:user,content:userPrompt},],temperature:0.7,response_format:{type:json_object},// ← 关键强制 JSON});// 打印 token 用量方便去蓝耘控制台对账if(res.usage){console.log([lanyun] tokens: prompt${res.usage.prompt_tokens}completion${res.usage.completion_tokens});}returnres.choices[0]?.message?.content??;};constextract(text:string):T{constcleanedtext.replace(/json\s*|\s*/g,).trim();conststartcleaned.indexOf({);constendcleaned.lastIndexOf(});if(start-1||end-1)thrownewError(响应中未找到 JSON 对象);returnJSON.parse(cleaned.slice(start,end1))asT;};try{returnextract(awaitcall());}catch{// 自愈机制JSON 解析失败追加格式约束重试一次returnextract(awaitcall(\n【重要】上一次输出不是合法 JSON请只输出 JSON 对象。));}}踩坑记录 1即便开了json_object模式模型偶尔还是会在 JSON 外面包一层 json markdown 代码块或者首尾带解释性文字。所以解析层做了「剥代码块 截取首个{到末个}」的容错再加一次带格式约束的重试实测重试触发率 5%。3.2 一次调用完成「筛选 写稿 分镜」这是整条流水线信息密度最高的一步。我把 25 条原始新闻HN 15 条 GitHub Trending 10 条一次性喂给蓝耘让它返回一个结构完全固定的 JSON// scripts/generate-script.tsconstresultawaitchatJSONVideoScript(你是一位资深科技媒体主编正在制作面向开发者的「每日技术新闻日报」短视频。 你需要从候选新闻中挑出最有价值的 5 条优先 AI、大模型、开源、开发者工具并为每条写口播稿。 严格要求 1. 只输出一个 JSON 对象结构如下 { date: 10月7日, title: 节目总标题15字以内, opening: 开场白30字以内, scenes: [{ headline: 新闻标题20字以内, summary: 一句话概括30字以内, script: 口播稿正文60-90字口语化讲清楚是什么、为什么重要, tags: [2-3个标签], url: 从候选中原样复制的链接 }], closing: 结束语20字以内 } 2. script 必须是自然中文口播稿不能英文长句堆砌 3. url 必须从候选列表原样复制。,以下是今天抓取到的候选新闻\n\n${newsDigest});这个 prompt 的设计有三个刻意为之的点角色锚定“资深科技媒体主编”让语气稳定不会一会儿学术一会儿营销每个字段都给字数上限防止某条新闻写超了破坏视频节奏url强制从候选原样复制杜绝模型编造链接——这是 AI 生成内容最容易翻车的点蓝耘返回的script.json实测效果10月7日真实数据{title:模型大战与开源工具上新,opening:开发者朋友们好科技圈今天热闹不减五分钟带你看重点,scenes:[{headline:Mistral 发布旗舰模型 Large 4,summary:欧洲 Mistral 推出新一代旗舰大模型 Large 4,script:法国 Mistral 正式发布旗舰模型 Large 4推理、代码和多语言能力全面升级...对开发者来说这意味着又多了一个可商用、可私有部署的高性能选择欧洲阵营这次是认真来抢市场的。,tags:[大模型,Mistral,AI]},{headline:Reflection 开源 501B 参数模型 Beam,...},{headline:Polars 2.0 正式发布,...},{headline:DeepSeek 开源 GPU 算子库 DeepGEMM,...},{headline:claude-mem给智能体装上记忆,...}],closing:点个关注明天同一时间见}选题质量确实在线——5 条全部是当天开发者圈子真实热点蓝耘挑的优先级Mistral 旗舰 501B 开源 Polars 大版本 DeepSeek 基础设施 Agent 工具符合一个技术主编的判断。四、TTS 配音 时间轴生成拿到脚本后用微软 Edge TTS 把每段口播稿转成 MP3并用文件大小反推时长CBR 48kbps 恒定码率字节数 × 8 ÷ 48000 ≈ 秒数生成 Remotion 需要的timeline.json// scripts/generate-tts.tsconstVOICEzh-CN-XiaoxiaoNeural;// 女声自然流畅functionestimateDurationSec(filePath:string):number{constbytesfs.statSync(filePath).size;returnMath.max(1,(bytes*8)/48000);}// 口播 标题 正文听感更完整constdurawaitsynthesize(tts,${s.headline}。${s.script},file);scenes.push({...s,audioFile:audio/scene-${i}.mp3,audioDurationSec:dur});踩坑记录 2初版直接读 MP3 二进制头解析时长结果不同段的时长精度飘了几百毫秒导致画面和配音对不上。后来改成「恒定码率 → 用文件大小反推」误差控制在 10ms 内问题消失。生成的timeline.json长这样每段都带精确到毫秒的时长{openingDurationSec:5.808,scenes:[{headline:Mistral 发布旗舰模型 Large 4,audioDurationSec:23.592,...},{headline:Reflection 开源 501B 参数模型 Beam,audioDurationSec:21.936,...}],closingDurationSec:3.096}五、Remotion用 React 写视频帧数由配音决定这是整个方案最优雅的部分——视频时长完全由配音时长反推不需要手动对时间轴。5.1 主合成组件// src/compositions/DailyNews.tsx export const DailyNews: React.FC{ timeline: Timeline } ({ timeline }) { const sec2frames (sec: number) Math.ceil(sec * FPS) TRANSITION_FRAMES; const introFrames sec2frames(timeline.openingDurationSec); const sceneFrames timeline.scenes.map((s) sec2frames(s.audioDurationSec)); const outroFrames sec2frames(timeline.closingDurationSec); // 游标累加算出每段的起始帧 let cursor 0; const introFrom cursor; cursor introFrames; const sceneFroms sceneFrames.map((f) { const from cursor; cursor f; return from; }); return ( AbsoluteFill style{{ backgroundColor: #0a0e27 }} Sequence from{introFrom} durationInFrames{introFrames} Intro date{timeline.date} title{timeline.title} audioFile{timeline.openingAudio} / /Sequence {timeline.scenes.map((scene, i) ( Sequence key{i} from{sceneFroms[i]} durationInFrames{sceneFrames[i]} NewsScene {...scene} audioFile{scene.audioFile} / /Sequence ))} Sequence from{outroFrom} durationInFrames{outroFrames} Outro closing{timeline.closing} audioFile{timeline.closingAudio} / /Sequence /AbsoluteFill ); };数据驱动视频的核心思想timeline.json的每一段映射为一个Sequence帧数由配音时长决定画面永远跟声音严丝合缝。5.2 新闻场景组件带入场动画每条新闻的画面元素——序号大字弹簧动画、标题上移 淡入、标签胶囊、底部口播字幕条、顶部进度条——全部用 Remotion 的interpolate/spring声明式写// src/components/NewsScene.tsx const numSpring spring({ frame, fps, config: { damping: 10 } }); const headlineY interpolate(frame, [5, 25], [60, 0], { extrapolateRight: clamp }); const headlineOpacity interpolate(frame, [5, 25], [0, 1], { extrapolateRight: clamp }); const bodyOpacity interpolate(frame, [20, 40], [0, 1], { extrapolateRight: clamp });5.3 一条命令渲染// scripts/render.tsconstdurationInFramessec2frames(timeline.openingDurationSec)sec2frames(timeline.closingDurationSec)timeline.scenes.reduce((a,s)asec2frames(s.audioDurationSec),0);awaitrenderMedia({composition:{...composition,durationInFrames,fps:30,width:1920,height:1080},codec:h264,outputLocation:out/daily-news-${timeline.date}.mp4,onProgress:({progress}){process.stdout.write(\r[render]${(progress*100).toFixed(1)}%);},});渲染完成后拿到成片daily-news-10月7日.mp4约 14.7 MB六、平台 Web UI给非技术人员用流水线脚本是给开发者用的我还包了一层 Express 原生 HTML 的 Web 控制台让运营同学也能点点按钮出片左侧蓝耘 API Key / Base URL / 模型 ID 配置中间脚本与分镜可视化编辑生成后还能手动改改完重新配音渲染右侧运行日志实时滚动 成片列表在线播放这个「生成后还能人工微调」的设计很关键——AI 负责 90% 的体力活人负责最后 10% 的品味把关。七、蓝耘控制台实测数据整条流水线跑完一次蓝耘侧只发生1 次大模型调用脚本生成。打开蓝耘控制台能看到清晰的 token 消耗曲线从控制台读到的关键数据指标数值单次调用 prompt tokens≈ 460025 条新闻摘要 prompt单次调用 completion tokens≈ 7005 条分镜 JSON首 token 响应时间20~45s 区间波动调用成功率100%期间无失败记录单条视频大模型成本 ¥0.01这个成本量级意味着——每天跑一条视频一个月的模型开销不到 3 毛钱。对比请一个剪辑师或自己花 2 小时ROI 完全是碾压级的。八、踩坑与经验总结坑 1JSON 模式不是银弹开了response_format: json_object依然可能拿到 markdown 包裹的 JSON。解决剥代码块 截取首尾大括号 一次格式约束重试。坑 2MP3 时长解析精度二进制头解析在不同 VBR/CBR 文件上表现不稳。解决强制 TTS 输出 CBR 48kbps用文件大小反推时长。坑 3模型会编造 URL初版让模型自己回忆新闻链接结果 5 条里编了 2 条。解决prompt 里硬性要求url 必须从候选列表原样复制并把候选 URL 显式列在 user prompt 里。经验 1一次调用 多次调用最初我想每条新闻调一次模型后来发现把 25 条一次性喂进去让模型自己筛选写稿效果好得多——模型能看到全局选题优先级判断更准还省了 5 倍 token。经验 2数据驱动视频是真香Remotion timeline.json 的组合让视频长度这个问题彻底消失——配音多长画面就多长永远同步。九、写在最后这套流水线现在的状态✅npm run pipeline一条命令5 分钟出成片✅ 蓝耘单次调用完成选题 写稿 分镜成本 1 分钱✅ Web UI 支持生成后人工微调脚本✅ 1080P / 30fps / H.264可直接发 B 站 / 视频号后续想做的优化换蓝耘更长上下文的模型如 Kimi-K2把新闻全文喂进去而不只是摘要口播稿信息密度还能再提一档用蓝耘批量推理一次生成未来 7 天的脚本摊薄调用开销接蓝耘的文生图模型给每条新闻自动生成配图画面更丰富如果你也在做内容自动化强烈建议试试蓝耘元生代 MaaS——OpenAI 兼容意味着你现有的openaiSDK 代码改两行就能跑控制台还能看到每次调用的 token 明细调试 prompt 时心里特别有数。