{"id":22559702,"url":"https://github.com/schahriar/mfx","last_synced_at":"2025-04-10T09:27:20.706Z","repository":{"id":247881022,"uuid":"803046357","full_name":"schahriar/mfx","owner":"schahriar","description":"In-browser video editing toolkit","archived":false,"fork":false,"pushed_at":"2024-10-24T04:09:34.000Z","size":27008,"stargazers_count":12,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-24T21:35:57.019Z","etag":null,"topics":["glsl","video","webcodecs","webgl"],"latest_commit_sha":null,"homepage":"https://mfxlib.com/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/schahriar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2024-05-20T00:29:05.000Z","updated_at":"2024-10-24T04:09:39.000Z","dependencies_parsed_at":"2024-07-11T04:44:43.104Z","dependency_job_id":"60dd63d3-3ec4-4016-bae5-bc942a97857c","html_url":"https://github.com/schahriar/mfx","commit_stats":null,"previous_names":["schahriar/mfx"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schahriar%2Fmfx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schahriar%2Fmfx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schahriar%2Fmfx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schahriar%2Fmfx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schahriar","download_url":"https://codeload.github.com/schahriar/mfx/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248190956,"owners_count":21062385,"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":["glsl","video","webcodecs","webgl"],"created_at":"2024-12-07T21:08:01.171Z","updated_at":"2025-04-10T09:27:20.694Z","avatar_url":"https://github.com/schahriar.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"./Logo.png\" width=\"100\"\u003e\n\n## MFX\nIn-browser video editing using WebCodecs, WebStreams, and WebGL\n→ [mfxlib.com](https://mfxlib.com)\n\n----\n\n## Usage\nDecode MP4 Video -\u003e zoom out -\u003e encode to WebM keeping original Audio (vp8):\n```javascript\nimport {\n  decode,\n  encode,\n  effect,\n  visual,\n  writeToFile,\n} from \"mfx\";\n\n// Files can be fetched locally\nconst file = await fetch(\"https://example.com/myvideo.mp4\");\n\n// Decode video container, returns each track as a WebStream\nconst { video, audio } = await decode(file, \"video/mp4\", {\n  // Addresses Chromium WebCodecs bug, Set to true for HEVC or if \"Can't readback frame textures\" is thrown. Has ~10% performance impact.\n  forceDecodeToSoftware: false,\n});\n\n// Hardware accelerated (WebGL2) effect pipeline\nconst videoOutput = effect(video, [\n  // Apply zoom out effect\n  visual.zoom({ factor: 0.5, x: 0.5, y: 0.25 })\n]);\n\n// Readable WebStream\nconst outputStream = encode({\n  mimeType: `video/webm; codecs=\"vp8,opus\"`, // Transcode to WebM VP8 (video) and Opus (audio)\n  video: {\n    ...video.track.config, // Inherit configuration from input video\n    stream: videoOutput,\n    width: 640,\n    height: 360,\n    bitrate: 1e6,\n    framerate: 30,\n  },\n  audio: {\n    ...audio.track.config, // Inherit configuration from input audio\n    stream: audio\n  }\n});\n\n// Opens a save dialog in the browser\nawait writeToFile(outputStream, \"output.webm\");\n\n// Alternatively you can pipeTo a fetch POST request\nawait fetch(\"example.com/save\", {\n  method: \"POST\",\n  body: outputStream\n});\n```\n\n## Support Table\nWhile `codec` support heavily depends on the browser, `mfx` aims to provide support for the following container / codec pairs:\n\n| Container | Codec       | Encode / Decode |\n| --------  | ---------   | --------------- \n| MP4       | H.264/AVC   | Both            |\n| MP4       | H.265/HEVC  | Decode          |\n| MP4       | VP8         | Both            |\n| MP4       | VP9         | Both            |\n| WebM      | VP8         | Both            |\n| WebM      | VP9         | Both            |\n| GIF       | LZW         | Encode          |\n| \u003chr\u003e | **`Audio`** | \u003chr\u003e\n| MP4       | Opus        | Both            |\n| MP4       | AAC         | Both            |\n| WebM      | Opus        | Both            |\n| WebM      | Vorbis      | Both            |\n\n## Roadmap\n\n### Soon\n- Fix Audio trimming to include subframes\n- Regional effects\n- GIF decoder\n  - decode: https://github.com/mattdesl/gifenc (or ImageDecoder)\n- Optimization Pipeline\n  - Frame delta GPU pipeline\n    - To remove duplicated or near-identical frames based on controllable parameters\n    - Auto-quantization based on frame hints\n  - RGB -\u003e YUV conversion for better compatibility and output size\n  - Multi-pass adaptive bitrate\n  - Frame rate pinning to auto-adjust timestamps\n    - Optionally disable VFR\n  - Temporal Noise Reduction\n- API Documentation\n  - Add note on VP9 probe\n- Testing: Source videos with frame duration \u003e fps to showcase frameRate\n- Run tests on Github actions\n- Contribution Guide\n\n### Later\n- Decode WebM via Matroska decoder to resolve issues of jswebm dependency (https://www.npmjs.com/package/ebml-stream), alternatively build libwebm for WebAssembly https://github.com/webmproject/libwebm/tree/main/webm_parser (e.g. https://github.com/ForeverSc/web-demuxer/blob/main/lib/web-demuxer/web_demuxer.cpp)\n  - https://github.com/GoogleChromeLabs/webm-wasm/tree/master\n- Utilize (https://github.com/dmnsgn/media-codecs?tab=readme-ov-file) for codec string generation\n- Canvas frame generator\n  - Add threejs demo\n- SVG → Image → Frame animated pipeline\n- Audio effect support\n  - Audio waveform\n- Color Grading\n  - HSV support\n  - Palette detection / Adjustment\n  - Mask: Alpha/Green-screen\n- Audio Containers (mp3, flac, wav, opus)\n- Improve encoding performance by reverting fill behavior for nearly identical frames (high effort)\n- Seek\n  - Clips view (similar to QuickTime)\n- Per frame quantizer\n- Log WebCodec bug (https://chromium.googlesource.com/chromium/src/+/7786d34a4e7771725b85f354247ad1bb1902c556/third_party/blink/renderer/modules/webcodecs/video_encoder.cc#939)\n- Reduce CPU → GPU → CPU copy times using texture atlas\n- Benchmarks (during test) against ffmpeg (AVC https://trac.ffmpeg.org/wiki/Encode/H.264#FAQ and possibly WebM)\n- Integrate GLSL debugger using [Spector](https://github.com/BabylonJS/Spector.js?tab=readme-ov-file#use-as-a-script-reference)\n\n----\n\n## Contributing\nInstall git-lfs to pull sample files:\n```\nbrew install git-lfs\n```\n\n```\nnpm install\nnpm start\n```\n----\n\n### License\nMIT [License](LICENSE)\n\n##### Disclaimer on Sample Videos\nSome test videos are sourced from `coverr.co` yet they are only used for testing and will not be built into the `MFX` package.\nThese videos are under a permissive license (https://coverr.co/license).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschahriar%2Fmfx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschahriar%2Fmfx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschahriar%2Fmfx/lists"}