Giter Site home page Giter Site logo

foreversc / web-demuxer Goto Github PK

View Code? Open in Web Editor NEW
12.0 2.0 0.0 143 KB

Demux media files in the browser using WebAssembly, designed for WebCodecs 在浏览器中实现媒体文件的解封装,专为WebCodecs设计

Home Page: https://foreversc.github.io/web-demuxer/

License: MIT License

Makefile 1.83% HTML 12.02% C 47.87% JavaScript 15.02% TypeScript 23.27%
audio media typescript video webassembly webcodecs demux demuxer

web-demuxer's Introduction

English | 简体中文

Web-Demuxer

Demux media files in the browser using WebAssembly, designed for WebCodecs.

Purpose

WebCodecs only provide the ability to decode, but not to demux. mp4box.js is cool, but it only supports mp4 demux. Web-Demuxer aims to support as many multimedia formats as possible at once.

Features

  • 🪄 Specifically designed for WebCodecs, the API is very friendly for WebCodecs development, you can easily realize the media file demux.
  • 📦 One-time support for a variety of media formats, such as mov/mp4/mkv/webm/flv/m4v/wmv/avi, etc.
  • 🧩 Support for customized packaging, you can adjust the configuration, packaged in a specified format demuxer

Install

NPM

npm install web-demuxer

CDN

<script type="module">
  import { WebDemuxer } from 'https://cdn.jsdelivr.net/npm/web-demuxer@latest/dist/web-demuxer.min.js';
</script>

Usage

import { WebDemuxer } from "web-demuxer"

const demuxer = new WebDemuxer({
  // ⚠️ you need to put the dist/wasm-files file in the npm package into a static directory like public
  // making sure that the js and wasm in wasm-files are in the same directory
  wasmLoaderPath: "https://cdn.jsdelivr.net/npm/web-demuxer@latest/dist/wasm-files/ffmpeg.min.js",
})

// Take the example of seeking a video frame at a specified point in time
async function seek(file, time) {
  // 1. load video file
  await demuxer.load(file);

  // 2. demux video file and generate WebCodecs needed VideoDecoderConfig and EncodedVideoChunk
  const videoDecoderConfig = await demuxer.getVideoDecoderConfig();
  const videoChunk = await demuxer.seekEncodedVideoChunk(time);

  // 3. use WebCodecs to decode frame
  const decoder = new VideoDecoder({
    output: (frame) => {
      // draw frame...
      frame.close();
    },
    error: (e) => {
      console.error('video decoder error:', e);
    }
  });

  decoder.configure(videoDecoderConfig);
  decoder.decode(videoChunk);
  decoder.flush();
}

Examples

Here is the translation of the provided TypeScript API documentation into English:

API

new WebDemuxer(options: WebDemuxerOptions)

Creates a new instance of WebDemuxer.

Parameters:

  • options: Required, configuration options.
    • wasmLoaderPath: Required, the path to the corresponding JavaScript loader file for wasm (corresponding to the ffmpeg.js or ffmpeg-mini.js in the dist/wasm-files directory of the npm package).

    ⚠️ You must ensure that the wasm and JavaScript loader files are placed in the same accessible directory, the JavaScript loader will default to requesting the wasm file in the same directory.

load(file: File): Promise<boolean>

Loads a file and waits for the wasm worker to finish loading. The subsequent methods can only be called after the load method has been successfully executed.

Parameters:

  • file: Required, the File object to be processed.
getVideoDecoderConfig(): Promise<VideoDecoderConfig>

Parses the video stream to obtain the VideoDecoderConfig of the file, and the return value can be directly used as an argument for the configure method of VideoDecoder.

getAudioDecoderConfig(): Promise<AudioDecoderConfig>

Parses the audio stream to obtain the AudioDecoderConfig of the file, and the return value can be directly used as an argument for the configure method of AudioDecoder.

seekEncodedVideoChunk(time: number): Promise<EncodedVideoChunk>

