{"id":13907342,"url":"https://github.com/ennuicastr/libavjs-webcodecs-polyfill","last_synced_at":"2025-05-16T14:04:50.741Z","repository":{"id":44615344,"uuid":"428832474","full_name":"ennuicastr/libavjs-webcodecs-polyfill","owner":"ennuicastr","description":"A polyfill for the WebCodecs API. No, really.","archived":false,"fork":false,"pushed_at":"2025-03-20T21:03:12.000Z","size":1708,"stargazers_count":96,"open_issues_count":0,"forks_count":15,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-12T15:57:52.163Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ennuicastr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-11-16T22:24:52.000Z","updated_at":"2025-04-18T01:12:53.000Z","dependencies_parsed_at":"2023-12-14T18:50:14.115Z","dependency_job_id":"6354a3cb-c43b-4cb4-a212-74844bfd1b74","html_url":"https://github.com/ennuicastr/libavjs-webcodecs-polyfill","commit_stats":{"total_commits":162,"total_committers":8,"mean_commits":20.25,"dds":"0.12962962962962965","last_synced_commit":"82b40bd2f18129efe16aed0602561e3975d5bbfe"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennuicastr%2Flibavjs-webcodecs-polyfill","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennuicastr%2Flibavjs-webcodecs-polyfill/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennuicastr%2Flibavjs-webcodecs-polyfill/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennuicastr%2Flibavjs-webcodecs-polyfill/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ennuicastr","download_url":"https://codeload.github.com/ennuicastr/libavjs-webcodecs-polyfill/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254544146,"owners_count":22088807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-06T23:01:53.835Z","updated_at":"2025-05-16T14:04:50.723Z","avatar_url":"https://github.com/ennuicastr.png","language":"TypeScript","funding_links":[],"categories":["HarmonyOS"],"sub_categories":["Windows Manager"],"readme":"# LibAVJS-WebCodecs-Polyfill\n\nThis is a polyfill for the [WebCodecs API](https://w3c.github.io/webcodecs/).\n\nNo, really.\n\nIt supports the `VideoEncoder`, `AudioEncoder`, `VideoDecoder`, and\n`AudioDecoder` classes, `VideoFrame`-specific versions of\n`CanvasRenderingContext2D.drawImage` and `createImageBitmap`, and all the\nclasses and interfaces required by these. There are no plans to implement image\nformats, only video and audio.\n\nIt implements WebCodecs through\n[libav.js](https://github.com/Yahweasel/libav.js/), which is a port of\n[FFmpeg](https://ffmpeg.org/)'s library interface to WebAssembly and asm.js.\n\nTo use it, simply include libav.js then this library, and then call and `await\nLibAVWebCodecs.load()`. `load` takes an optional `options` parameter, which is\nan object:\n\n```\noptions: {\n    /* Polyfill: If the WebCodecs API is not provided by the browser in the\n     * global object, link it to this library */\n    polyfill?: boolean,\n\n    /* Options to pass to LibAV.LibAV while constructing a LibAV instance */\n    libavOptions?: any\n}\n```\n\nUse it either by the WebCodecs API specification (if you used `polyfill`), or\nas a [ponyfill](https://ponyfill.com), with the API under the global\n`LibAVWebCodecs` object.\n\nIf you don't bring your own libav.js, LibAVJS-WebCodecs-Polyfill will load its\nown. If you load LibAVJS-WebCodecs-Polyfill in the browser context (and not a\nworker thread), it is highly recommended that you do *not* use this option,\nbecause libav.js is designed to use Web Workers, and Web Workers cannot be\nloaded from a different origin. This will hurt both performance and\nresponsiveness. That is, it is recommended that *either* you load libav.js\nyourself, *or* you use LibAVJS-WebCodecs-Polyfill in a Worker thread (or both!).\n\nFor rendering, it is highly recommended that you use\n`LibAVWebCodecs.createImageBitmap` and draw the result on a canvas, rather than\n`LibAVWebCodecs.canvasDrawImage`, which is synchronous.\n`LibAVWebCodecs.createImageBitmap` only accepts the `resizeWidth` and\n`resizeHeight` options, so only the overload\n`LibAVWebCodecs.createImageBitmap(frame, options)` is supported, with `options`\noptional.\n\nIf you need the synchronous API, use `LibAVWebCodecs.canvasDrawImage(ctx,\n...)`. The first argument is the context, and the remaining arguments are as in\n`CanvasRenderingContext2D.drawImage`. It is safe to use `canvasDrawImage` with\nany image type, not just a `VideoFrame`; it will fall through to the original\n`drawImage` as needed. If you used the `polyfill` option while loading\nLibAVJS-WebCodecs-Polyfill, then `drawImage` itself will also support\n`VideoFrame`s.\n\n\n## Interaction with Browser WebCodecs\n\nYou can use LibAVJS-WebCodecs-Polyfill along with a browser implementation of\nWebCodecs, but you cannot mix and match raw data objects from each (e.g.,\n`VideoFrame`s from a browser implementation of WebCodecs cannot be used in\nLibAV-WebCodecs-Polyfill and vice-versa).\n\nTo make this practical, `LibAVWebCodecs.getXY(config)` (where `X` = `Video` or\n`Audio` and `Y` = `Encoder` or `Decoder`) are implemented, and will return a\npromise for an object with, e.g.  `VideoEncoder`, `EncodedVideoChunk`, and\n`VideoFrame` set to either WebCodecs' or LibAVJS-WebCodecs-Polyfill's version.\nThe promise is rejected if the configuration is unsupported.\n\nIn addition, you can convert between the two using functions provided by the\npolyfill. If you have a polyfill AudioData `ad`, you can use `ad.toNative()` to\nconvert it to a browser WebCodecs AudioData, and if you have a browser WebCodecs\nAudioData `ad`, you can use `LibAVWebCodecs.AudioData.fromNative(ad)`.\nSimilarly, you can convert VideoFrames with `vf.toNative()` or\n`LibAVWebCodecs.VideoFrame.fromNative(vf)`.\n\nConverting involves extra copying, so is best avoided when possible. But,\nsometimes it's not possible.\n\n\n## Compatibility\n\nLibAVJS-WebCodecs-Polyfill should be up to date with the 2024-02-29 working\ndraft of the WebCodecs specification:\nhttps://www.w3.org/TR/2024/WD-webcodecs-20240229/\n\nVideo support in LibAVJS-WebCodecs-Polyfill requires libav.js 5.1.6 or later.\nAudio support should work with libav.js 4.8.6 or later, but is of course usually\ntested only with the latest version.\n\nDepending on the libav.js variant used, LibAVJS-WebCodecs-Polyfill supports the\naudio codecs FLAC (`\"flac\"`), Opus (`\"opus\"`), and Vorbis (`\"vorbis\"`), and the\nvideo codecs AV1 (`\"av01\"`), VP9 (`\"vp09\"`), and VP8 (`\"vp8\"`). The\n`webm-vp9` variant, which LibAVJS-WebCodecs-Polyfill uses if no libav.js is\nloaded, supports FLAC, Opus, VP8, and VP9.\n\nFFmpeg supports many codecs, and it's generally easy to add new codecs to\nlibav.js and LibAVJS-WebCodecs-Polyfill. However, there are no plans to add any\ncodecs by the Misanthropic Patent Extortion Gang (MPEG), so all useful codecs\nin the WebCodecs codec registry are supported.\n\nLibAVJS-WebCodecs-Polyfill also supports bypassing the codec registry entirely\nand using any codec FFmpeg is capable of, by using the `LibAVJSCodec` interface\n(see `src/libav.ts`) instead of a string for the codec. For instance,\n`VideoEncoder` can be configured to use H.263+ like so:\n\n```\nconst enc = new LibAVJS.VideoEncoder(...);\nenc.configure({\n    codec: {libavjs: {\n        codec: \"h263p\",\n        ctx: {\n            pix_fmt: 0,\n            width: settings.width,\n            height: settings.height,\n            framerate_num: settings.frameRate,\n            framerate_den: 1\n        }\n    }},\n    ...\n});\n```\n\nThis is useful because VP8, even in realtime mode, is really too slow to\nencode/decode in software in WebAssembly on many modern systems, but a simpler\ncodec like H.263+ works in software nearly anywhere.\n\n\n## Limitations\n\nThe `createImageBitmap` polyfill is quite limited in the arguments it accepts.\n\nlibav.js is surprisingly fast for what it is, but it ain't fast. All audio\ncodecs work fine, but video struggles. This is why support for codecs outside\nthe codec registry was added.\n\n`VideoFrame` is fairly incomplete. In particular, nothing to do with color\nspaces is actually implemented, and nor is cropping. The initialization of\nframes from canvas sources has many caveats in the spec, and none in\nLibAVJS-WebCodecs-Polyfill, and as a consequence, `timestamp` is always a\nmandatory field of `VideoFrameInit`.\n\n`VideoEncoder` assumes that `VideoFrame`s passed to it are fairly sane (i.e.,\nthe planes are lain out in the obvious way).\n\nCertain events are supposed to eagerly halt the event queue, but\nLibAVJS-WebCodecs-Polyfill always lets the event queue finish.\n\nThe framerate reported to video codecs is the nearest whole number to the input\nframerate. This should usually only affect bitrate and latency calculations, as\neach frame is individually timestamped.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fennuicastr%2Flibavjs-webcodecs-polyfill","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fennuicastr%2Flibavjs-webcodecs-polyfill","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fennuicastr%2Flibavjs-webcodecs-polyfill/lists"}