)
LifeOS Remotion 技能实战使用 Mediabunny 精确获取视频时长秒【免费下载链接】LifeOS⛰️ The Life Operating System — an intent engineering platform that moves you from your current state to your ideal state, in life and work.项目地址: https://gitcode.com/GitHub_Trending/pe/LifeOS导读在 LifeOS 的 Remotion 编程化视频生产链路中几乎所有自动化流程内容转动画、动态时长编排、多素材拼接都依赖一个前置能力先拿到视频文件的精确时长。本文以 Remotion 技能的参考文档 Ref-get-video-duration.md 为主体结合仓库中同系列的音频时长、视频尺寸、calculateMetadata动态编排等源码级文档系统讲解如何用 Mediabunny 的Input.computeDuration()在浏览器、Node.js、Bun 三种环境中读取视频时长并给出远程 URL、本地文件、RemotionstaticFile()三种数据源与组合成动态时长的完整实战方案。读完本文你将能写出可复用的getVideoDuration工具函数并把它接入 Remotion 组合的动态元数据计算。Mediabunny 是什么为什么用它在 LifeOS 的 Remotion 技能体系中视频时长读取由Mediabunny承担。这是一个统一的媒体解析库能从媒体文件中提取时长、尺寸、轨道等元数据。它的关键特性是跨环境一致同一套 API 在浏览器、Node.js、Bun 中都能工作这与 Remotion 技能代码即视频、结果确定性可复现的理念一致——SKILL.md 中明确指出 Remotion 的每一帧都由useCurrentFrame()驱动而非 CSS 动画保证输出确定性与可复现性时长作为组合Composition的输入参数自然也需要一个确定、可编程的获取途径。从仓库的 Tools/package.json 可以看到该技能以remotion 4.0.0为 peer 依赖运行环境为 Bunbunx而非npx这是 CriticalRules.md 第 10 条硬性规定因此 Mediabunny 对 Bun 的原生支持与整个技能栈是无缝衔接的。核心 APIInputcomputeDuration()参考文档给出的最小实现是一个纯函数getVideoDuration它把构造输入源与计算时长两个动作封装起来import { Input, ALL_FORMATS, UrlSource } from mediabunny; export const getVideoDuration async (src: string) { const input new Input({ formats: ALL_FORMATS, source: new UrlSource(src, { getRetryDelay: () null, }), }); const durationInSeconds await input.computeDuration(); return durationInSeconds; };拆解这段代码理解每个参数的实际作用ALL_FORMATS告诉 Mediabunny 允许使用全部媒体封装格式MP4、WebM、MOV 等来解析。从源码结构看formats是Input的核心配置项决定解析器允许探测的容器类型全部启用可以最大化兼容不同来源的视频文件。UrlSource(src, { getRetryDelay: () null })声明输入源为远程 URL。getRetryDelay回调用于控制网络重试策略——返回null表示不重试。这在读取不稳定的远程媒体时是一种快速失败策略宁可立刻报错也不让渲染管线长时间挂在重试上渲染是 CPU 密集任务见 SKILL.md 的 Gotchas 部分。computeDuration()异步方法返回以秒为单位的时长类型为 number例如10.5表示 10.5 秒。时长可能是小数后续换算帧数时需要用Math.ceil()向上取整见下文接入动态时长。三种数据源URL、本地文件、staticFile1. 远程 URL默认场景把任意可访问的视频地址传给UrlSource即可const duration await getVideoDuration(https://remotion.media/video.mp4); console.log(duration); // e.g. 10.5 (seconds)远程源适合视频托管在 CDN、对象存储或第三方服务上的场景是 LifeOS 内容工作流中最常见的输入形式例如把 YouTube 视频转为动画时先拿到原视频时长用于编排。2. 本地文件改用FileSource当视频来自本地例如用户拖拽上传、文件选择器返回的File对象时不能再用UrlSource而是换成FileSourceimport { Input, ALL_FORMATS, FileSource } from mediabunny; const input new Input({ formats: ALL_FORMATS, source: new FileSource(file), // File object from input or drag-drop }); const durationInSeconds await input.computeDuration();注意FileSource接收的是浏览器环境中的File对象而不是文件路径字符串。这意味着本地文件时长读取天然面向浏览器内或运行时内存中已有文件对象的场景若你在 Node/Bun 后端拿到的是磁盘路径需要先以合适的方式构造文件对象再传入。3. Remotion 静态资源staticFile()在 Remotion 组合内部/public目录下的资源必须通过staticFile()引用而不能硬编码绝对路径或相对路径——CriticalRules.md 第 3 条明确要求ALWAYS usestaticFile()for/publicassets因为staticFile()在 Remotion Studio 预览和服务端渲染两种模式下都能正确解析路径。import { staticFile } from remotion; const duration await getVideoDuration(staticFile(video.mp4));把getVideoDuration与staticFile组合就能在渲染前读取打包进项目的素材时长。这与 Ref-videos.md 中Video src{staticFile(video.mp4)} /的用法完全一致构成读时长→设时长→渲染视频的完整闭环。把时长接进 RemotioncalculateMetadata动态编排单纯拿到时长还不够它真正的价值在于驱动Composition的动态元数据。参考文档 Ref-calculate-metadata.md 给出了标准接法用calculateMetadata在渲染前根据视频时长动态设置durationInFrames。单视频时长决定组合帧数import {CalculateMetadataFunction} from remotion; import {getMediaMetadata} from ../get-media-metadata; const calculateMetadata: CalculateMetadataFunctionProps async ({props}) { const {durationInSeconds} await getMediaMetadata(props.videoSrc); return { durationInFrames: Math.ceil(durationInSeconds * 30), }; };这里的换算关系是帧数 时长秒× fps。Math.ceil()向上取整保证帧数不会因为小数时长而不足避免组合在最后一帧被截断。getMediaMetadata与本文的getVideoDuration属于同一 Mediabunny 工具族——你可以直接在自己的getVideoDuration返回值上乘以 fps 完成换算。匹配视频尺寸进阶组合时长与尺寸可以一次同时设置让组合自动匹配素材分辨率const calculateMetadata: CalculateMetadataFunctionProps async ({props}) { const {durationInSeconds, dimensions} await getMediaMetadata(props.videoSrc); return { durationInFrames: Math.ceil(durationInSeconds * 30), width: dimensions?.width ?? 1920, height: dimensions?.height ?? 1080, }; };尺寸的读取方式可以参考同目录的 Ref-get-video-dimensions.md通过input.getPrimaryVideoTrack()拿到主视频轨道再读取track.displayWidth/track.displayHeight。两者配合即可实现视频是什么规格组合就是什么规格的自动化适配。多视频时长求和当组合由多个视频素材拼接而成时用Promise.all并行读取所有时长再求和const calculateMetadata: CalculateMetadataFunctionProps async ({props}) { const metadataPromises props.videos.map((video) getMediaMetadata(video.src)); const allMetadata await Promise.all(metadataPromises); const totalDuration allMetadata.reduce((sum, meta) sum meta.durationInSeconds, 0); return { durationInFrames: Math.ceil(totalDuration * 30), }; };这正好对应 LifeOS 的 ContentToAnimation.md 工作流中内容分镜 → 场景编排 → 总时长 90 (sections × 150) 90的时长规划逻辑无论分镜时长来自内容密度公式还是真实视频素材最终都要换算为durationInFrames交给组合。同一工具族音频时长与视频尺寸本文主角getVideoDuration不是孤立函数它与 Mediabunny 工具族共享完全一致的Input source computeXxx()模式。理解这一模式后其他元数据读取可以触类旁通音频时长Ref-get-audio-duration.md 提供getAudioDuration代码结构与本文几乎相同只是示例源换成https://remotion.media/audio.mp3返回180.5这类秒数值。当视频需要配乐、配音并据此设置音频轨时长时使用。视频尺寸Ref-get-video-dimensions.md 使用input.getPrimaryVideoTrack()读取displayWidth/displayHeight并通过if (!videoTrack) throw new Error(No video track found)做轨道缺失保护。三者共用的关键点是数据源构造UrlSource / FileSource / staticFile与元数据读取computeDuration / getPrimaryVideoTrack完全解耦你可以在getVideoDuration之上自由扩展例如返回一个包含时长、宽高、帧率的结构化MediaMetadata对象。常见陷阱与最佳实践结合仓库文档整理出使用 Mediabunny 读时长时最值得注意的几条规则远程源重试策略getRetryDelay: () null表示不重试。如果你的素材来自不稳定的 CDN可以按业务需要改为返回固定毫秒数实现有限重试但在渲染管线中建议保持快速失败避免后台渲染任务长时间挂起。本地文件必须用FileSource误用UrlSource传本地路径不会得到文件内容只会得到解析失败或网络请求错误。Remotion 内永远用staticFile()这是 CriticalRules.md 的硬性规则直接传/video.mp4在服务端渲染时可能解析失败。帧数换算向上取整Math.ceil(durationInSeconds * fps)避免小数帧导致的最后一帧截断或组合边界计算错误。环境差异意识Mediabunny 的跨环境一致是 API 层面的实际部署时仍需注意——例如FileSource依赖浏览器File对象Node/Bun 后端需先构造对应文件对象渲染用bunx remotion render见 SKILL.md 的 Quick Reference不要在 Bun 环境使用npx。与动态时长功能配合calculateMetadata支持动态设置durationInFrames、width、height、fps、props、defaultOutName等字段详见 Ref-calculate-metadata.md 的返回值清单读时长只是其中一环把它和defaultOutName、props变换组合可以构建完全数据驱动的视频生成管线。总结通过本文你掌握了在 LifeOS Remotion 技能中使用 Mediabunny 读取视频时长的完整方案以InputALL_FORMATS构造解析器用UrlSource/FileSource/staticFile()三种方式切换数据源以computeDuration()拿到秒级时长再通过calculateMetadata把时长换算为durationInFrames驱动组合动态渲染。这套读元数据 → 动态编排 → 渲染的模式同时覆盖音频时长与视频尺寸是 LifeOS 内容自动化生产链路中最基础也最关键的一环。进一步阅读参考文档原文见 Ref-get-video-duration.md同族工具见 Ref-get-audio-duration.md 与 Ref-get-video-dimensions.md动态编排见 Ref-calculate-metadata.md整个技能的总览与使用约束见 SKILL.md 与 CriticalRules.md。【免费下载链接】LifeOS⛰️ The Life Operating System — an intent engineering platform that moves you from your current state to your ideal state, in life and work.项目地址: https://gitcode.com/GitHub_Trending/pe/LifeOS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考