Yahweasel / libav.js

This is a compilation of the libraries associated with handling audio and video in ffmpeg—libavformat, libavcodec, libavfilter, libavutil, libswresample, and libswscale—for emscripten, and thus the web.
288 stars 18 forks source link

Encoding h264 using VideoEncoder: VideoEncoder codec not supported #51

Closed Angramme closed 3 months ago

Angramme commented 3 months ago

I have read through the issues and it seems that video encoding for h264 should be supported, however it seems to me that it isn't. I have tried building my own config with the following array parameters:

["parser-h264","bsf-h264_metadata","format-mp4","format-aac","format-webm","parser-aac","codec-aac","parser-h264","decoder-h264","codec-libopenh264","encoder-h264","codec-h264"]

(I included every possible option related to h264 and aac encoding I could think of) When building I get the following warning:

WARNING: Option --enable-encoder=h264 did not match anything
WARNING: Option --enable-encoder=h264 did not match anything
WARNING: unknown architecture emscripten

(here I also attach the full build log build-log.txt)

When running the code in the following manner:

<script src="/libav-5.1.6.1.1-custom.js"/>
<script src="/libavjs-webcodecs-polyfill.min.js"/>
(all the generated files in dist have been moved to the public folder)

<script>
        (...inside some async function)
        await LibAVWebCodecs.load();
        this.videoEncoder = new LibAVWebCodecs.VideoEncoder({
            output: (chunk, meta) => this.muxer!.addVideoChunk(chunk, meta),
            error: params.onError,
        });
        const config = {
            codec: 'avc1.4d002a', // variant 1
            // codec: 'avc1.42001f', // variant 2
            // codec: {libavjs: { .. variant 3
            //     codec: "h264",
            // }},
            width: this.canvas.width,
            height: this.canvas.height,
            bitrate: 20e6, // Mbps
            framerate: params.fps,
        };
        this.videoEncoder.configure(config);
</script>

I have tried variant 1 through 3 and all of them give me "DOMException: Unsupported codec" errors. Please note that on the native implementation in chrome both variant 1 and 2 work properly without errors and export readable video.

TLDR; It seems that the codec for h264 is not getting included in the build files despite the explicit flags. Either that or I'm configuring something wrong.

btw I wasn't sure if I should put this issue here or in the polyfill repo, but I thought it is more closely related to libav build.

Thank you in advance for your help :)

Yahweasel commented 3 months ago

The libav encoder for H.264 is not named "h264". They reserve that style of name for built-in/embedded encoders, and the H.264 encoder is external to libav. The particular H.264 encoder included in libav.js is "libopenh264". Use that encoder name; it should be included in the h264-aac[-avc] variants without the need to add any extra configs. (libx264 is more a popular encoder, but isn't included in libav.js, presumably because it's under the GPL.)

... personally, I find libav's naming convention for encoders to be inscrutable and inconsistent, but that's only because it's inscrutable and inconsistent.