# go-ffmpreg

empregge- sorry, uh... embedded [ffmpeg](https://github.com/ffmpeg/ffmpeg) WASM binary with a small Go library wrapper, using [wazero](https://github.com/tetratelabs/wazero) WebAssembly runtime

this provides a singular binary capable of calling into `ffmpeg` or `ffprobe` (switches on argv0, like busybox)

ffmpeg version: `n5.1.6` (the latest version not reliant on pthreads)

yes, you will have to publicly acknowledge the fact you used `ffmpreg` as this is GPL

ffmpeg is built with GPLv3 code enabled and with the following external libraries:
- [libx264](https://code.videolan.org/videolan/x264) (for H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 encoding)
- [libwebp](https://chromium.googlesource.com/webm/libwebp) (for WebP encoding)
- [libmp3l*me](https://sourceforge.net/projects/lame) (for MP3 encoding)
- [libopus](https://github.com/xiph/opus) (for Opus encoding)
- [libvpx](https://chromium.googlesource.com/webm/libvpx) (for VP8 / VP9 encoding)
- [zlib](https://github.com/madler/zlib)

for a list of what ffmpeg supports (and what it requires external libaries for) see: https://www.ffmpeg.org/general.html#External-libraries

the resulting binary is passed through many `wasm-opt` optimization passes focusing on a balance of speed and size, such that the embedded binary is ~24MB (uncompressed, before in this is gzip compressed to ~8MB)

## usage

see `cmd/{ffmpeg,ffprobe,ffmpreg}` for examples

ffmpeg may need access to `/dev/` and `/tmp/` depending on what you are doing, please factor this in when setting up directory mounts

note since wazero runtime is not aware of a "working directory", all paths passed must be absolute relative to filesystem mount

## build

run `./build.sh` to rebuild ffmpreg binary (note this may take a *long* time), this will write the resulting binary to `./embed/ffmpreg.wasm.gz`

## hacking

the WebAssembly binary (once uncompressed) under `embed/` should be useable under any WebAssembly runtime that supports the following: `simd, bulk-memory, nontrapping-float-to-int, mutable-globals, sign-ext, reference-types`

on top of the above runtime features, this binary expects exported host functions as defined in the wasi snapshot preview 1, and additionally, `setjmp, longjmp`

## future

- more tests (in particular: ffprobe, 3rd-party libs)

- update ffmpeg to `n7.x.x` (requires wazero to fully support wasm threads proposal)

- tidy up the ffmpeg patch, in particular add code comments

- build-tagged output with differing 3rd-party library options?

- build with libjxl for JPEG XL, *may* rely on threads

- build with libx265 for HEVC, *may* rely on threads

- some form of AV1 encode / decode

## further thanks

`viviridian` for showing me how to modify the ffmpeg build-system to support a new binary!