Retrieves the video data at the specified time point (default keyframe), and the return value can be directly used as an argument for the decode method of VideoDecoder.

Parameters:

  • time: Required, in seconds.
seekEncodedAudioChunk(time: number): Promise<EncodedAudioChunk>

Retrieves the audio data at the specified time point, and the return value can be directly used as an argument for the decode method of AudioDecoder.

Parameters:

  • time: Required, in seconds.
readAVPacket(start?: number, end?: number, streamType?: AVMediaType, streamIndex?: number): ReadableStream<WebAVPacket>

Returns a ReadableStream for streaming packet data.

Parameters:

  • start: The start time for reading, in seconds, defaults to 0, reading packets from the beginning.
  • end: The end time for reading, in seconds, defaults to 0, reading until the end of the file.
  • streamType: The type of media stream, defaults to 0, which is the video stream. 1 is audio stream. See AVMediaType for more details.
  • streamIndex: The index of the media stream, defaults to -1, which is to automatically select.
getAVStream(streamType?: AVMediaType, streamIndex?: number): Promise<WebAVStream>

Gets information about a specified stream in the media file.

Parameters:

  • streamType: The type of media stream, defaults to 0, which is the video stream. 1 is audio stream. See AVMediaType for more details.
  • streamIndex: The index of the media stream, defaults to -1, which is to automatically select.

Simplified methods based on the semantics of getAVStream:

  • getVideoStream(streamIndex?: number): Promise<WebAVStream>
  • getAudioStream(streamIndex?: number): Promise<WebAVStream>
getAVStreams(): Promise<WebAVStream[]>

Get all streams in the media file.

getAVPacket(time: number, streamType?: AVMediaType, streamIndex?: number): Promise<WebAVPacket>

Gets the data at a specified time point in the media file.

Parameters:

  • time: Required, in seconds.
  • streamType: The type of media stream, defaults to 0, which is the video stream. 1 is audio stream. See AVMediaType for more details.
  • streamIndex: The index of the media stream, defaults to -1, which is to automatically select.

Simplified methods based on the semantics of getAVPacket:

  • seekVideoPacket(time: number): Promise<WebAVPacket>
  • seekAudioPacket(time: number): Promise<WebAVPacket>
  • readVideoPacket(start?: number, end?: number): ReadableStream<WebAVPacket>
  • readAudioPacket(start?: number, end?: number): ReadableStream<WebAVPacket>
getAVPackets(time: number): Promise<WebAVPacket[]>

Simultaneously retrieves packet data on all streams at a certain time point and returns in the order of the stream array.

Parameters:

  • time: Required, in seconds.
destroy(): void

Destroys the instance and releases the worker.

Custom Demuxer

Currently, two versions of the demuxer are provided by default to support different formats:

  • dist/wasm-files/ffmpeg.js: Full version (gzip: 941 kB), larger in size, supports mov, mp4, m4a, 3gp, 3g2, mj2, avi, flv, matroska, webm, m4v, mpeg, asf
  • dist/wasm-files/ffmpeg-mini.js: Minimalist version (gzip: 115 kB), smaller in size, only supports mov, mp4, m4a, 3gp, 3g2, matroska, webm, m4v

You can also implement a demuxer for specific formats through custom configuration:

First, modify the enable-demuxer configuration in the Makefile

DEMUX_ARGS = \
    --enable-demuxer=mov,mp4,m4a,3gp,3g2,mj2,avi,flv,matroska,webm,m4v,mpeg,asf

Then execute npm run dev:docker:arm64 (if on Windows, please execute npm run dev:docker:x86_64) to start the Docker environment.

Finally, execute npm run build:wasm to build the demuxer for the specified formats.

License

MIT

web-demuxer's People

Contributors

foreversc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

web-demuxer's Issues

readAVPacket question

im trying to get correct chunk of frames out of my video using readAVPacket, the video im using is 5 second long, 30 FPS, so it has 150 frames, im trying to get frames between 2-3 second of the video like this:

webdemuxer.readAVPacket(2, 3).getReader()

