Skip to main content
warning
This package is experimental.
We might change the API at any time, until we remove this notice.

createVideoDecoder()v4.0.307

此函数是 VideoDecoder Web API 的封装器。

🌐 This function is a wrapper around the VideoDecoder Web API.

Create a video decoder
import {createVideoDecoder} from '@remotion/webcodecs'; const decoder = await createVideoDecoder({ track, onFrame: console.log, onError: console.error, });

VideoDecoder 的差异

🌐 Differences to VideoDecoder

  • 添加了两种新方法:.waitForQueueToBeLessThan().waitForFinish()
  • [dequeue](https://web.nodejs.cn/en-US/docs/Web/API/VideoDecoder/dequeue_event) 事件不被支持,因为它在不同浏览器中不可靠。
  • 除了 EncodedVideoChunk 之外,.decode() 也接受 EncodedVideoChunkInit 对象。
  • 可以将webcodecsController()实例传递给函数,从而允许解码被暂停、恢复和中止。
  • .decode() 是异步的,并返回一个 promise,如果解码器暂停,可以停止执行。
  • 可以将 logLevel 传递给函数,从而允许对队列进行调试。
  • [onFrame](#onframe) 回调正在被等待。当被拒绝时,错误会进入 [onError](#onerror) 回调。只有在解决后,队列大小计数器才会减少。

应用编程接口

🌐 API

接受具有以下属性的对象:

🌐 Takes an object with the following properties:

track

一个 VideoDecoderConfig 对象。
你可以传入一个来自 parseMedia()MediaParserVideoTrack 对象,它也是一个 VideoDecoderConfig 对象。

🌐 An VideoDecoderConfig object.
You may pass a MediaParserVideoTrack object from parseMedia(), which also is an VideoDecoderConfig object.

onFrame

当一帧被解码时调用的回调。

🌐 A callback that is called when a frame is decoded.

接受一个参数,该参数是一个VideoFrame对象。

🌐 Takes a single argument, which is a VideoFrame object.

如果传入的回调是异步的,队列大小计数器只有在回调被解决后才会减少。

🌐 If the passed callback is asynchronous, the queue size counter will be decreased only after the callback has been resolved.

然而,当你的回调仍在运行时,下一个帧的回调可能已经被调用。我们不能保证回调按顺序运行。

🌐 However, the callback for the next frame may already be called while your callback is still running.
We do not ensure that callbacks are running sequentially.

onError

当发生错误或通过控制器中止解码时调用的回调。

🌐 A callback that is called when an error occurs or the decode is aborted through the controller.

接受一个参数,该参数是一个Error对象。

🌐 Takes a single argument, which is an Error object.

controller?

一个 webcodecsController() 实例。

🌐 A webcodecsController() instance.

如果提供,你可以在控制器上调用 .pause().resume().abort() 来暂停、恢复和中止解码。

🌐 If provided, you can call .pause(), .resume() and .abort() on the controller to pause, resume and abort the decoding.

logLevel?

字符串 LogLevel

🌐 string LogLevel

"error""warn""info""debug""trace" 之一。
默认值:"info",仅记录重要信息。

🌐 One of "error", "warn", "info", "debug", "trace".
Default value: "info", which logs only important information.

返回类型

🌐 Return type

返回一个具有以下属性的对象:

🌐 Returns an object with the following properties:

waitForQueueToBeLessThan()

传入一个数字以等待队列少于给定数字。

🌐 Pass a number to wait for the queue to be less than the given number.

当队列大小小于给定数字时,返回一个解决的承诺。
只有在 onFrame 回调解决时,队列才会减少。

🌐 A promise that resolves when the queue size is less than the given number.
The queue is only decremented when the onFrame callback resolves.

flush()

刷新解码器,强制清除队列。返回一个在所有帧都已清除且 onFrame() 回调已为所有帧解析后解决的 Promise。

🌐 Flushes the decoder, forcing the queue to be cleared. Returns a promise that resolves when all frames have been cleared and the onFrame() callback has beeen resolved for all frames.

reset()

清除队列并重置解码器。与VideoDecoder.reset() + VideoDecoder.configure()相同。

🌐 Clears the queue and resets the decoder. Same as VideoDecoder.reset() + VideoDecoder.configure().

close()

关闭解码器。与 AudioDecoder.close() 相同。

🌐 Closes the decoder. Same as AudioDecoder.close().

checkReset()v4.0.312

返回一个带有 wasReset() 函数的句柄。如果在调用 .checkReset() 与调用 wasReset() 之间解码器被重置,wasReset() 将返回 true。参见下文 below 的示例。

🌐 Returns a handle with a wasReset() function. If the decoder was reset inbetween the call to .checkReset() and the call to wasReset(), wasReset() will return true. See below for an example.

getMostRecentSampleInput()v4.0.312

返回最近输入样本的 .timestamp

🌐 Return the .timestamp of the most recently input sample.

@remotion/media-parser 的示例用法

🌐 Example usage with @remotion/media-parser

Decode a video track
import {parseMedia} from '@remotion/media-parser'; import {createVideoDecoder} from '@remotion/webcodecs'; await parseMedia({ src: 'https://remotion.media/video.mp4', onVideoTrack: async ({track, container}) => { const decoder = await createVideoDecoder({ track, onFrame: console.log, onError: console.error, }); return async (sample) => { // Called on every sample await decoder.waitForQueueToBeLessThan(10); await decoder.decode(sample); return async () => { // Called when the track is done await decoder.flush(); decoder.close(); }; }; }, });

检查解码器是否已重置

🌐 Checking if the decoder was reset

你可能遇到的一个潜在竞争条件是,当样本正在等待队列少于某个数量时,decoder.reset() 被调用。使用 .checkReset() 检查解码器在任何异步操作后是否被重置,并在需要时中止样本的处理。

🌐 A potential race condition you may face is that decoder.reset() is called while a sample is waiting for the queue to be less than a certain number. Use .checkReset() to check if the decoder was reset after any asynchronous operation, and abort the processing of the sample if needed.

Check if the decoder was reset
import {parseMedia} from '@remotion/media-parser'; import {createVideoDecoder} from '@remotion/webcodecs'; await parseMedia({ src: 'https://remotion.media/video.mp4', onVideoTrack: async ({track, container}) => { const decoder = await createVideoDecoder({ track, onFrame: console.log, onError: console.error, }); return async (sample) => { const {wasReset} = decoder.checkReset(); await decoder.waitForQueueToBeLessThan(10); if (wasReset()) { return; } await decoder.decode(sample); if (wasReset()) { return; } return async () => { if (wasReset()) { return; } // Called when the track is done await decoder.flush(); decoder.close(); }; }; }, });

无法解码的视频v4.0.333

🌐 Undecodable videov4.0.333

如果浏览器无法解码视频,将抛出 VideoUndecodableError

🌐 If the video cannot be decoded by the browser, an VideoUndecodableError will be thrown.

Undecodable audio
import {VideoUndecodableError, createVideoDecoder} from '@remotion/webcodecs'; try { await createVideoDecoder({ track: {codec: 'invalid'}, onFrame: console.log, onError: console.error, }); } catch (error) { if (error instanceof VideoUndecodableError) { console.log('The video cannot be decoded by this browser'); } else { throw error; } }

另请参阅

🌐 See also