間線定位與過渡效果拆解)
用 Remotion 把散片段拼成一條片時(shí)間線定位與過渡效果拆解【免費(fèi)下載鏈接】remotion Make videos programmatically with React項(xiàng)目地址: https://gitcode.com/GitHub_Trending/re/remotion把三段不同長(zhǎng)度的素材卡著節(jié)奏排進(jìn)同一條時(shí)間線傳統(tǒng)做法是在剪輯軟件里手動(dòng)拖拽、逐幀對(duì)齊銜接處再補(bǔ)轉(zhuǎn)場(chǎng)關(guān)鍵幀素材一改就得重來。這篇文章用 Remotion 做程序化視頻拼接把拼接關(guān)系直接寫成代碼時(shí)間線、時(shí)長(zhǎng)與轉(zhuǎn)場(chǎng)全部可復(fù)現(xiàn)。最短路徑跑通一條命令初始化空白項(xiàng)目npx create-videolatest my-video --template blank cd my-video往合成文件里寫兩段片段打開新項(xiàng)目的src/Composition.tsx把內(nèi)容替換成兩段Sequence一行核心寫法長(zhǎng)這樣Sequence from{90} durationInFrames{150}Main //Sequence啟動(dòng) Studio 預(yù)覽畫面npm run dev瀏覽器里的 Studio 會(huì)打開預(yù)覽拖動(dòng)時(shí)間線可以看到兩段畫面在第 90 幀切換第一次視頻拼接就跑通了。如果跑通往下看原理如果報(bào)錯(cuò)跳到避坑清單章節(jié)。它是怎么工作的視頻拼接的核心對(duì)象是Sequence它把一組 React 組件包起來聲明這段內(nèi)容在全局時(shí)間線里的位置。兩個(gè)關(guān)鍵參數(shù)from起始幀號(hào)默認(rèn) 0durationInFrames持續(xù)幀數(shù)幀之于視頻猶如節(jié)拍之于音樂每段素材的起點(diǎn)和長(zhǎng)度都能用節(jié)拍說清楚時(shí)間線就完全確定。Sequence from{0} durationInFrames{90} {/* from: 起點(diǎn)幀durationInFrames: 長(zhǎng)度 */} Intro / /Sequence Sequence from{90} durationInFrames{150} {/* 起點(diǎn)正好接上一段的終點(diǎn)無縫拼接 */} Main / /SequenceSequence支持嵌套內(nèi)層序列的幀號(hào)相對(duì)外層重新計(jì)算每個(gè)模塊可以獨(dú)立開發(fā)調(diào)試實(shí)現(xiàn)見 packages/core/src/Sequence.tsx。把它用到真實(shí)場(chǎng)景多段視頻拼接三段不同長(zhǎng)度的素材首尾相接排在同一條時(shí)間線上。import {AbsoluteFill, Sequence, Video, staticFile} from remotion; export const Concat: React.FC () ( AbsoluteFill Sequence from{0} durationInFrames{120} {/* 片段一第 0–120 幀 */} Video src{staticFile(intro.mp4)} / /Sequence Sequence from{120} durationInFrames{180} {/* 片段二緊接片段一結(jié)束處 */} Video src{staticFile(main.mp4)} / /Sequence /AbsoluteFill );為什么這樣寫每段片段的起始幀等于前一段的結(jié)束幀時(shí)間線只有一份真值Video只會(huì)加載當(dāng)前播放范圍內(nèi)的媒體文件片段再多也不白占帶寬。從手動(dòng)重疊到聲明式轉(zhuǎn)場(chǎng)手寫淡入淡出要自己用插值算淡出與淡入兩段的透明度片段一多幀號(hào)就散得到處都是。remotion/transitions的TransitionSeries是自動(dòng)處理重疊的序列容器呈現(xiàn)效果做什么與時(shí)間曲線怎么做彼此分離。聲明每段時(shí)長(zhǎng)和轉(zhuǎn)場(chǎng)時(shí)長(zhǎng)即可總時(shí)長(zhǎng)自動(dòng)累加。帶淡入淡出的轉(zhuǎn)場(chǎng)拼接銜接處不想要硬切想要平滑溶解時(shí)替換掉TransitionSeries。import {TransitionSeries, linearTiming} from remotion/transitions; import {fade} from remotion/transitions/fade; export const WithTransition: React.FC () ( TransitionSeries TransitionSeries.Sequence durationInFrames{120}Intro //TransitionSeries.Sequence TransitionSeries.Transition presentation{fade()} timing{linearTiming({durationInFrames: 30})} / TransitionSeries.Sequence durationInFrames{180}Main //TransitionSeries.Sequence /TransitionSeries );為什么這樣寫30 幀的轉(zhuǎn)場(chǎng)時(shí)長(zhǎng)由容器自動(dòng)從上一段尾部與下一段頭部各取一半計(jì)算重疊無需手算換成slide或springTiming只改一個(gè)詞轉(zhuǎn)場(chǎng)拼接的效果即可切換。避坑清單癥狀視頻后段音畫逐漸錯(cuò)位。原因素材是可變幀率VFR渲染按固定幀推進(jìn)。處理導(dǎo)入前把素材轉(zhuǎn)成恒定幀率ffmpeg -i intro.mp4 -vsync cfr -r 30 intro-cfr.mp4癥狀預(yù)覽只出現(xiàn)第一段或成片尾部被截?cái)?。原因各片段from durationInFrames之和超過合成注冊(cè)總時(shí)長(zhǎng)多出來的部分被裁掉。處理注冊(cè)合成時(shí)把總時(shí)長(zhǎng)寫足Composition idConcat component{Concat} durationInFrames{300} fps{30} width{1920} height{1080} /癥狀性能/資源相關(guān)1080p 多段拼接渲染慢、內(nèi)存飆高。原因默認(rèn)全分辨率并行渲染視頻解碼占用大量?jī)?nèi)存。處理預(yù)覽降采樣、渲染降并發(fā)、中間幀改有損格式參數(shù)建議值作用--scale預(yù)覽0.5成片1預(yù)覽降分辨率流暢度更高--concurrencyCPU 核心數(shù) ÷ 2限制并行渲染幀數(shù)壓內(nèi)存峰值--image-formatjpeg幀以有損格式落盤減少磁盤寫入接下來往哪走轉(zhuǎn)場(chǎng)特效庫(kù)remotion/transitions內(nèi)置 fade、slide、crossZoom 等二十余種呈現(xiàn)效果可混用springTiming等時(shí)間曲線packages/transitions/項(xiàng)目模板template-blank 是空白骨架template-music-visualization 展示了多媒體源的視頻拼接結(jié)構(gòu)packages/template-blank/官方文檔docs 目錄里 Sequence、視頻與轉(zhuǎn)場(chǎng)各有專門章節(jié)查參數(shù)方便packages/docs/以上代碼均可在項(xiàng)目模板中找到對(duì)應(yīng)實(shí)現(xiàn)直接 fork 跑一遍比讀十遍文檔更快?!久赓M(fèi)下載鏈接】remotion Make videos programmatically with React項(xiàng)目地址: https://gitcode.com/GitHub_Trending/re/remotion創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考