### Default libav.js Configuration Fragments Example Source: https://github.com/yahweasel/libav.js/blob/master/docs/CONFIG.md An example of configuration fragments typically found in the default libav.js build. This list includes support for Ogg, WebM formats, Opus and FLAC codecs, and audio filters. ```json ["format-ogg", "format-webm", "parser-opus", "codec-libopus", "format-flac", "parser-flac", "codec-flac", "format-wav", "audio-filters"] ``` -------------------------------- ### Setup Video Player UI and Decoder Source: https://github.com/yahweasel/libav.js/blob/master/demo/demo.html Configures the user interface for video playback, including a canvas for rendering, a seeker bar for navigation, and display areas for duration and statistics. It also initializes the video decoder and scaler context. ```javascript // ... inside the main async function, after demuxing ... const videoStream = streams[videoIdx]; // Set up the "player" UI main.innerHTML = ""; const durationBox = dce("div"); durationBox.innerHTML = `0/${videoStream.duration}`; main.appendChild(durationBox); const statsBox = dce("div"); statsBox.innerHTML = " "; main.appendChild(statsBox); const renderChk = dce("input"); renderChk.style.display = "block"; renderChk.type = "checkbox"; renderChk.checked = true; main.appendChild(renderChk); const canvas = dce("canvas"); canvas.style.display = "block"; canvas.width = 640; canvas.height = 360; main.appendChild(canvas); const cctx = canvas.getContext("2d"); const seeker = dce("input"); seeker.type = "range"; seeker.min = 0; seeker.max = Math.ceil(videoStream.duration * 10); main.appendChild(seeker); let seekerWakeup = null; let seeked = false; seeker.oninput = async () => { const ts = seeker.value / 10 * videoStream.time_base_den / videoStream.time_base_num; const ret = await libav.avformat_seek_file_max(fmt_ctx, videoIdx, ts, 0); seeked = true; if (seekerWakeup) { const w = seekerWakeup; seekerWakeup = null; w(); } }; // Initialize the decoder const [, c, pkt, frame] = await libav.ff_init_decoder(videoStream.codec_id, videoStream.codecpar); // Prepare for scaler and stats let inW = -1, inH = -1, inF = -1; let sctx = null; const sinFrame = await libav.av_frame_alloc(); const soutFrame = await libav.av_frame_alloc(); const stats = []; // ... rest of the code ... ``` -------------------------------- ### Load and Demux Video File Source: https://github.com/yahweasel/libav.js/blob/master/demo/demo.html Handles user file input and prepares the video file for processing by LibAV.js. It initializes the demuxer to get stream information and sets up the necessary structures for decoding and rendering. ```javascript // ... inside the main async function ... const libav = await LibAV.LibAV(); // Initialize LibAV // Load the file from user input const file = await new Promise(res => { main.innerHTML = ""; const label = dce("label"); label.innerHTML = "File: "; label.htmlFor = "load-file"; main.appendChild(label); const picker = dce("input"); picker.type = "file"; picker.id = "load-file"; main.appendChild(picker); picker.focus(); picker.onchange = () => { if (picker.files.length > 0) res(picker.files[0]); }; }); main.innerHTML = "Loading..."; // Initial read and demuxer setup await libav.mkreadaheadfile("input", file); const [fmt_ctx, streams] = await libav.ff_init_demuxer_file("input"); // Find the video stream let videoIdx = -1; for (let i = 0; i < streams.length; i++) { if (streams[i].codec_type === libav.AVMEDIA_TYPE_VIDEO) { videoIdx = i; break; } } if (videoIdx < 0) { main.innerHTML = "Error! Couldn't find video stream!"; return; } const videoStream = streams[videoIdx]; // ... rest of the code ... ``` -------------------------------- ### Create Custom libav.js Variant Configuration Source: https://github.com/yahweasel/libav.js/blob/master/docs/CONFIG.md This command demonstrates how to create a custom build variant for libav.js. It specifies the variant name and a JSON array of configuration fragments to include, such as audio filters, codecs, and formats. ```bash ./mkconfig.js my-great-variant '["audio-filters", "format-rm", "codec-rv20", "codec-ra_144"]' ``` ```bash ./mkconfig.js my-custom-variant '["audio-filters", "swscale", "protocol-jsfetch", "demuxer-hls", "parser-h264", "decoder-h264", "parser-aac", "decoder-aac"]' ``` -------------------------------- ### Run libav.js Tests in a Web Browser Source: https://github.com/yahweasel/libav.js/blob/master/docs/TESTS.md Guide to exposing the libav.js directory via a web server and accessing the browser-based test suite. This method also supports running slow tests. ```html Expose libav.js directory with a web server. Access: tests/web-test.html ``` -------------------------------- ### Load libav.js Instance within Test Harness Source: https://github.com/yahweasel/libav.js/blob/master/docs/TESTS.md Demonstrates how to load an instance of libav.js within the test harness. It shows how to get the default shared instance or a new, separate instance. ```javascript // Get the default shared libav.js instance const lav = await h.LibAV(); // Get a new, separate libav.js instance const lav_new = await h.LibAV({}); // Load options can be passed to h.LibAV({}) ``` -------------------------------- ### Checking Browser Feature Support for LibAV.js Source: https://github.com/yahweasel/libav.js/blob/master/docs/API.md Provides examples of using exported functions `LibAV.isWebAssemblySupported` and `LibAV.isThreadingSupported` to check if the browser environment supports WebAssembly and threading, respectively. ```javascript const wasmSupported = await LibAV.isWebAssemblySupported(); const threadingSupported = await LibAV.isThreadingSupported(); console.log("WebAssembly supported:", wasmSupported); console.log("Threading supported:", threadingSupported); ``` -------------------------------- ### TypeScript Import Example for libav.js Source: https://github.com/yahweasel/libav.js/blob/master/README.md Demonstrates how to import TypeScript type definitions for libav.js. This allows for type checking and autocompletion when using libav.js in a TypeScript project. You can either copy the type definition file or import it from the npm package. ```typescript import type LibAVJS from "./libav.types"; declare let LibAV: LibAVJS.LibAVWrapper; ``` ```typescript import type LibAVJS from "libav.js"; declare let LibAV: LibAVJS.LibAVWrapper; ``` -------------------------------- ### Browser: Decode Opus audio locally with default Web Worker behavior Source: https://github.com/yahweasel/libav.js/blob/master/README.md Illustrates using libav.js included from a local file, allowing it to use Web Workers by default. Similar to the CDN example, it decodes an Opus file and reports the number of audio frames. This is the recommended approach for local development and production. ```html
``` -------------------------------- ### Build and Run Node.js Tests for libav.js Source: https://github.com/yahweasel/libav.js/blob/master/docs/TESTS.md Instructions to build the libav.js 'all' variant and execute tests using Node.js. Supports options for including slow tests and performing coverage analysis. ```bash make build-all cd tests/ node node-test.js [--include-slow] [--coverage] ``` -------------------------------- ### Delete File or Device in libav.js Source: https://github.com/yahweasel/libav.js/blob/master/docs/IO.md Provides examples for deleting different types of files and devices managed by libav.js. Note that specific unlink methods are required for readahead and workerfs files. ```javascript // Delete a simple file or a block reader device await libav.unlink("my_file_or_device_name"); // Delete a readahead file await libav.unlinkreadaheadfile("my_readahead_file_name"); // Delete a workerfs file (using the original name provided to mkworkerfsfile) await libav.unlinkworkerfsfile("my_workerfs_file_name"); ``` -------------------------------- ### Initialize and Load LibAV.js Source: https://github.com/yahweasel/libav.js/blob/master/demo/demo.html Asynchronously initializes the LibAV.js library. It allows the user to select a variant (e.g., 'webm') and dynamically loads the corresponding script. This sets up the core LibAV object for further operations. ```javascript async function() { try { const dce = document.createElement.bind(document); const main = dce("div"); document.body.appendChild(main); // Variant selection const variant = await new Promise(res => { // ... UI code for variant selection ... const label = dce("label"); label.innerHTML = "Variant: "; label.htmlFor = "variant"; main.appendChild(label); const vbox = dce("input"); vbox.type = "text"; vbox.id = "variant"; vbox.value = "webm"; main.appendChild(vbox); const ok = dce("button"); ok.innerHTML = "Load"; main.appendChild(ok); vbox.focus(); vbox.select(); vbox.onkeypress = ev => { if (ev.key === "Enter") res(vbox.value); }; ok.onclick = ev => { res(vbox.value); }; }); main.innerHTML = "Loading..."; // Load libav.js dynamically LibAV = {base: "../dist"}; await new Promise(res => { const scr = dce("script"); scr.src = `../dist/libav-${variant}.js?${Math.random()}`; scr.onload = res; scr.onerror = () => { alert("Failed to load variant!"); }; document.body.appendChild(scr); }); const libav = await LibAV.LibAV(); // Initialize LibAV // ... rest of the code ... } catch (e) { console.error("Error initializing LibAV.js:", e); } } ``` -------------------------------- ### Initialize Muxer with Options and Streams - libav.js Source: https://github.com/yahweasel/libav.js/blob/master/docs/API.md Initializes a muxer, optionally opening the file and initializing the format context. It accepts format by numerical code or name, filename, and device options. Streams are provided as tuples of codec context, time base numerator, and denominator. Returns the output context, format, writer context, and stream contexts. Requires `avformat_write_header` before writing and `av_write_trailer` after. ```javascript ff_init_muxer( opts: { oformat?: number, format_name?: string, filename?: string, device?: boolean, open?: boolean, codecpars?: boolean }, streamCtxs: [number, number, number][] ): Promise<[number, number, number, number[]]> ``` -------------------------------- ### Creating a LibAV Instance Source: https://github.com/yahweasel/libav.js/blob/master/docs/API.md Demonstrates the basic usage of the `LibAV.LibAV` factory function to create a new instance of LibAV. It can be called with no arguments for default options or with a configuration object. ```javascript const libav = await LibAV.LibAV(); ``` -------------------------------- ### Remux Media File with LibAV.JS and FileSystemFileHandle (JavaScript) Source: https://github.com/yahweasel/libav.js/blob/master/demo/fsfh-demo.html This JavaScript code demonstrates a complete workflow for remuxing a media file using LibAV.JS. It handles user interaction for selecting the LibAV.JS variant, loading an input file via file picker, and saving the remuxed output using the `showSaveFilePicker` API. It initializes the demuxer, sets up the muxer, reads frames, writes packets, and cleans up resources. ```javascript async function() { try { const dce = document.createElement.bind(document); const main = dce("div"); document.body.appendChild(main); const variant = await new Promise(res => { const label = dce("label"); label.innerHTML = "Variant: "; label.htmlFor = "variant"; main.appendChild(label); const vbox = dce("input"); vbox.type = "text"; vbox.id = "variant"; vbox.value = "webm"; main.appendChild(vbox); const ok = dce("button"); ok.innerHTML = "Load"; main.appendChild(ok); vbox.focus(); vbox.select(); vbox.onkeypress = ev => { if (ev.key === "Enter") res(vbox.value); }; ok.onclick = ev => { res(vbox.value); }; }); main.innerHTML = "Loading..."; // Load libav.js LibAV = {base: "../dist"}; await new Promise(res => { const scr = dce("script"); scr.src = `../dist/libav-${variant}.js?${Math.random()}`; scr.onload = res; scr.onerror = () => { alert("Failed to load variant!"); }; document.body.appendChild(scr); }); const libav = await LibAV.LibAV(); // Load the file const file = await new Promise(res => { main.innerHTML = ""; const label = dce("label"); label.innerHTML = "File: "; label.htmlFor = "load-file"; main.appendChild(label); const picker = dce("input"); picker.type = "file"; picker.id = "load-file"; main.appendChild(picker); picker.focus(); picker.onchange = () => { if (picker.files.length > 0) res(picker.files[0]); }; }); main.innerHTML = "Loading..."; // Initial read await libav.mkreadaheadfile("input", file); const [fmt_ctx, streams] = await libav.ff_init_demuxer_file("input"); // Create the writer const fsfh = await showSaveFilePicker({ suggestedName: "out.mkv" }); await libav.mkfsfhfile("out.mkv", fsfh); // Get the codec parameters const ostreams = streams.map(s => [ s.codecpar, s.time_base_num, s.time_base_den ]); // And the muxer const [oc, , pb] = await libav.ff_init_muxer({ filename: "out.mkv", open: true, codecpars: true }, ostreams); await libav.avformat_write_header(oc, 0); const pkt = await libav.av_packet_alloc(); main.innerHTML = "Remuxing..."; // And read while (true) { // Read some packets const [res, packets] = await libav.ff_read_frame_multi(fmt_ctx, pkt, { limit: 1024 * 1024, unify: true }); // And write them out if (packets[0]) await libav.ff_write_multi(oc, pkt, packets[0]); if (res === libav.AVERROR_EOF) break; } await libav.av_write_trailer(oc); await libav.unlinkfsfhfile("out.mkv"); await libav.ff_free_muxer(oc, pb); await libav.av_packet_free_js(pkt); await libav.avformat_close_input_js(fmt_ctx); main.innerHTML = "Done."; } catch (ex) { alert(ex + ""); } }() ``` -------------------------------- ### Run LibAV.js Tests with Options (JavaScript) Source: https://github.com/yahweasel/libav.js/blob/master/tests/web-test.html This JavaScript code snippet sets up an event listener for a button click to run LibAV.js tests. It fetches test suite information, configures test options (including WebAssembly and threading), and displays test output in designated HTML elements. Dependencies include the LibAVTestHarness, fetch API, and specific HTML elements with IDs like 'runTests', 'stdout', 'stderr', 'status', and 'includeSlow'. ```javascript function() { const runTests = document.getElementById("runTests"); runTests.onclick = async function() { runTests.style.display = "none"; const harness = LibAVTestHarness; harness.print = text => { document.getElementById("stdout").innerText += text + "\n"; }; harness.printErr = text => { document.getElementById("stderr").innerText += text + "\n"; }; harness.printStatus = text => { document.getElementById("status").innerText = text; }; let suite; { const resp = await fetch("suite.json"); suite = await resp.json(); } await harness.loadTests(suite); harness.options.includeSlow = document.getElementById("includeSlow").checked; await harness.runTests([ null, {yesthreads: true}, {nowasm: true} ]); runTests.style.display = ""; }; })(); ``` -------------------------------- ### Muxing - ff_init_muxer and ff_write_multi Source: https://context7.com/yahweasel/libav.js/llms.txt This section explains how to combine encoded packets into various container formats like WebM. It covers initializing the muxer, writing headers, writing packets, finalizing the file, and freeing allocated resources. ```APIDOC ## Muxing - ff_init_muxer and ff_write_multi ### Description Combine encoded packets into container formats. ### Method Asynchronous JavaScript functions ### Endpoint N/A (Client-side library functions) ### Parameters N/A ### Request Example ```javascript // Initialize muxer for WebM output const [oc, fmt, pb, streams] = await libav.ff_init_muxer( {format_name: "webm", filename: "output.webm", device: true}, [[codecpar, 1, 48000]] // [codec_params, time_base_num, time_base_den] ); // Write header await libav.avformat_write_header(oc, 0); // Write packets await libav.ff_write_multi(oc, pkt, packets); // Finalize file await libav.av_write_trailer(oc); await libav.ff_free_muxer(oc, pb); // Read output const outputData = await libav.readFile("output.webm"); ``` ### Response N/A (Operations modify internal state or produce output files) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Complete Transcode Pipeline with libav.js Source: https://context7.com/yahweasel/libav.js/llms.txt This snippet demonstrates a full media transcoding workflow: reading and demuxing an input file, decoding its streams, encoding with new settings (e.g., libopus audio), and muxing into an output container. It handles file writing, event callbacks for output data, and cleanup of all intermediate contexts and resources. Requires libav.js and input media data. ```javascript const libav = await LibAV.LibAV(); await libav.writeFile("input.webm", inputData); const [in_fmt_ctx, in_streams] = await libav.ff_init_demuxer_file("input.webm"); const in_stream = in_streams[0]; const [, dec_ctx, dec_pkt, dec_frame] = await libav.ff_init_decoder( in_stream.codec_id, {codecpar: in_stream.codecpar} ); const [, enc_ctx, enc_frame, enc_pkt, frame_size] = await libav.ff_init_encoder("libopus", { ctx: { sample_fmt: libav.AV_SAMPLE_FMT_FLT, sample_rate: 48000, channel_layout: 4, channels: 1, bit_rate: 96000 } }); const codecpar = await libav.avcodec_parameters_alloc(); await libav.avcodec_parameters_from_context(codecpar, enc_ctx); await libav.mkwriterdev("output.ogg"); let outputData = new Uint8Array(0); libav.onwrite = (name, position, data) => { const newLen = Math.max(outputData.length, position + data.length); if (newLen > outputData.length) { const newData = new Uint8Array(newLen); newData.set(outputData); outputData = newData; } outputData.set(data, position); }; const [out_fmt_ctx, , pb] = await libav.ff_init_muxer( {format_name: "ogg", filename: "output.ogg", open: true}, [[codecpar, 1, 48000]] ); await libav.avformat_write_header(out_fmt_ctx, 0); const [, in_packets] = await libav.ff_read_multi(in_fmt_ctx, dec_pkt); const frames = await libav.ff_decode_multi(dec_ctx, dec_pkt, dec_frame, in_packets[in_stream.index], true); const out_packets = await libav.ff_encode_multi(enc_ctx, enc_frame, enc_pkt, frames, true); await libav.ff_write_multi(out_fmt_ctx, enc_pkt, out_packets); await libav.av_write_trailer(out_fmt_ctx); await libav.ff_free_muxer(out_fmt_ctx, pb); await libav.ff_free_encoder(enc_ctx, enc_frame, enc_pkt); await libav.ff_free_decoder(dec_ctx, dec_pkt, dec_frame); await libav.avformat_close_input_js(in_fmt_ctx); console.log(`Transcoded to ${outputData.length} bytes`); ``` -------------------------------- ### Initialize libav.js Instance - LibAV.LibAV Source: https://context7.com/yahweasel/libav.js/llms.txt Initializes a libav.js instance with customizable execution modes. It can be configured for default worker mode, synchronous mode (noworker: true), or multi-threaded mode (yesthreads: true). It also allows loading specific variants and checking for feature support like threading. ```javascript // Basic initialization with default settings (worker mode) const libav = await LibAV.LibAV(); // Initialize with options for different execution modes const libavDirect = await LibAV.LibAV({noworker: true}); // Synchronous mode const libavThreaded = await LibAV.LibAV({yesthreads: true}); // Multi-threaded mode // Check which target will load const target = LibAV.target(); // Returns "asm", "wasm", or "thr" console.log(`Loading target: ${target}`); // Load a specific variant const libavOpus = await LibAV.LibAV({variant: "opus"}); // Check feature support if (LibAV.isThreadingSupported()) { console.log("Threading is available"); } ``` -------------------------------- ### AVFormat Demuxing Source: https://github.com/yahweasel/libav.js/blob/master/docs/API.md Functions for initializing a demuxer from a file in libav.js. ```APIDOC ## POST /ff_init_demuxer_file ### Description Initializes a demuxer from a given filename, which can be a reader device. Optionally takes the expected format as a string. ### Method POST ### Endpoint /ff_init_demuxer_file ### Parameters #### Request Body - **filename** (string) - Required - The filename or device to open for demuxing. - **fmt** (string) - Optional - The expected format of the input file. ### Request Example ```json { "filename": "input.mp4", "fmt": "mp4" } ``` ### Response #### Success Response (200) - **fmt_ctx** (number) - The format context (fmt_ctx). - **streams** (array) - An array of stream objects. #### Response Example ```json { "fmt_ctx": 202, "streams": [ {"index": 0, "codec_type": "video", "time_base": {"num": 1, "den": 30}}, {"index": 1, "codec_type": "audio", "time_base": {"num": 1, "den": 48000}} ] } ``` ``` -------------------------------- ### Creating and Sending Data to Streaming Reader Devices in libav.js Source: https://github.com/yahweasel/libav.js/blob/master/docs/IO.md Illustrates the creation of virtual streaming devices and how to send data to them. This is useful for handling data that arrives sequentially. The `onread` callback is triggered when libav needs more data, and `ff_reader_dev_send` is used to provide it. Sending `null` signals the end of the stream. ```javascript await libav.mkreaderdev("input"); libav.onread = function(filename, position, length) { // ... get some data ... libav.ff_reader_dev_send("input", eof ? null : data); }; libav.ff_reader_dev_send("input", data); ``` -------------------------------- ### LibAV Loading Options Configuration Source: https://github.com/yahweasel/libav.js/blob/master/docs/API.md Illustrates the structure of the configuration object that can be passed to the `LibAV.LibAV` factory function. These options control aspects like worker usage, WASM loading, threading, and base paths. ```javascript const options = { "noworker": false, "nowasm": false, "yesthreads": false, "nothreads": false, "base": "/path/to/assets/", "toImport": ["libavformat.js", "libavcodec.js"], "factory": "./libav.js", "variant": "avformat", "wasmurl": "/path/to/wasm/libav.wasm" }; const libav = await LibAV.LibAV(options); ``` -------------------------------- ### Initialize Filter Graph in libav.js (ff_init_filter_graph) Source: https://github.com/yahweasel/libav.js/blob/master/docs/API.md Creates a filter graph using a filter description string and specifies input/output settings. It supports complex filter graphs and multiple inputs/outputs, naming pads as 'in'/'out' or 'in0'/'out0' etc. based on the number of connections. Returns the filter graph context, source contexts, and sink contexts. ```typescript ff_init_filter_graph( filters_descr: string, input: FilterIOSettings | FilterIOSettings[], output: FilterIOSettings | FilterIOSettings[] ): Promise<[number, number | number[], number | number[]]> ``` -------------------------------- ### Create and Use Block Reader Device in libav.js Source: https://github.com/yahweasel/libav.js/blob/master/docs/IO.md Demonstrates how to create a block reader device, set up its read callback, and send data back to libav.js for processing. This is useful for fixed-size input data that needs to be presented as a block device. ```javascript libav.onblockread = async function(name, pos, length) { const ab = await file.slice(pos, pos + length).arrayBuffer(); libav.ff_block_reader_dev_send(name, pos, new Uint8Array(ab)); }; await libav.mkblockreaderdev("input"); // ... later in the code ... while (true) { const [result, packets] = await libav.ff_read_multi(fmt_ctx, pkt, null, {limit: 32*1024 /* amount to read at once */}); // Process packets if (result.is_eos) break; } ``` -------------------------------- ### Mount and Unmount Writer Filesystem Source: https://github.com/yahweasel/libav.js/blob/master/docs/IO.md Shows how to mount a writer filesystem to a specified directory and unmount it when no longer needed. All files created within the mounted directory will automatically behave as block writer devices, invoking the `onwrite` callback. ```javascript await libav.mountwriterfs("/my_output_dir"); // Files written to '/my_output_dir/*' will now trigger onwrite // Example: await libav.ffmpeg("-i", "input.mp4", "/my_output_dir/frame_%d.png"); // ... perform operations ... await libav.unmount("/my_output_dir"); ``` -------------------------------- ### Initialize Demuxer from File - libav.js Source: https://github.com/yahweasel/libav.js/blob/master/docs/API.md Initializes a demuxer from a given filename, which can be a reader device. An optional expected format string can be provided. Returns the format context and a list of streams. The format context should be freed using `avformat_close_input_js`. ```javascript ff_init_demuxer_file( filename: string, fmt?: string ): Promise<[number, Stream[]]> ``` -------------------------------- ### Reading Data with ff_read_multi in libav.js (Push Style) Source: https://github.com/yahweasel/libav.js/blob/master/docs/IO.md Demonstrates using `ff_read_multi` in a 'push' style, where `ff_read_multi` itself manages data requests. If `ff_read_multi` returns `-libav.EAGAIN`, it signifies that more data is needed, which should then be provided via `libav.ff_reader_dev_send`. ```javascript while (true) { const [result, packets] = await libav.ff_read_multi(fmt_ctx, pkt, "input"); // ... process packets ... if (result === -libav.EAGAIN) { // ... get some data ... libav.ff_reader_dev_send("input", data); } } ``` -------------------------------- ### Create and Use Block Writer Device with ffmpeg CLI Source: https://github.com/yahweasel/libav.js/blob/master/docs/IO.md Demonstrates creating a block writer device, setting up an onwrite callback to accumulate data, and using the ffmpeg CLI to write to the device. The callback collects data chunks into a single Uint8Array. Ensure the '-y' option is used with ffmpeg to overwrite the device file. ```javascript await libav.writeFile("input", inputData); await libav.mkwriterdev("output"); let writtenData = new Uint8Array(0); libav.onwrite = function(name, pos, data) { const newLen = Math.max(writtenData.length, pos + data.length); if (newLen > writtenData.length) { const newData = new Uint8Array(newLen); newData.set(writtenData); writtenData = newData; } writtenData.set(data, pos); }; await libav.ffmpeg( "-i", "input", "-f", "webm", "-y", "output" ); // writtenData now contains the data written to the file ``` -------------------------------- ### Reading Data with ff_read_multi in libav.js (Callback Style) Source: https://github.com/yahweasel/libav.js/blob/master/docs/IO.md Shows how to use `ff_read_multi` with a streaming reader device in a callback-driven manner. libav.js calls the `onread` callback when it requires more data, and this data is then supplied using `ff_reader_dev_send`. The loop continues until all data is processed. ```javascript await libav.mkreaderdev("input"); libav.onread = function() { // ... get some data ... libav.ff_reader_dev_send("input", eof ? null : data); }; while (true) { const [result, packets] = await libav.ff_read_multi( fmt_ctx, pkt, null, { limit: 32*1024 /* amount to read at once */ } ); // ... process packets ... } ``` -------------------------------- ### Reading Packets - ff_read_multi Source: https://context7.com/yahweasel/libav.js/llms.txt Demonstrates how to read compressed packets from a demuxed media file. It includes initializing the demuxer, allocating packet buffers, and reading packets iteratively with a specified limit. ```APIDOC ## Reading Packets - ff_read_multi ### Description Read compressed packets from a demuxed media file. ### Method Asynchronous JavaScript functions ### Endpoint N/A (Client-side library functions) ### Parameters N/A ### Request Example ```javascript const [fmt_ctx, streams] = await libav.ff_init_demuxer_file("video.webm"); const pkt = await libav.av_packet_alloc(); // Read packets in chunks with limit let allPackets = {}; while (true) { const [result, packets] = await libav.ff_read_multi(fmt_ctx, pkt, null, { limit: 1024 * 1024 // Read 1MB at a time }); // Merge packets by stream index for (const streamIdx in packets) { if (!allPackets[streamIdx]) allPackets[streamIdx] = []; allPackets[streamIdx].push(...packets[streamIdx]); } if (result === libav.AVERROR_EOF) break; } console.log(`Stream 0: ${allPackets[0].length} packets`); await libav.av_packet_free(pkt); ``` ### Response N/A (Operations modify internal state or produce output packets) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Run ffprobe CLI (libav.js) Source: https://github.com/yahweasel/libav.js/blob/master/docs/API.md Executes the ffprobe command-line tool, analogous to the ffmpeg CLI function. It accepts arguments as strings or arrays of strings and returns the exit code of the ffprobe process. ```javascript ffprobe(...args: (string | string[])[]): Promise