diff --git a/.changeset/big-jokes-reflect.md b/.changeset/big-jokes-reflect.md new file mode 100644 index 00000000..429bb4ed --- /dev/null +++ b/.changeset/big-jokes-reflect.md @@ -0,0 +1,5 @@ +--- +'@webav/av-cliper': patch +--- + +fix: The output video has a corrupted image (artifacting) diff --git a/packages/av-cliper/demo/concat-media.ts b/packages/av-cliper/demo/concat-media.ts index e6e96943..abf1b925 100644 --- a/packages/av-cliper/demo/concat-media.ts +++ b/packages/av-cliper/demo/concat-media.ts @@ -25,7 +25,7 @@ document.querySelector('#mp4-img')?.addEventListener('click', () => { const spr1 = new OffscreenSprite( new MP4Clip((await fetch(resList[0])).body!), ); - spr1.time.duration = 3e6; + // spr1.time.duration = 3e6; const spr2 = new OffscreenSprite( new ImgClip( diff --git a/packages/av-cliper/src/mp4-utils/index.ts b/packages/av-cliper/src/mp4-utils/index.ts index ac30f80e..e20ffc91 100644 --- a/packages/av-cliper/src/mp4-utils/index.ts +++ b/packages/av-cliper/src/mp4-utils/index.ts @@ -211,7 +211,7 @@ function encodeVideoTrack( let lastAddedSampleTime = 0; // 双编码器交替消费,保证帧的顺序 // 小于期望帧间隔帧判定为连续的 - const deltaTime = Math.floor((1000 / opts.expectFPS) * 1e6); + const deltaTime = Math.floor((1000 / opts.expectFPS) * 1e3); function checkCache() { if (!audioReady) return; const nextEncId = curEncId === 'encoder1' ? 'encoder0' : 'encoder1'; @@ -231,7 +231,11 @@ function encodeVideoTrack( // 检测是否需要切换消费队列 const nextFirst = nextCache[0]; // 另一个队列跟已消费的最后一帧是连续的,则需要切换 - if (nextFirst != null && nextFirst.cts - lastAddedSampleTime < deltaTime) { + if ( + nextFirst != null && + nextFirst.is_sync && + nextFirst.cts - lastAddedSampleTime < deltaTime + ) { curEncId = nextEncId; // 说明另一个队列有数据,尽快消费 checkCache();