but even though im trying to get here 1 second chunk which should be 30 frames, im getting about 70 frames and those frames are not starting from the 2 second of the video like stated in readAVPacket, not sure how to go about this ?

npm run build:wasm

我尝试运行 build:wasm 遇到错误:

> [email protected] make:ffmpeg-lib
> docker exec -it web-demuxer make ffmpeg-lib

cd lib/FFmpeg && \
emconfigure ./configure --target-os=none --arch=x86_32 --cc=emcc --ranlib=emranlib --disable-all --disable-asm --enable-avcodec --enable-avformat --enable-protocol=file --enable-decoder=h264,hevc,vp9,vp8 --enable-demuxer=mov,mp4,m4a,3gp,3g2,mj2,avi,flv,matroska,webm,m4v,mpegi,asf && \
emmake make
configure: ./configure --target-os=none --arch=x86_32 --cc=emcc --ranlib=emranlib --disable-all --disable-asm --enable-avcodec --enable-avformat --enable-protocol=file --enable-decoder=h264,hevc,vp9,vp8 --enable-demuxer=mov,mp4,m4a,3gp,3g2,mj2,avi,flv,matroska,webm,m4v,mpegi,asf
emconfigure: error: './configure --target-os=none --arch=x86_32 --cc=emcc --ranlib=emranlib --disable-all --disable-asm --enable-avcodec --enable-avformat --enable-protocol=file --enable-decoder=h264,hevc,vp9,vp8 --enable-demuxer=mov,mp4,m4a,3gp,3g2,mj2,avi,flv,matroska,webm,m4v,mpegi,asf' failed: [Errno 2] No such file or directory: './configure'
make: *** [Makefile:47: ffmpeg-lib] Error 1

【1】执行:docker exec -it web-demuxer make ffmpeg-lib

docker exec -it web-demuxer make ffmpeg-lib
cd lib/FFmpeg && \
emconfigure ./configure --target-os=none --arch=x86_32 --cc=emcc --ranlib=emranlib --disable-all --disable-asm --enable-avcodec --enable-avformat --enable-protocol=file --enable-decoder=h264,hevc,vp9,vp8 --enable-demuxer=mov,mp4,m4a,3gp,3g2,mj2,avi,flv,matroska,webm,m4v,mpegi,asf && \
emmake make
configure: ./configure --target-os=none --arch=x86_32 --cc=emcc --ranlib=emranlib --disable-all --disable-asm --enable-avcodec --enable-avformat --enable-protocol=file --enable-decoder=h264,hevc,vp9,vp8 --enable-demuxer=mov,mp4,m4a,3gp,3g2,mj2,avi,flv,matroska,webm,m4v,mpegi,asf
emconfigure: error: './configure --target-os=none --arch=x86_32 --cc=emcc --ranlib=emranlib --disable-all --disable-asm --enable-avcodec --enable-avformat --enable-protocol=file --enable-decoder=h264,hevc,vp9,vp8 --enable-demuxer=mov,mp4,m4a,3gp,3g2,mj2,avi,flv,matroska,webm,m4v,mpegi,asf' failed: [Errno 2] No such file or directory: './configure'
make: *** [Makefile:47: ffmpeg-lib] Error 1

【2】执行:docker exec -it web-demuxer make web-demuxer

./lib/FFmpeg/libavutil/macros.h:28:10: fatal error: 'libavutil/avconfig.h' file not found
   28 | #include "libavutil/avconfig.h"

是缺失了什么步骤吗?lib\FFmpeg 已经拉了代码,请指点,谢谢

convenience api for demuxing all frames in one go

could there be convenience api for demuxing all frames in one go ?
i see there is api for getting all packets (getAVPackets, if im correct), would be cool if there was method exposed to get all encoded frames and push them to decoder queue as they are demuxed (ideally both in their workers, if its possible to have demuxer in web worker?), not a big deal though, i havent tested your library yet, i will check it in my project soon (omniclip) and replace mp4boxjs, thanks for working on the library 👍

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.