webcodecs-node 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +656 -0
- package/README.md +607 -0
- package/dist/AudioData.d.ts +6 -0
- package/dist/AudioData.d.ts.map +1 -0
- package/dist/AudioData.js +6 -0
- package/dist/AudioData.js.map +1 -0
- package/dist/AudioDecoder.d.ts +6 -0
- package/dist/AudioDecoder.d.ts.map +1 -0
- package/dist/AudioDecoder.js +6 -0
- package/dist/AudioDecoder.js.map +1 -0
- package/dist/AudioEncoder.d.ts +6 -0
- package/dist/AudioEncoder.d.ts.map +1 -0
- package/dist/AudioEncoder.js +6 -0
- package/dist/AudioEncoder.js.map +1 -0
- package/dist/EncodedAudioChunk.d.ts +6 -0
- package/dist/EncodedAudioChunk.d.ts.map +1 -0
- package/dist/EncodedAudioChunk.js +6 -0
- package/dist/EncodedAudioChunk.js.map +1 -0
- package/dist/EncodedVideoChunk.d.ts +6 -0
- package/dist/EncodedVideoChunk.d.ts.map +1 -0
- package/dist/EncodedVideoChunk.js +6 -0
- package/dist/EncodedVideoChunk.js.map +1 -0
- package/dist/FFmpegProcess.d.ts +6 -0
- package/dist/FFmpegProcess.d.ts.map +1 -0
- package/dist/FFmpegProcess.js +6 -0
- package/dist/FFmpegProcess.js.map +1 -0
- package/dist/HardwareAcceleration.d.ts +6 -0
- package/dist/HardwareAcceleration.d.ts.map +1 -0
- package/dist/HardwareAcceleration.js +6 -0
- package/dist/HardwareAcceleration.js.map +1 -0
- package/dist/ImageDecoder.d.ts +6 -0
- package/dist/ImageDecoder.d.ts.map +1 -0
- package/dist/ImageDecoder.js +6 -0
- package/dist/ImageDecoder.js.map +1 -0
- package/dist/Logger.d.ts +6 -0
- package/dist/Logger.d.ts.map +1 -0
- package/dist/Logger.js +6 -0
- package/dist/Logger.js.map +1 -0
- package/dist/MediaCapabilities.d.ts +9 -0
- package/dist/MediaCapabilities.d.ts.map +1 -0
- package/dist/MediaCapabilities.js +8 -0
- package/dist/MediaCapabilities.js.map +1 -0
- package/dist/VideoDecoder.d.ts +6 -0
- package/dist/VideoDecoder.d.ts.map +1 -0
- package/dist/VideoDecoder.js +6 -0
- package/dist/VideoDecoder.js.map +1 -0
- package/dist/VideoEncoder.d.ts +6 -0
- package/dist/VideoEncoder.d.ts.map +1 -0
- package/dist/VideoEncoder.js +6 -0
- package/dist/VideoEncoder.js.map +1 -0
- package/dist/VideoFrame.d.ts +10 -0
- package/dist/VideoFrame.d.ts.map +1 -0
- package/dist/VideoFrame.js +9 -0
- package/dist/VideoFrame.js.map +1 -0
- package/dist/__tests__/AudioData.test.d.ts +5 -0
- package/dist/__tests__/AudioData.test.d.ts.map +1 -0
- package/dist/__tests__/AudioData.test.js +179 -0
- package/dist/__tests__/AudioData.test.js.map +1 -0
- package/dist/__tests__/AudioDecoder.test.d.ts +5 -0
- package/dist/__tests__/AudioDecoder.test.d.ts.map +1 -0
- package/dist/__tests__/AudioDecoder.test.js +733 -0
- package/dist/__tests__/AudioDecoder.test.js.map +1 -0
- package/dist/__tests__/AudioEncoder.test.d.ts +5 -0
- package/dist/__tests__/AudioEncoder.test.d.ts.map +1 -0
- package/dist/__tests__/AudioEncoder.test.js +247 -0
- package/dist/__tests__/AudioEncoder.test.js.map +1 -0
- package/dist/__tests__/EncodedChunks.test.d.ts +5 -0
- package/dist/__tests__/EncodedChunks.test.d.ts.map +1 -0
- package/dist/__tests__/EncodedChunks.test.js +99 -0
- package/dist/__tests__/EncodedChunks.test.js.map +1 -0
- package/dist/__tests__/HardwareAcceleration.test.d.ts +5 -0
- package/dist/__tests__/HardwareAcceleration.test.d.ts.map +1 -0
- package/dist/__tests__/HardwareAcceleration.test.js +84 -0
- package/dist/__tests__/HardwareAcceleration.test.js.map +1 -0
- package/dist/__tests__/ImageDecoder.test.d.ts +5 -0
- package/dist/__tests__/ImageDecoder.test.d.ts.map +1 -0
- package/dist/__tests__/ImageDecoder.test.js +587 -0
- package/dist/__tests__/ImageDecoder.test.js.map +1 -0
- package/dist/__tests__/MediaCapabilities.test.d.ts +5 -0
- package/dist/__tests__/MediaCapabilities.test.d.ts.map +1 -0
- package/dist/__tests__/MediaCapabilities.test.js +346 -0
- package/dist/__tests__/MediaCapabilities.test.js.map +1 -0
- package/dist/__tests__/VideoDecoder.test.d.ts +5 -0
- package/dist/__tests__/VideoDecoder.test.d.ts.map +1 -0
- package/dist/__tests__/VideoDecoder.test.js +675 -0
- package/dist/__tests__/VideoDecoder.test.js.map +1 -0
- package/dist/__tests__/VideoEncoder.test.d.ts +5 -0
- package/dist/__tests__/VideoEncoder.test.d.ts.map +1 -0
- package/dist/__tests__/VideoEncoder.test.js +468 -0
- package/dist/__tests__/VideoEncoder.test.js.map +1 -0
- package/dist/__tests__/VideoFrame.test.d.ts +5 -0
- package/dist/__tests__/VideoFrame.test.d.ts.map +1 -0
- package/dist/__tests__/VideoFrame.test.js +243 -0
- package/dist/__tests__/VideoFrame.test.js.map +1 -0
- package/dist/__tests__/aac-utils.test.d.ts +2 -0
- package/dist/__tests__/aac-utils.test.d.ts.map +1 -0
- package/dist/__tests__/aac-utils.test.js +37 -0
- package/dist/__tests__/aac-utils.test.js.map +1 -0
- package/dist/__tests__/avc-utils.test.d.ts +2 -0
- package/dist/__tests__/avc-utils.test.d.ts.map +1 -0
- package/dist/__tests__/avc-utils.test.js +63 -0
- package/dist/__tests__/avc-utils.test.js.map +1 -0
- package/dist/__tests__/hevc-utils.test.d.ts +2 -0
- package/dist/__tests__/hevc-utils.test.d.ts.map +1 -0
- package/dist/__tests__/hevc-utils.test.js +78 -0
- package/dist/__tests__/hevc-utils.test.js.map +1 -0
- package/dist/capabilities/MediaCapabilities.d.ts +78 -0
- package/dist/capabilities/MediaCapabilities.d.ts.map +1 -0
- package/dist/capabilities/MediaCapabilities.js +276 -0
- package/dist/capabilities/MediaCapabilities.js.map +1 -0
- package/dist/capabilities/codecs.d.ts +72 -0
- package/dist/capabilities/codecs.d.ts.map +1 -0
- package/dist/capabilities/codecs.js +153 -0
- package/dist/capabilities/codecs.js.map +1 -0
- package/dist/capabilities/index.d.ts +7 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +8 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/types.d.ts +77 -0
- package/dist/capabilities/types.d.ts.map +1 -0
- package/dist/capabilities/types.js +5 -0
- package/dist/capabilities/types.js.map +1 -0
- package/dist/core/AudioData.d.ts +36 -0
- package/dist/core/AudioData.d.ts.map +1 -0
- package/dist/core/AudioData.js +229 -0
- package/dist/core/AudioData.js.map +1 -0
- package/dist/core/EncodedAudioChunk.d.ts +26 -0
- package/dist/core/EncodedAudioChunk.d.ts.map +1 -0
- package/dist/core/EncodedAudioChunk.js +58 -0
- package/dist/core/EncodedAudioChunk.js.map +1 -0
- package/dist/core/EncodedVideoChunk.d.ts +23 -0
- package/dist/core/EncodedVideoChunk.d.ts.map +1 -0
- package/dist/core/EncodedVideoChunk.js +55 -0
- package/dist/core/EncodedVideoChunk.js.map +1 -0
- package/dist/core/VideoFrame.d.ts +61 -0
- package/dist/core/VideoFrame.d.ts.map +1 -0
- package/dist/core/VideoFrame.js +385 -0
- package/dist/core/VideoFrame.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -0
- package/dist/debug-h264.d.ts +5 -0
- package/dist/debug-h264.d.ts.map +1 -0
- package/dist/debug-h264.js +103 -0
- package/dist/debug-h264.js.map +1 -0
- package/dist/decoders/AudioDecoder.d.ts +57 -0
- package/dist/decoders/AudioDecoder.d.ts.map +1 -0
- package/dist/decoders/AudioDecoder.js +333 -0
- package/dist/decoders/AudioDecoder.js.map +1 -0
- package/dist/decoders/ImageDecoder.d.ts +111 -0
- package/dist/decoders/ImageDecoder.d.ts.map +1 -0
- package/dist/decoders/ImageDecoder.js +686 -0
- package/dist/decoders/ImageDecoder.js.map +1 -0
- package/dist/decoders/VideoDecoder.d.ts +70 -0
- package/dist/decoders/VideoDecoder.d.ts.map +1 -0
- package/dist/decoders/VideoDecoder.js +410 -0
- package/dist/decoders/VideoDecoder.js.map +1 -0
- package/dist/decoders/index.d.ts +8 -0
- package/dist/decoders/index.d.ts.map +1 -0
- package/dist/decoders/index.js +7 -0
- package/dist/decoders/index.js.map +1 -0
- package/dist/demos/demo-audio-opus.d.ts +5 -0
- package/dist/demos/demo-audio-opus.d.ts.map +1 -0
- package/dist/demos/demo-audio-opus.js +107 -0
- package/dist/demos/demo-audio-opus.js.map +1 -0
- package/dist/demos/demo-audio.d.ts +10 -0
- package/dist/demos/demo-audio.d.ts.map +1 -0
- package/dist/demos/demo-audio.js +135 -0
- package/dist/demos/demo-audio.js.map +1 -0
- package/dist/demos/demo-conversion.d.ts +13 -0
- package/dist/demos/demo-conversion.d.ts.map +1 -0
- package/dist/demos/demo-conversion.js +301 -0
- package/dist/demos/demo-conversion.js.map +1 -0
- package/dist/demos/demo-h264.d.ts +7 -0
- package/dist/demos/demo-h264.d.ts.map +1 -0
- package/dist/demos/demo-h264.js +134 -0
- package/dist/demos/demo-h264.js.map +1 -0
- package/dist/demos/demo-hwaccel-conversion.d.ts +8 -0
- package/dist/demos/demo-hwaccel-conversion.d.ts.map +1 -0
- package/dist/demos/demo-hwaccel-conversion.js +161 -0
- package/dist/demos/demo-hwaccel-conversion.js.map +1 -0
- package/dist/demos/demo-hwaccel.d.ts +7 -0
- package/dist/demos/demo-hwaccel.d.ts.map +1 -0
- package/dist/demos/demo-hwaccel.js +51 -0
- package/dist/demos/demo-hwaccel.js.map +1 -0
- package/dist/demos/demo-image.d.ts +12 -0
- package/dist/demos/demo-image.d.ts.map +1 -0
- package/dist/demos/demo-image.js +178 -0
- package/dist/demos/demo-image.js.map +1 -0
- package/dist/demos/demo-mediabunny.d.ts +7 -0
- package/dist/demos/demo-mediabunny.d.ts.map +1 -0
- package/dist/demos/demo-mediabunny.js +78 -0
- package/dist/demos/demo-mediabunny.js.map +1 -0
- package/dist/demos/demo-pipeline.d.ts +8 -0
- package/dist/demos/demo-pipeline.d.ts.map +1 -0
- package/dist/demos/demo-pipeline.js +83 -0
- package/dist/demos/demo-pipeline.js.map +1 -0
- package/dist/demos/demo-samples.d.ts +9 -0
- package/dist/demos/demo-samples.d.ts.map +1 -0
- package/dist/demos/demo-samples.js +413 -0
- package/dist/demos/demo-samples.js.map +1 -0
- package/dist/demos/demo-streaming.d.ts +8 -0
- package/dist/demos/demo-streaming.d.ts.map +1 -0
- package/dist/demos/demo-streaming.js +299 -0
- package/dist/demos/demo-streaming.js.map +1 -0
- package/dist/demos/demo-webcodecs.d.ts +8 -0
- package/dist/demos/demo-webcodecs.d.ts.map +1 -0
- package/dist/demos/demo-webcodecs.js +316 -0
- package/dist/demos/demo-webcodecs.js.map +1 -0
- package/dist/demos/demo.d.ts +10 -0
- package/dist/demos/demo.d.ts.map +1 -0
- package/dist/demos/demo.js +123 -0
- package/dist/demos/demo.js.map +1 -0
- package/dist/encoders/AudioEncoder.d.ts +69 -0
- package/dist/encoders/AudioEncoder.d.ts.map +1 -0
- package/dist/encoders/AudioEncoder.js +425 -0
- package/dist/encoders/AudioEncoder.js.map +1 -0
- package/dist/encoders/VideoEncoder.d.ts +80 -0
- package/dist/encoders/VideoEncoder.d.ts.map +1 -0
- package/dist/encoders/VideoEncoder.js +386 -0
- package/dist/encoders/VideoEncoder.js.map +1 -0
- package/dist/encoders/codecs/av1.d.ts +31 -0
- package/dist/encoders/codecs/av1.d.ts.map +1 -0
- package/dist/encoders/codecs/av1.js +66 -0
- package/dist/encoders/codecs/av1.js.map +1 -0
- package/dist/encoders/codecs/h264.d.ts +28 -0
- package/dist/encoders/codecs/h264.d.ts.map +1 -0
- package/dist/encoders/codecs/h264.js +95 -0
- package/dist/encoders/codecs/h264.js.map +1 -0
- package/dist/encoders/codecs/hevc.d.ts +28 -0
- package/dist/encoders/codecs/hevc.d.ts.map +1 -0
- package/dist/encoders/codecs/hevc.js +73 -0
- package/dist/encoders/codecs/hevc.js.map +1 -0
- package/dist/encoders/codecs/index.d.ts +19 -0
- package/dist/encoders/codecs/index.d.ts.map +1 -0
- package/dist/encoders/codecs/index.js +60 -0
- package/dist/encoders/codecs/index.js.map +1 -0
- package/dist/encoders/codecs/vp9.d.ts +29 -0
- package/dist/encoders/codecs/vp9.d.ts.map +1 -0
- package/dist/encoders/codecs/vp9.js +58 -0
- package/dist/encoders/codecs/vp9.js.map +1 -0
- package/dist/encoders/index.d.ts +8 -0
- package/dist/encoders/index.d.ts.map +1 -0
- package/dist/encoders/index.js +8 -0
- package/dist/encoders/index.js.map +1 -0
- package/dist/ffmpeg/FFmpegProcess.d.ts +111 -0
- package/dist/ffmpeg/FFmpegProcess.d.ts.map +1 -0
- package/dist/ffmpeg/FFmpegProcess.js +543 -0
- package/dist/ffmpeg/FFmpegProcess.js.map +1 -0
- package/dist/ffmpeg/audio-codecs.d.ts +59 -0
- package/dist/ffmpeg/audio-codecs.d.ts.map +1 -0
- package/dist/ffmpeg/audio-codecs.js +99 -0
- package/dist/ffmpeg/audio-codecs.js.map +1 -0
- package/dist/ffmpeg/formats.d.ts +42 -0
- package/dist/ffmpeg/formats.d.ts.map +1 -0
- package/dist/ffmpeg/formats.js +147 -0
- package/dist/ffmpeg/formats.js.map +1 -0
- package/dist/ffmpeg/index.d.ts +9 -0
- package/dist/ffmpeg/index.d.ts.map +1 -0
- package/dist/ffmpeg/index.js +13 -0
- package/dist/ffmpeg/index.js.map +1 -0
- package/dist/ffmpeg/parsers/annexb.d.ts +88 -0
- package/dist/ffmpeg/parsers/annexb.d.ts.map +1 -0
- package/dist/ffmpeg/parsers/annexb.js +201 -0
- package/dist/ffmpeg/parsers/annexb.js.map +1 -0
- package/dist/ffmpeg/parsers/index.d.ts +6 -0
- package/dist/ffmpeg/parsers/index.d.ts.map +1 -0
- package/dist/ffmpeg/parsers/index.js +8 -0
- package/dist/ffmpeg/parsers/index.js.map +1 -0
- package/dist/ffmpeg/parsers/ivf.d.ts +54 -0
- package/dist/ffmpeg/parsers/ivf.d.ts.map +1 -0
- package/dist/ffmpeg/parsers/ivf.js +109 -0
- package/dist/ffmpeg/parsers/ivf.js.map +1 -0
- package/dist/ffmpeg/types.d.ts +85 -0
- package/dist/ffmpeg/types.d.ts.map +1 -0
- package/dist/ffmpeg/types.js +8 -0
- package/dist/ffmpeg/types.js.map +1 -0
- package/dist/formats/audio-formats.d.ts +61 -0
- package/dist/formats/audio-formats.d.ts.map +1 -0
- package/dist/formats/audio-formats.js +113 -0
- package/dist/formats/audio-formats.js.map +1 -0
- package/dist/formats/color-space.d.ts +35 -0
- package/dist/formats/color-space.d.ts.map +1 -0
- package/dist/formats/color-space.js +62 -0
- package/dist/formats/color-space.js.map +1 -0
- package/dist/formats/conversions/frame-converter.d.ts +42 -0
- package/dist/formats/conversions/frame-converter.d.ts.map +1 -0
- package/dist/formats/conversions/frame-converter.js +244 -0
- package/dist/formats/conversions/frame-converter.js.map +1 -0
- package/dist/formats/conversions/index.d.ts +8 -0
- package/dist/formats/conversions/index.d.ts.map +1 -0
- package/dist/formats/conversions/index.js +10 -0
- package/dist/formats/conversions/index.js.map +1 -0
- package/dist/formats/index.d.ts +9 -0
- package/dist/formats/index.d.ts.map +1 -0
- package/dist/formats/index.js +14 -0
- package/dist/formats/index.js.map +1 -0
- package/dist/formats/parsers/index.d.ts +5 -0
- package/dist/formats/parsers/index.d.ts.map +1 -0
- package/dist/formats/parsers/index.js +5 -0
- package/dist/formats/parsers/index.js.map +1 -0
- package/dist/formats/parsers/webp.d.ts +16 -0
- package/dist/formats/parsers/webp.d.ts.map +1 -0
- package/dist/formats/parsers/webp.js +116 -0
- package/dist/formats/parsers/webp.js.map +1 -0
- package/dist/formats/pixel-formats.d.ts +41 -0
- package/dist/formats/pixel-formats.d.ts.map +1 -0
- package/dist/formats/pixel-formats.js +113 -0
- package/dist/formats/pixel-formats.js.map +1 -0
- package/dist/hardware/HardwareAcceleration.d.ts +6 -0
- package/dist/hardware/HardwareAcceleration.d.ts.map +1 -0
- package/dist/hardware/HardwareAcceleration.js +6 -0
- package/dist/hardware/HardwareAcceleration.js.map +1 -0
- package/dist/hardware/decoder-args.d.ts +25 -0
- package/dist/hardware/decoder-args.d.ts.map +1 -0
- package/dist/hardware/decoder-args.js +84 -0
- package/dist/hardware/decoder-args.js.map +1 -0
- package/dist/hardware/detection.d.ts +39 -0
- package/dist/hardware/detection.d.ts.map +1 -0
- package/dist/hardware/detection.js +178 -0
- package/dist/hardware/detection.js.map +1 -0
- package/dist/hardware/encoder-args.d.ts +38 -0
- package/dist/hardware/encoder-args.d.ts.map +1 -0
- package/dist/hardware/encoder-args.js +177 -0
- package/dist/hardware/encoder-args.js.map +1 -0
- package/dist/hardware/index.d.ts +12 -0
- package/dist/hardware/index.d.ts.map +1 -0
- package/dist/hardware/index.js +14 -0
- package/dist/hardware/index.js.map +1 -0
- package/dist/hardware/types.d.ts +29 -0
- package/dist/hardware/types.d.ts.map +1 -0
- package/dist/hardware/types.js +58 -0
- package/dist/hardware/types.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/mediabunny/FFmpegAudioDecoder.d.ts +37 -0
- package/dist/mediabunny/FFmpegAudioDecoder.d.ts.map +1 -0
- package/dist/mediabunny/FFmpegAudioDecoder.js +254 -0
- package/dist/mediabunny/FFmpegAudioDecoder.js.map +1 -0
- package/dist/mediabunny/FFmpegAudioEncoder.d.ts +77 -0
- package/dist/mediabunny/FFmpegAudioEncoder.d.ts.map +1 -0
- package/dist/mediabunny/FFmpegAudioEncoder.js +484 -0
- package/dist/mediabunny/FFmpegAudioEncoder.js.map +1 -0
- package/dist/mediabunny/FFmpegVideoDecoder.d.ts +58 -0
- package/dist/mediabunny/FFmpegVideoDecoder.d.ts.map +1 -0
- package/dist/mediabunny/FFmpegVideoDecoder.js +366 -0
- package/dist/mediabunny/FFmpegVideoDecoder.js.map +1 -0
- package/dist/mediabunny/FFmpegVideoEncoder.d.ts +77 -0
- package/dist/mediabunny/FFmpegVideoEncoder.d.ts.map +1 -0
- package/dist/mediabunny/FFmpegVideoEncoder.js +551 -0
- package/dist/mediabunny/FFmpegVideoEncoder.js.map +1 -0
- package/dist/mediabunny/index.d.ts +21 -0
- package/dist/mediabunny/index.d.ts.map +1 -0
- package/dist/mediabunny/index.js +33 -0
- package/dist/mediabunny/index.js.map +1 -0
- package/dist/polyfill.d.ts +27 -0
- package/dist/polyfill.d.ts.map +1 -0
- package/dist/polyfill.js +78 -0
- package/dist/polyfill.js.map +1 -0
- package/dist/polyfills/CanvasRenderingContext2DPolyfill.d.ts +72 -0
- package/dist/polyfills/CanvasRenderingContext2DPolyfill.d.ts.map +1 -0
- package/dist/polyfills/CanvasRenderingContext2DPolyfill.js +293 -0
- package/dist/polyfills/CanvasRenderingContext2DPolyfill.js.map +1 -0
- package/dist/polyfills/ImageDataPolyfill.d.ts +12 -0
- package/dist/polyfills/ImageDataPolyfill.d.ts.map +1 -0
- package/dist/polyfills/ImageDataPolyfill.js +22 -0
- package/dist/polyfills/ImageDataPolyfill.js.map +1 -0
- package/dist/polyfills/OffscreenCanvas.d.ts +15 -0
- package/dist/polyfills/OffscreenCanvas.d.ts.map +1 -0
- package/dist/polyfills/OffscreenCanvas.js +35 -0
- package/dist/polyfills/OffscreenCanvas.js.map +1 -0
- package/dist/polyfills/OffscreenCanvasPolyfill.d.ts +16 -0
- package/dist/polyfills/OffscreenCanvasPolyfill.d.ts.map +1 -0
- package/dist/polyfills/OffscreenCanvasPolyfill.js +46 -0
- package/dist/polyfills/OffscreenCanvasPolyfill.js.map +1 -0
- package/dist/polyfills/VideoFramePolyfill.d.ts +44 -0
- package/dist/polyfills/VideoFramePolyfill.d.ts.map +1 -0
- package/dist/polyfills/VideoFramePolyfill.js +98 -0
- package/dist/polyfills/VideoFramePolyfill.js.map +1 -0
- package/dist/tools/generate-capabilities-profile.d.ts +2 -0
- package/dist/tools/generate-capabilities-profile.d.ts.map +1 -0
- package/dist/tools/generate-capabilities-profile.js +63 -0
- package/dist/tools/generate-capabilities-profile.js.map +1 -0
- package/dist/types/audio.d.ts +26 -0
- package/dist/types/audio.d.ts.map +1 -0
- package/dist/types/audio.js +5 -0
- package/dist/types/audio.js.map +1 -0
- package/dist/types/common.d.ts +68 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +70 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/geometry.d.ts +35 -0
- package/dist/types/geometry.d.ts.map +1 -0
- package/dist/types/geometry.js +34 -0
- package/dist/types/geometry.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/video.d.ts +43 -0
- package/dist/types/video.d.ts.map +1 -0
- package/dist/types/video.js +5 -0
- package/dist/types/video.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/aac.d.ts +26 -0
- package/dist/utils/aac.d.ts.map +1 -0
- package/dist/utils/aac.js +129 -0
- package/dist/utils/aac.js.map +1 -0
- package/dist/utils/avc.d.ts +39 -0
- package/dist/utils/avc.d.ts.map +1 -0
- package/dist/utils/avc.js +225 -0
- package/dist/utils/avc.js.map +1 -0
- package/dist/utils/buffer.d.ts +25 -0
- package/dist/utils/buffer.d.ts.map +1 -0
- package/dist/utils/buffer.js +73 -0
- package/dist/utils/buffer.js.map +1 -0
- package/dist/utils/hevc.d.ts +27 -0
- package/dist/utils/hevc.d.ts.map +1 -0
- package/dist/utils/hevc.js +239 -0
- package/dist/utils/hevc.js.map +1 -0
- package/dist/utils/index.d.ts +11 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +16 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +55 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +110 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/type-guards.d.ts +50 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +49 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/dist/utils/validation.d.ts +32 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +66 -0
- package/dist/utils/validation.js.map +1 -0
- package/docs/api.md +506 -0
- package/docs/codecs.md +382 -0
- package/docs/configuration.md +442 -0
- package/examples/README.md +100 -0
- package/examples/audio-encoding.ts +85 -0
- package/examples/hardware-decoding.ts +245 -0
- package/examples/hardware-encoding.ts +231 -0
- package/examples/image-decoding.ts +145 -0
- package/examples/streaming.ts +151 -0
- package/examples/transparent-video.ts +162 -0
- package/examples/video-decoding.ts +107 -0
- package/examples/video-encoding.ts +93 -0
- package/package.json +105 -0
package/README.md
ADDED
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
# webcodecs-node
|
|
2
|
+
|
|
3
|
+
WebCodecs API implementation for Node.js using FFmpeg.
|
|
4
|
+
|
|
5
|
+
This package provides a Node.js-compatible implementation of the [WebCodecs API](https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API), enabling video and audio encoding/decoding in server-side JavaScript applications.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **VideoEncoder / VideoDecoder** - H.264, HEVC, VP8, VP9, AV1
|
|
10
|
+
- **AudioEncoder / AudioDecoder** - AAC, Opus, MP3, FLAC, Vorbis
|
|
11
|
+
- **ImageDecoder** - PNG, JPEG, WebP, GIF, AVIF, BMP, TIFF (including animated with frame timing)
|
|
12
|
+
- **VideoFrame / AudioData** - Frame-level data manipulation
|
|
13
|
+
- **MediaCapabilities** - Query codec support, smooth playback, and power efficiency
|
|
14
|
+
- **Hardware Acceleration** - VAAPI, NVENC, QSV support
|
|
15
|
+
- **Streaming Support** - Real-time frame-by-frame encoding/decoding
|
|
16
|
+
- **Latency Modes** - Configure for real-time streaming vs maximum compression
|
|
17
|
+
- **Bitrate Modes** - Constant, variable, and quantizer (CRF) encoding modes
|
|
18
|
+
- **Alpha Channel** - Preserve transparency with VP9 and AV1 codecs
|
|
19
|
+
- **Mediabunny Integration** - Custom encoders/decoders for file conversion
|
|
20
|
+
|
|
21
|
+
## Documentation
|
|
22
|
+
|
|
23
|
+
- [API Reference](./docs/api.md) - Detailed API documentation for all classes
|
|
24
|
+
- [Codec Support](./docs/codecs.md) - Supported video, audio, and image codecs
|
|
25
|
+
- [Configuration Guide](./docs/configuration.md) - bitrateMode, alpha, latencyMode, and more
|
|
26
|
+
- [Examples](./examples/) - Practical usage examples
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
- Node.js 18+
|
|
31
|
+
- FFmpeg with encoding libraries (libx264, libx265, libvpx, etc.)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Ubuntu/Debian
|
|
35
|
+
sudo apt install ffmpeg
|
|
36
|
+
|
|
37
|
+
# macOS
|
|
38
|
+
brew install ffmpeg
|
|
39
|
+
|
|
40
|
+
# Check installation
|
|
41
|
+
ffmpeg -version
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install webcodecs-node
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
### Using the Polyfill
|
|
53
|
+
|
|
54
|
+
Install the WebCodecs API globally to make it available as browser-compatible globals:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { installWebCodecsPolyfill } from 'webcodecs-node';
|
|
58
|
+
|
|
59
|
+
// Install globally
|
|
60
|
+
installWebCodecsPolyfill();
|
|
61
|
+
|
|
62
|
+
// Now use standard WebCodecs API
|
|
63
|
+
const encoder = new VideoEncoder({
|
|
64
|
+
output: (chunk, metadata) => {
|
|
65
|
+
console.log('Encoded chunk:', chunk.byteLength, 'bytes');
|
|
66
|
+
},
|
|
67
|
+
error: (e) => console.error(e),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
await encoder.configure({
|
|
71
|
+
codec: 'avc1.42001E', // H.264 Baseline
|
|
72
|
+
width: 1280,
|
|
73
|
+
height: 720,
|
|
74
|
+
bitrate: 2_000_000,
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Direct Import
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import {
|
|
82
|
+
VideoEncoder,
|
|
83
|
+
VideoDecoder,
|
|
84
|
+
VideoFrame,
|
|
85
|
+
AudioEncoder,
|
|
86
|
+
AudioDecoder,
|
|
87
|
+
AudioData,
|
|
88
|
+
ImageDecoder,
|
|
89
|
+
mediaCapabilities,
|
|
90
|
+
} from 'webcodecs-node';
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## API Reference
|
|
94
|
+
|
|
95
|
+
### VideoEncoder
|
|
96
|
+
|
|
97
|
+
Encodes raw video frames to compressed video.
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
const encoder = new VideoEncoder({
|
|
101
|
+
output: (chunk, metadata) => {
|
|
102
|
+
// chunk is EncodedVideoChunk
|
|
103
|
+
// metadata contains timing info
|
|
104
|
+
},
|
|
105
|
+
error: (e) => console.error(e),
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
await encoder.configure({
|
|
109
|
+
codec: 'avc1.42001E', // H.264
|
|
110
|
+
width: 1920,
|
|
111
|
+
height: 1080,
|
|
112
|
+
bitrate: 5_000_000,
|
|
113
|
+
framerate: 30,
|
|
114
|
+
bitrateMode: 'variable', // Optional: 'constant', 'variable', or 'quantizer'
|
|
115
|
+
latencyMode: 'realtime', // Optional: 'realtime' for streaming, 'quality' for best compression
|
|
116
|
+
hardwareAcceleration: 'prefer-hardware', // Optional: use GPU encoding
|
|
117
|
+
format: 'mp4', // Optional: 'annexb' (default) or 'mp4'
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Create a frame from raw RGBA data
|
|
121
|
+
const frame = new VideoFrame(rgbaBuffer, {
|
|
122
|
+
format: 'RGBA',
|
|
123
|
+
codedWidth: 1920,
|
|
124
|
+
codedHeight: 1080,
|
|
125
|
+
timestamp: 0,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
encoder.encode(frame);
|
|
129
|
+
frame.close();
|
|
130
|
+
|
|
131
|
+
await encoder.flush();
|
|
132
|
+
encoder.close();
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Supported codecs:**
|
|
136
|
+
- `avc1.*` - H.264/AVC
|
|
137
|
+
- `hev1.*`, `hvc1.*` - H.265/HEVC
|
|
138
|
+
- `vp8` - VP8
|
|
139
|
+
- `vp09.*` - VP9
|
|
140
|
+
- `av01.*` - AV1
|
|
141
|
+
|
|
142
|
+
### VideoDecoder
|
|
143
|
+
|
|
144
|
+
Decodes compressed video to raw frames.
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
const decoder = new VideoDecoder({
|
|
148
|
+
output: (frame) => {
|
|
149
|
+
// frame is VideoFrame with raw pixel data
|
|
150
|
+
console.log(`Frame: ${frame.codedWidth}x${frame.codedHeight}`);
|
|
151
|
+
frame.close();
|
|
152
|
+
},
|
|
153
|
+
error: (e) => console.error(e),
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
await decoder.configure({
|
|
157
|
+
codec: 'avc1.42001E',
|
|
158
|
+
codedWidth: 1920,
|
|
159
|
+
codedHeight: 1080,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Decode an encoded chunk
|
|
163
|
+
decoder.decode(encodedVideoChunk);
|
|
164
|
+
await decoder.flush();
|
|
165
|
+
decoder.close();
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### AudioEncoder
|
|
169
|
+
|
|
170
|
+
Encodes raw audio samples to compressed audio.
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
const encoder = new AudioEncoder({
|
|
174
|
+
output: (chunk, metadata) => {
|
|
175
|
+
console.log('Encoded audio:', chunk.byteLength, 'bytes');
|
|
176
|
+
},
|
|
177
|
+
error: (e) => console.error(e),
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
await encoder.configure({
|
|
181
|
+
codec: 'opus',
|
|
182
|
+
sampleRate: 48000,
|
|
183
|
+
numberOfChannels: 2,
|
|
184
|
+
bitrate: 128000,
|
|
185
|
+
format: 'aac', // Optional: 'adts' (default for AAC) or 'aac'
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Create audio data from raw samples
|
|
189
|
+
const audioData = new AudioData({
|
|
190
|
+
format: 'f32',
|
|
191
|
+
sampleRate: 48000,
|
|
192
|
+
numberOfChannels: 2,
|
|
193
|
+
numberOfFrames: 1024,
|
|
194
|
+
timestamp: 0,
|
|
195
|
+
data: float32Samples,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
encoder.encode(audioData);
|
|
199
|
+
audioData.close();
|
|
200
|
+
|
|
201
|
+
await encoder.flush();
|
|
202
|
+
encoder.close();
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Supported codecs:**
|
|
206
|
+
- `opus` - Opus
|
|
207
|
+
- `mp4a.40.2` - AAC-LC
|
|
208
|
+
- `mp3` - MP3
|
|
209
|
+
- `flac` - FLAC
|
|
210
|
+
- `vorbis` - Vorbis
|
|
211
|
+
|
|
212
|
+
### ImageDecoder
|
|
213
|
+
|
|
214
|
+
Decodes images (including animated) to VideoFrames. Fully compliant with the [WebCodecs ImageDecoder API](https://developer.mozilla.org/en-US/docs/Web/API/ImageDecoder).
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import { readFileSync } from 'fs';
|
|
218
|
+
|
|
219
|
+
const imageData = readFileSync('animation.gif');
|
|
220
|
+
|
|
221
|
+
const decoder = new ImageDecoder({
|
|
222
|
+
type: 'image/gif',
|
|
223
|
+
data: imageData,
|
|
224
|
+
// Optional: transfer ownership for zero-copy
|
|
225
|
+
// transfer: [imageData.buffer],
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// Wait for parsing to complete
|
|
229
|
+
await decoder.completed;
|
|
230
|
+
|
|
231
|
+
// Access track information
|
|
232
|
+
const track = decoder.tracks.selectedTrack;
|
|
233
|
+
console.log(`Type: ${decoder.type}`);
|
|
234
|
+
console.log(`Frames: ${track?.frameCount}`);
|
|
235
|
+
console.log(`Animated: ${track?.animated}`);
|
|
236
|
+
console.log(`Loop count: ${track?.repetitionCount}`); // Infinity = loop forever
|
|
237
|
+
|
|
238
|
+
// Decode each frame with timing info
|
|
239
|
+
for (let i = 0; i < track.frameCount; i++) {
|
|
240
|
+
const { image, complete } = await decoder.decode({ frameIndex: i });
|
|
241
|
+
console.log(`Frame ${i}: ${image.codedWidth}x${image.codedHeight}`);
|
|
242
|
+
console.log(` Timestamp: ${image.timestamp / 1000}ms`);
|
|
243
|
+
console.log(` Duration: ${image.duration / 1000}ms`);
|
|
244
|
+
image.close();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
decoder.close();
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Constructor options:**
|
|
251
|
+
- `type` - MIME type (required)
|
|
252
|
+
- `data` - ArrayBuffer, TypedArray, or ReadableStream (required)
|
|
253
|
+
- `transfer` - ArrayBuffer[] for zero-copy ownership
|
|
254
|
+
- `colorSpaceConversion` - 'none' | 'default'
|
|
255
|
+
- `desiredWidth` / `desiredHeight` - Target dimensions
|
|
256
|
+
- `preferAnimation` - Prefer animated track if available
|
|
257
|
+
- `premultiplyAlpha` - 'none' | 'premultiply' | 'default'
|
|
258
|
+
|
|
259
|
+
**Properties:**
|
|
260
|
+
- `type` - MIME type string
|
|
261
|
+
- `complete` - Boolean, true when data is buffered
|
|
262
|
+
- `completed` - Promise that resolves when ready
|
|
263
|
+
- `tracks` - ImageTrackList with track information
|
|
264
|
+
|
|
265
|
+
**Supported formats:**
|
|
266
|
+
- `image/png`, `image/apng`
|
|
267
|
+
- `image/jpeg`
|
|
268
|
+
- `image/webp`
|
|
269
|
+
- `image/gif`
|
|
270
|
+
- `image/avif`
|
|
271
|
+
- `image/bmp`
|
|
272
|
+
- `image/tiff`
|
|
273
|
+
|
|
274
|
+
### MediaCapabilities API
|
|
275
|
+
|
|
276
|
+
Query codec capabilities before encoding/decoding. Implements the standard [MediaCapabilities API](https://developer.mozilla.org/en-US/docs/Web/API/MediaCapabilities).
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
import { mediaCapabilities } from 'webcodecs-node';
|
|
280
|
+
|
|
281
|
+
// Query decoding capabilities
|
|
282
|
+
const decodeInfo = await mediaCapabilities.decodingInfo({
|
|
283
|
+
type: 'file',
|
|
284
|
+
video: {
|
|
285
|
+
contentType: 'video/mp4; codecs="avc1.42E01E"',
|
|
286
|
+
width: 1920,
|
|
287
|
+
height: 1080,
|
|
288
|
+
bitrate: 5_000_000,
|
|
289
|
+
framerate: 30,
|
|
290
|
+
},
|
|
291
|
+
audio: {
|
|
292
|
+
contentType: 'audio/mp4; codecs="mp4a.40.2"',
|
|
293
|
+
channels: 2,
|
|
294
|
+
bitrate: 128000,
|
|
295
|
+
samplerate: 44100,
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
console.log('Supported:', decodeInfo.supported);
|
|
300
|
+
console.log('Smooth playback:', decodeInfo.smooth);
|
|
301
|
+
console.log('Power efficient:', decodeInfo.powerEfficient);
|
|
302
|
+
|
|
303
|
+
// Query encoding capabilities
|
|
304
|
+
const encodeInfo = await mediaCapabilities.encodingInfo({
|
|
305
|
+
type: 'record',
|
|
306
|
+
video: {
|
|
307
|
+
contentType: 'video/webm; codecs="vp9"',
|
|
308
|
+
width: 1280,
|
|
309
|
+
height: 720,
|
|
310
|
+
bitrate: 2_000_000,
|
|
311
|
+
framerate: 30,
|
|
312
|
+
},
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
if (encodeInfo.supported && encodeInfo.powerEfficient) {
|
|
316
|
+
console.log('Hardware-accelerated encoding available!');
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Supported containers & codecs:**
|
|
321
|
+
| Container | Video Codecs | Audio Codecs |
|
|
322
|
+
|-----------|-------------|--------------|
|
|
323
|
+
| video/mp4 | H.264, HEVC, AV1 | AAC |
|
|
324
|
+
| video/webm | VP8, VP9, AV1 | Opus, Vorbis |
|
|
325
|
+
| audio/mp4 | - | AAC |
|
|
326
|
+
| audio/webm | - | Opus, Vorbis |
|
|
327
|
+
| audio/ogg | - | Opus, Vorbis, FLAC |
|
|
328
|
+
| audio/mpeg | - | MP3 |
|
|
329
|
+
|
|
330
|
+
**Result properties:**
|
|
331
|
+
- `supported` - Whether the configuration can be decoded/encoded
|
|
332
|
+
- `smooth` - Whether playback/encoding will be smooth (no dropped frames)
|
|
333
|
+
- `powerEfficient` - Whether hardware acceleration is available
|
|
334
|
+
|
|
335
|
+
### MediaCapabilities Profiles
|
|
336
|
+
|
|
337
|
+
By default, capability queries use heuristics (resolution, bitrate, detected hardware). You can provide a detailed profile generated from the local FFmpeg installation:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
# Generate a JSON profile alongside the repo (builds first)
|
|
341
|
+
npm run capabilities:generate -- ./webcodecs-capabilities.json
|
|
342
|
+
|
|
343
|
+
# Point WebCodecs at the profile
|
|
344
|
+
export WEBCODECS_CAPABILITIES_PROFILE=$(pwd)/webcodecs-capabilities.json
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
`decodingInfo` / `encodingInfo` will load that JSON (schema: `{ video: CapabilityProfileEntry[]; audio: CapabilityProfileEntry[] }`) and match codec/profile/level against those entries for precise limits. Without the env var the library falls back to its built-in heuristics.
|
|
348
|
+
|
|
349
|
+
### Hardware Acceleration
|
|
350
|
+
|
|
351
|
+
Detect and use hardware encoding/decoding:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import {
|
|
355
|
+
detectHardwareAcceleration,
|
|
356
|
+
getHardwareAccelerationSummary,
|
|
357
|
+
getBestEncoder,
|
|
358
|
+
} from 'webcodecs-node';
|
|
359
|
+
|
|
360
|
+
// Get a summary of available hardware acceleration
|
|
361
|
+
const summary = await getHardwareAccelerationSummary();
|
|
362
|
+
console.log(summary);
|
|
363
|
+
|
|
364
|
+
// Detect capabilities
|
|
365
|
+
const capabilities = await detectHardwareAcceleration();
|
|
366
|
+
console.log('Available methods:', capabilities.methods);
|
|
367
|
+
console.log('Hardware encoders:', capabilities.encoders);
|
|
368
|
+
console.log('Hardware decoders:', capabilities.decoders);
|
|
369
|
+
|
|
370
|
+
// Get best encoder for a codec
|
|
371
|
+
const best = await getBestEncoder('h264', 'prefer-hardware');
|
|
372
|
+
console.log(`Using: ${best.encoder} (hardware: ${best.isHardware})`);
|
|
373
|
+
|
|
374
|
+
// Use in VideoEncoder config
|
|
375
|
+
await encoder.configure({
|
|
376
|
+
codec: 'avc1.42001E',
|
|
377
|
+
width: 1920,
|
|
378
|
+
height: 1080,
|
|
379
|
+
bitrate: 5_000_000,
|
|
380
|
+
hardwareAcceleration: 'prefer-hardware',
|
|
381
|
+
});
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Supported acceleration methods:**
|
|
385
|
+
- **VAAPI** - Intel/AMD on Linux
|
|
386
|
+
- **NVENC/NVDEC** - NVIDIA GPUs
|
|
387
|
+
- **QSV** - Intel Quick Sync Video
|
|
388
|
+
- **VideoToolbox** - macOS (planned)
|
|
389
|
+
|
|
390
|
+
### Streaming & Latency Modes
|
|
391
|
+
|
|
392
|
+
For real-time streaming applications, use `latencyMode: 'realtime'` to minimize encoding latency:
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
// Real-time streaming encoder
|
|
396
|
+
const encoder = new VideoEncoder({
|
|
397
|
+
output: (chunk) => {
|
|
398
|
+
// Send chunk immediately over network
|
|
399
|
+
streamToClient(chunk);
|
|
400
|
+
},
|
|
401
|
+
error: console.error,
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
await encoder.configure({
|
|
405
|
+
codec: 'avc1.42001E',
|
|
406
|
+
width: 1280,
|
|
407
|
+
height: 720,
|
|
408
|
+
bitrate: 2_000_000,
|
|
409
|
+
framerate: 30,
|
|
410
|
+
latencyMode: 'realtime', // Prioritize low latency
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// Process frames as they arrive
|
|
414
|
+
camera.on('frame', (frameData) => {
|
|
415
|
+
const frame = new VideoFrame(frameData, {
|
|
416
|
+
format: 'RGBA',
|
|
417
|
+
codedWidth: 1280,
|
|
418
|
+
codedHeight: 720,
|
|
419
|
+
timestamp: Date.now() * 1000,
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
encoder.encode(frame);
|
|
423
|
+
frame.close();
|
|
424
|
+
});
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
**Latency mode options:**
|
|
428
|
+
- `'quality'` (default) - Best compression, higher latency (uses B-frames, lookahead)
|
|
429
|
+
- `'realtime'` - Minimum latency for live streaming (no B-frames, zero-delay)
|
|
430
|
+
|
|
431
|
+
**Codec-specific optimizations in realtime mode:**
|
|
432
|
+
| Codec | Quality Mode | Realtime Mode |
|
|
433
|
+
|-------|-------------|---------------|
|
|
434
|
+
| H.264 | B-frames, rc-lookahead | zerolatency tune, no B-frames |
|
|
435
|
+
| H.265 | B-frames, lookahead | zerolatency tune, no B-frames |
|
|
436
|
+
| VP8 | Default settings | deadline=realtime, cpu-used=8 |
|
|
437
|
+
| VP9 | row-mt, tile-columns | deadline=realtime, cpu-used=8 |
|
|
438
|
+
| AV1 | Default settings | usage=realtime, cpu-used=8 |
|
|
439
|
+
|
|
440
|
+
### Bitrate Modes
|
|
441
|
+
|
|
442
|
+
Control how bitrate is managed during encoding:
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
await encoder.configure({
|
|
446
|
+
codec: 'avc1.42001E',
|
|
447
|
+
width: 1920,
|
|
448
|
+
height: 1080,
|
|
449
|
+
bitrate: 5_000_000,
|
|
450
|
+
bitrateMode: 'constant', // CBR for streaming
|
|
451
|
+
});
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
**Bitrate mode options:**
|
|
455
|
+
| Mode | Description | Use Case |
|
|
456
|
+
|------|-------------|----------|
|
|
457
|
+
| `'variable'` | VBR - varies bitrate for quality (default) | General purpose |
|
|
458
|
+
| `'constant'` | CBR - fixed bitrate throughout | Streaming, broadcast |
|
|
459
|
+
| `'quantizer'` | CRF/CQ - fixed quality level | Archival, quality-first |
|
|
460
|
+
|
|
461
|
+
### Alpha Channel (Transparency)
|
|
462
|
+
|
|
463
|
+
Preserve transparency when encoding with VP9 or AV1:
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
// Encode video with alpha channel
|
|
467
|
+
await encoder.configure({
|
|
468
|
+
codec: 'vp9',
|
|
469
|
+
width: 1920,
|
|
470
|
+
height: 1080,
|
|
471
|
+
alpha: 'keep', // Preserve transparency
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
// Create RGBA frame with transparency
|
|
475
|
+
const frame = new VideoFrame(rgbaWithAlpha, {
|
|
476
|
+
format: 'RGBA',
|
|
477
|
+
codedWidth: 1920,
|
|
478
|
+
codedHeight: 1080,
|
|
479
|
+
timestamp: 0,
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
encoder.encode(frame);
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
**Alpha options:**
|
|
486
|
+
- `'discard'` (default) - Strip alpha channel (works with all codecs)
|
|
487
|
+
- `'keep'` - Preserve transparency (VP9 and AV1 only)
|
|
488
|
+
|
|
489
|
+
## Mediabunny Integration
|
|
490
|
+
|
|
491
|
+
For file-to-file conversion, use with [Mediabunny](https://mediabunny.dev):
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
import { ReadableStream, WritableStream, TransformStream } from 'stream/web';
|
|
495
|
+
import { installWebCodecsPolyfill } from 'webcodecs-node';
|
|
496
|
+
|
|
497
|
+
// Polyfill Web Streams
|
|
498
|
+
if (typeof globalThis.WritableStream === 'undefined') {
|
|
499
|
+
globalThis.WritableStream = WritableStream;
|
|
500
|
+
}
|
|
501
|
+
if (typeof globalThis.ReadableStream === 'undefined') {
|
|
502
|
+
globalThis.ReadableStream = ReadableStream;
|
|
503
|
+
}
|
|
504
|
+
if (typeof globalThis.TransformStream === 'undefined') {
|
|
505
|
+
globalThis.TransformStream = TransformStream;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// Install WebCodecs
|
|
509
|
+
installWebCodecsPolyfill();
|
|
510
|
+
|
|
511
|
+
import {
|
|
512
|
+
Input,
|
|
513
|
+
Output,
|
|
514
|
+
Conversion,
|
|
515
|
+
FilePathSource,
|
|
516
|
+
FilePathTarget,
|
|
517
|
+
Mp4OutputFormat,
|
|
518
|
+
ALL_FORMATS,
|
|
519
|
+
registerEncoder,
|
|
520
|
+
registerDecoder,
|
|
521
|
+
} from 'mediabunny';
|
|
522
|
+
|
|
523
|
+
import { FFmpegVideoEncoder } from 'webcodecs-node/mediabunny/FFmpegVideoEncoder';
|
|
524
|
+
import { FFmpegVideoDecoder } from 'webcodecs-node/mediabunny/FFmpegVideoDecoder';
|
|
525
|
+
import { FFmpegAudioEncoder } from 'webcodecs-node/mediabunny/FFmpegAudioEncoder';
|
|
526
|
+
import { FFmpegAudioDecoder } from 'webcodecs-node/mediabunny/FFmpegAudioDecoder';
|
|
527
|
+
|
|
528
|
+
// Register FFmpeg-backed encoders/decoders
|
|
529
|
+
registerEncoder(FFmpegVideoEncoder);
|
|
530
|
+
registerEncoder(FFmpegAudioEncoder);
|
|
531
|
+
registerDecoder(FFmpegVideoDecoder);
|
|
532
|
+
registerDecoder(FFmpegAudioDecoder);
|
|
533
|
+
|
|
534
|
+
// Convert video
|
|
535
|
+
const input = new Input({
|
|
536
|
+
formats: ALL_FORMATS,
|
|
537
|
+
source: new FilePathSource('input.mkv'),
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
const output = new Output({
|
|
541
|
+
format: new Mp4OutputFormat(),
|
|
542
|
+
target: new FilePathTarget('output.mp4'),
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
const conversion = await Conversion.init({ input, output });
|
|
546
|
+
await conversion.execute();
|
|
547
|
+
|
|
548
|
+
console.log('Conversion complete!');
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
## Demos
|
|
552
|
+
|
|
553
|
+
Run the included demos to test functionality:
|
|
554
|
+
|
|
555
|
+
```bash
|
|
556
|
+
npm run build
|
|
557
|
+
|
|
558
|
+
# Basic WebCodecs demo
|
|
559
|
+
npm run demo:webcodecs
|
|
560
|
+
|
|
561
|
+
# Image decoding demo (animated GIF/PNG/WebP with frame timing)
|
|
562
|
+
npm run demo:image
|
|
563
|
+
|
|
564
|
+
# Streaming demo (real-time encoding with latency comparison)
|
|
565
|
+
npm run demo:streaming
|
|
566
|
+
|
|
567
|
+
# File conversion with Mediabunny
|
|
568
|
+
npm run demo:conversion
|
|
569
|
+
|
|
570
|
+
# Hardware acceleration detection
|
|
571
|
+
npm run demo:hwaccel
|
|
572
|
+
|
|
573
|
+
# Hardware vs software encoding comparison
|
|
574
|
+
npm run demo:hwaccel-conversion
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
## API Compatibility
|
|
578
|
+
|
|
579
|
+
This implementation follows the [WebCodecs specification](https://www.w3.org/TR/webcodecs/) with some Node.js-specific adaptations:
|
|
580
|
+
|
|
581
|
+
| Feature | Browser | webcodecs-node |
|
|
582
|
+
|---------|---------|----------------|
|
|
583
|
+
| VideoEncoder | ✓ | ✓ |
|
|
584
|
+
| VideoDecoder | ✓ | ✓ |
|
|
585
|
+
| AudioEncoder | ✓ | ✓ |
|
|
586
|
+
| AudioDecoder | ✓ | ✓ |
|
|
587
|
+
| ImageDecoder | ✓ | ✓ |
|
|
588
|
+
| VideoFrame | ✓ | ✓ |
|
|
589
|
+
| AudioData | ✓ | ✓ |
|
|
590
|
+
| EncodedVideoChunk | ✓ | ✓ |
|
|
591
|
+
| EncodedAudioChunk | ✓ | ✓ |
|
|
592
|
+
| ImageTrack/ImageTrackList | ✓ | ✓ |
|
|
593
|
+
| MediaCapabilities | ✓ | ✓ |
|
|
594
|
+
| Hardware Acceleration | Auto | Opt-in |
|
|
595
|
+
| latencyMode | ✓ | ✓ |
|
|
596
|
+
| bitrateMode | ✓ | ✓ |
|
|
597
|
+
| alpha (transparency) | ✓ | ✓ (VP9, AV1) |
|
|
598
|
+
| isConfigSupported() | ✓ | ✓ |
|
|
599
|
+
| isTypeSupported() | ✓ | ✓ |
|
|
600
|
+
|
|
601
|
+
**Notes:**
|
|
602
|
+
- Hardware acceleration defaults to software encoding for reliability. Use `hardwareAcceleration: 'prefer-hardware'` to enable GPU acceleration.
|
|
603
|
+
- ImageDecoder supports animated image frame timing (duration, timestamp) and loop count (repetitionCount).
|
|
604
|
+
|
|
605
|
+
## License
|
|
606
|
+
|
|
607
|
+
webcodecs-node is distributed under the GNU Affero General Public License v3.0. Files located under `src/mediabunny/` remain available under the MIT License to preserve compatibility with Mediabunny integrations. See `LICENSE` for full terms.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioData.d.ts","sourceRoot":"","sources":["../src/AudioData.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioData.js","sourceRoot":"","sources":["../src/AudioData.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioDecoder.d.ts","sourceRoot":"","sources":["../src/AudioDecoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioDecoder.js","sourceRoot":"","sources":["../src/AudioDecoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioEncoder.d.ts","sourceRoot":"","sources":["../src/AudioEncoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioEncoder.js","sourceRoot":"","sources":["../src/AudioEncoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncodedAudioChunk.d.ts","sourceRoot":"","sources":["../src/EncodedAudioChunk.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,6BAA6B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncodedAudioChunk.js","sourceRoot":"","sources":["../src/EncodedAudioChunk.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,6BAA6B,CAAC"}
|