### Serve JPEG Keyframes from Media Files with Koa Source: https://github.com/streampunk/beamcoder/blob/master/README.md This example demonstrates how to create a Koa server that serves JPEG keyframes from media files. It parses the request path to get the filename and time, seeks to the nearest keyframe, decodes it, and then encodes it as a JPEG image. Ensure FFmpeg is installed and accessible. ```javascript const beamcoder = require('beamcoder'); const Koa = require('koa'); const app = new Koa(); app.use(async (ctx) => { // Assume HTTP GET with path // let parts = ctx.path.split('/'); // Split the path into filename and time if ((parts.length < 3) || (isNaN(+parts[2]))) return; // Ignore favicon etc.. let dm = await beamcoder.demuxer('file:' + parts[1]); // Probe the file await dm.seek({ time: +parts[2] }); // Seek to the closest keyframe to time let packet = await dm.read(); // Find the next video packet (assumes stream 0) for ( ; packet.stream_index !== 0 ; packet = await dm.read() ); let dec = beamcoder.decoder({ demuxer: dm, stream_index: 0 }); // Create a decoder let decResult = await dec.decode(packet); // Decode the frame if (decResult.frames.length === 0) // Frame may be buffered, so flush it out decResult = await dec.flush(); // Filtering could be used to transform the picture here, e.g. scaling let enc = beamcoder.encoder({ // Create an encoder for JPEG data name : 'mjpeg', // FFmpeg does not have an encoder called 'jpeg' width : dec.width, height: dec.height, pix_fmt: dec.pix_fmt.indexOf('422') >= 0 ? 'yuvj422p' : 'yuvj420p', time_base: [1, 1] }); let jpegResult = await enc.encode(decResult.frames[0]); // Encode the frame await enc.flush(); // Tidy the encoder ctx.type = 'image/jpeg'; // Set the Content-Type of the data ctx.body = jpegResult.packets[0].data; // Return the JPEG image data }); app.listen(3000); // Start the server on port 3000 ``` -------------------------------- ### Install Beamcoder on Windows Source: https://github.com/streampunk/beamcoder/blob/master/README.md Install beam coder from the root folder of your package. This will install all necessary dependencies, download FFmpeg, and compile native extensions. Ensure sufficient threads are available by setting UV_THREADPOOL_SIZE. ```bash npm install beamcoder set UV_THREADPOOL_SIZE=32 ``` -------------------------------- ### Install Beamcoder on Linux Source: https://github.com/streampunk/beamcoder/blob/master/README.md Install beam coder from the root folder of your package. This will check for dependencies and compile native extensions. Ensure sufficient threads are available by setting UV_THREADPOOL_SIZE. ```bash npm install beamcoder export UV_THREADPOOL_SIZE=32 ``` -------------------------------- ### Muxer Stream for Raw Audio Source: https://github.com/streampunk/beamcoder/blob/master/README.md Configure a muxer stream for raw audio output and pipe it to an output stream. This example sets up a muxer for 16-bit, 2-channel audio and opens the IO with specific flags. ```javascript let muxerStream = beamcoder.muxerStream({ highwaterMark: 1024 }); muxerStream.pipe(outStream); let muxer = muxerStream.muxer({ format_name: 's16le' }); await muxer.openIO({ url: '', flags: { DIRECT: true } }); await muxer.writeHeader({ options: { flags: { AVFMT_NOFILE: true }, fflags: 'flush_packets' } }); ``` -------------------------------- ### Get Sample Format Details with Beamcoder Source: https://github.com/streampunk/beamcoder/blob/master/README.md Call beamcoder.sample_fmts() to get details about the sample formats for planar audio representations. ```javascript beamcoder.sample_fmts(); ``` -------------------------------- ### Muxing WAVE File with Beamcoder Source: https://github.com/streampunk/beamcoder/blob/master/README.md Example of reading from a WAVE file using a demuxer and writing to a new WAVE file using a muxer. This demonstrates the basic stages of muxing, including opening IO, writing headers, writing frames, and writing trailers. ```javascript let demuxer = await beamcoder.demuxer('file:input.wav'); let muxer = beamcoder.muxer({ filename: 'file:test.wav' }); let stream = muxer.newStream(demuxer.streams[0]); await muxer.openIO(); await muxer.writeHeader(); let packet = {}; for ( let x = 0 ; x < 100 && packet !== null ; x++ ) { packet = await demuxer.read(); await muxer.writeFrame(packet); } await muxer.writeTrailer(); ``` -------------------------------- ### Create Encoder by Name Source: https://github.com/streampunk/beamcoder/blob/master/README.md Instantiate an encoder by specifying the codec's name. For example, 'h264' will typically select the 'libx264' software codec. ```javascript // Create an encoder by name of name of a codec family let v_encoder = beamcoder.encoder({ name: 'h264' }); // In this case, the 'libx264' software codec will be selected. ``` -------------------------------- ### Demuxer Object Structure Source: https://github.com/streampunk/beamcoder/blob/master/README.md An example of the Javascript object returned after successfully creating a demuxer. It details the input format, context flags, streams (video and audio), URL, timing information, and available methods. ```javascript { type: 'demuxer', iformat: { type: 'InputFormat', name: 'mpegts', /* ... */ }, ctx_flags: { NOHEADER: false, UNSEEKABLE: false }, streams: [ { type: 'Stream', index: 0, id: 301, time_base: [ 1, 90000 ], /* ... */ codecpar: { type: 'CodecParameters', codec_type: 'video', codec_id: 173, name: 'hevc', codec_tag: 'HEVC', format: 'yuv420p', /* ... */ width: 1920, height: 1080, /* ... */ } }, { type: 'Stream', index: 1, id: 302, time_base: [ 1, 90000 ], /* ... */ codecpar: { type: 'CodecParameters', codec_type: 'audio', codec_id: 86018, name: 'aac', /* ... */ format: 'fltp', /* ... */ channel_layout: 'stereo', channels: 2, /* ... */ } } ], url: '../media/bbb_1080p_c.ts', start_time: 80000, duration: 596291667, bit_rate: 2176799, /* ... */ stream: [Function], read: [Function: readFrame], seek: [Function: seekFrame] } ``` -------------------------------- ### Initiate FFmpeg Reactive Streams Processing Source: https://github.com/streampunk/beamcoder/blob/master/README.md Start the FFmpeg media processing pipeline by creating sources and streams, then running the stream execution. Processing continues until the specified time range is completed or sources are exhausted. ```javascript await beamcoder.makeSources(params); let beamStreams = await beamcoder.makeStreams(params); await beamStreams.run(); ``` -------------------------------- ### Get Pixel Format Details with Beamcoder Source: https://github.com/streampunk/beamcoder/blob/master/README.md Call beamcoder.pix_fmts() to get details about the planes expected for each pixel format. ```javascript beamcoder.pix_fmts(); ``` -------------------------------- ### Encoder Input Buffer Padding Size Source: https://github.com/streampunk/beamcoder/blob/master/README.md Access beamcoder.AV_INPUT_BUFFER_PADDING_SIZE to get the minimum amount of padding recommended when creating buffers from Javascript. ```javascript beamcoder.AV_INPUT_BUFFER_PADDING_SIZE ``` -------------------------------- ### Packet Data Structure Source: https://github.com/streampunk/beamcoder/blob/master/README.md An example of the `Packet` object structure returned by the `read` method. It contains metadata like timestamps, data buffer, size, stream index, flags, duration, and file position. ```json { type: 'Packet', pts: 2792448, // presentation timestamp, measured in stream timebase dts: 2792448, // decode timestamp, measured in stream timebase data: // the raw data of the packet , size: 4160, // the size of the raw data stream_index: 0, // the stream index of the stream this packet belongs to flags: { KEY: true, // Packet represents a key frame CORRUPT: false, // Corruption detected DISCARD: false, // Can be dropped after decoding TRUSTED: false, // Packet from a trusted source DISPOSABLE: false }, // Frames that can be discarded by the decoder duration: 1024, // Wrt the stream timebase pos: 11169836 } // Byte offset into the file ``` -------------------------------- ### Basic Media Processing Workflow with Promises Source: https://github.com/streampunk/beamcoder/blob/master/README.md Demonstrates creating a demuxer and decoder, reading frames in a loop, decoding them, and flushing the decoder. Ensure the file path is correct and the codec is supported. ```javascript const beamcoder = require('beamcoder'); async function run() { let demuxer = await beamcoder.demuxer('/path/to/file.mp4'); // Create a demuxer for a file let decoder = beamcoder.decoder({ name: 'h264' }); // Codec asserted. Can pass in demuxer. let packet = {}; for ( let x = 0 ; x < 1000 && packet != null ; x++ ) { packet = await format.read(); // Read next frame. Note: returns null for EOF if (packet && packet.stream_index === 0) { // Check demuxer to find index of video stream let frames = await decoder.decode(packet); // Do something with the frame data console.log(x, frames.total_time); // Optional log of time taken to decode each frame } } let frames = await decoder.flush(); // Must tell the decoder when we are done console.log('flush', frames.total_time, frames.length); } run(); ``` -------------------------------- ### Create Muxer Instance Source: https://github.com/streampunk/beamcoder/blob/master/README.md Instantiate a muxer by specifying the output format through `format_name`, `filename`, or an `oformat` object. This is the initial step in preparing media output. ```javascript muxer = beamcoder.muxer({ format_name: 'mp4' }); ``` ```javascript muxer = beamcoder.muxer({ filename: 'example.wav' }); ``` ```javascript muxer = beamcoder.muxer({ oformat: of }); ``` -------------------------------- ### Create Demuxer with Options for Raw Formats Source: https://github.com/streampunk/beamcoder/blob/master/README.md Demonstrates how to create a demuxer for formats like 'rawvideo' that require additional metadata. Options for video size and pixel format are passed in an object. ```javascript let rawDemuxer = await beamcoder.demuxer({ url: 'file:movie/bbb/raw_pictures_%d.rgb', options: { video_size: '640x480', pixel_format: 'rgb24' } }); ``` -------------------------------- ### Open Muxer Output (Simple) Source: https://github.com/streampunk/beamcoder/blob/master/README.md Asynchronously open the output for a muxer when a filename was provided during its creation. This prepares the output destination for writing media data. ```javascript await muxer.openIO(); ``` -------------------------------- ### Open Muxer Output with Options Source: https://github.com/streampunk/beamcoder/blob/master/README.md Asynchronously open the muxer's output, specifying the URL and protocol-specific options. This allows for advanced configuration of the output destination. ```javascript await muxer.openIO({ url: 'file:test2.wav', // Update URL options: { // Protocol private options blocksize: 8192 } }); ``` -------------------------------- ### Initialize Muxer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Initialize the muxer with a specified format name after the stream has been set up. ```javascript let muxer = muxerStream.muxer({ format_name: 'wav' }); ``` -------------------------------- ### Create Decoder Source: https://github.com/streampunk/beamcoder/blob/master/README.md Instantiate a decoder by specifying its name, codec ID, or by providing a demuxer and stream index. Optional parameters like width and height can also be provided. ```APIDOC ## Create Decoder ### Description To create an instance of a decoder, request a `decoder` from beam coder, specifying either the decoder's `name`, a `codec_id`, or by providing a `demuxer` and a `stream_id`. ### Method `beamcoder.decoder(options)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **name** (string) - Optional - The name of the decoder (e.g., 'h264'). - **codec_id** (number) - Optional - The ID of the codec. - **demuxer** (object) - Optional - A demuxer instance. - **stream_index** (number) - Optional - The index of the stream within the demuxer. - **width** (number) - Optional - The width of the video. - **height** (number) - Optional - The height of the video. ### Request Example ```javascript // Create a decoder by name let decoder = beamcoder.decoder({ name: 'h264' }); // Create a decoder by codec ID let decoder = beamcoder.decoder({ codec_id: 27 }); // Create a decoder using a demuxer and stream index let tsDemux = await beamcoder.demuxer('media/bbb_1080p.ts'); let decoder = beamcoder.decoder({ demuxer: tsDemux, stream_index: 0 }); // Create a decoder with specific dimensions let decoder = beamcoder.decoder({ name: 'h264', width: 1920, height: 1080 }); ``` ### Response #### Success Response (200) - **decoder** (object) - An instance of the decoder. ``` -------------------------------- ### Initialize Muxer Output Source: https://github.com/streampunk/beamcoder/blob/master/README.md Call initOutput() before writeHeader() if muxer structures need to be initialized first. This method can also take options to configure muxer-specific parameters. ```javascript await muxer.initOutput(); ``` -------------------------------- ### Create Video Filterer with Multiple Inputs/Outputs Source: https://github.com/streampunk/beamcoder/blob/master/README.md Instantiate a video filterer supporting multiple inputs and outputs using named parameters. These names must match those used in the filter string. ```javascript let v_filterer = await beamcoder.filterer({ filterType: 'video', inputParams: [ { name: 'in0:v', width: vidStream0.codecpar.width, height: vidStream0.codecpar.height, pixelFormat: vidStream0.codecpar.format, timeBase: vidStream0.time_base, pixelAspect: vidStream0.sample_aspect_ratio, }, { name: 'in1:v', width: vidStream1.codecpar.width, height: vidStream1.codecpar.height, pixelFormat: vidStream1.codecpar.format, timeBase: vidStream1.time_base, pixelAspect: vidStream1.sample_aspect_ratio, } ], outputParams: [ { name: 'out0:v', pixelFormat: 'yuv422' } ], filterSpec: '[in0:v] scale=1280:720 [left]; [in1:v] scale=640:360 [right]; [left][right] overlay=format=auto:x=640 [out0:v]' }); ``` -------------------------------- ### Query Available Muxer Formats Source: https://github.com/streampunk/beamcoder/blob/master/README.md Retrieve a list of all available output formats for muxers. This is useful for understanding supported file types. ```javascript let mxs = beamcoder.muxers(); ``` -------------------------------- ### Create Beamcoder Decoder Instance Source: https://github.com/streampunk/beamcoder/blob/master/README.md Instantiate a decoder by specifying its name, codec ID, or by providing a demuxer and stream ID. The codec parameters of the streams will be used to set the decoding parameters when using a demuxer. ```javascript let decoder = beamcoder.decoder({ name: 'h264' }); ``` ```javascript let decoder = beamcoder.decoder({ codec_id: 27 }); ``` ```javascript let tsDemux = await beamcoder.demuxer('media/bbb_1080p_ts'); let decoder = beamcoder.decoder({ demuxer: tsDemux, stream_index: 0 }); ``` -------------------------------- ### Create Video Filterer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Instantiate a video filterer by specifying filter type, input/output parameters, and a filter definition string. Input parameters are typically read from a demuxer stream object. ```javascript let v_filterer = await beamcoder.filterer({ filterType: 'video', inputParams: [ { width: vidStream.codecpar.width, height: vidStream.codecpar.height, pixelFormat: vidStream.codecpar.format, timeBase: vidStream.time_base, pixelAspect: vidStream.sample_aspect_ratio, } ], outputParams: [ { pixelFormat: 'yuv422' } ], filterSpec: 'scale=1280:720' }); ``` -------------------------------- ### Create a Beamcoder Packet with Options Source: https://github.com/streampunk/beamcoder/blob/master/README.md Instantiates a packet object using the beamcoder factory method. Pass an options object to set initial properties like PTS, DTS, and stream index. ```javascript let q = beamcoder.packet({ pts: 10, dts: 10, stream_index: 3 }); console.log(q); ``` -------------------------------- ### Create Audio Filterer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Instantiate an audio filterer by specifying filter type, input/output parameters, and a filter definition string. Input parameters are typically read from a demuxer stream object. ```javascript let a_filterer = await beamcoder.filterer({ filterType: 'audio', inputParams: [ { sampleRate: audStream.codecpar.sample_rate, sampleFormat: audStream.codecpar.format, channelLayout: 'mono', timeBase: audStream.time_base } ], outputParams: [ { sampleRate: 8000, sampleFormat: 's16', channelLayout: 'mono' } ], filterSpec: 'aresample=8000, aformat=sample_fmts=s16:channel_layouts=mono' }); ``` -------------------------------- ### Create Demuxer from File Source: https://github.com/streampunk/beamcoder/blob/master/README.md Creates a demuxer instance by specifying a file path or URL. This operation is asynchronous and probes the media content upon resolution. ```javascript let tsDemuxer = await beamcoder.demuxer('file:media/bbb_1080p_c.ts'); ``` -------------------------------- ### Configure FFmpeg Reactive Streams Pipeline Parameters Source: https://github.com/streampunk/beamcoder/blob/master/README.md Define parameters for video and audio sources, filters, and output streams for the FFmpeg pipeline. Includes optional time specifications for extracting sections of media. ```javascript const urls = [ 'file:../../Media/big_buck_bunny_1080p_h264.mov' ]; const spec = { start: 0, end: 48 }; const params = { video: [ { sources: [ { url: urls[0], ms: spec, streamIndex: 0 } ], filterSpec: '[in0:v] scale=1280:720, colorspace=all=bt709 [out0:v]', streams: [ { name: 'h264', time_base: [1, 90000], encoderName: 'libx264', codecpar: { width: 1280, height: 720, format: 'yuv422p', color_space: 'bt709', sample_aspect_ratio: [1, 1] } } ] } ], audio: [ { sources: [ { url: urls[0], ms: spec, streamIndex: 2 } ], filterSpec: '[in0:a] aformat=sample_fmts=fltp:channel_layouts=mono [out0:a]', streams: [ { name: 'aac', time_base: [1, 90000], encoderName: 'aac', codecpar: { sample_rate: 48000, format: 'fltp', frame_size: 1024, channels: 1, channel_layout: 'mono' } }, ] }, ], out: { formatName: 'mp4', url: 'file:temp.mp4' } }; ``` -------------------------------- ### Allocate Frame Buffers with Beamcoder Source: https://github.com/streampunk/beamcoder/blob/master/README.md Use the .alloc() method after creating a frame to automatically allocate buffers of the correct size based on computed linesize. This is useful for ensuring correct buffer allocation for video and audio frames. ```javascript let f = beamcoder.frame({ width: 1920, height: 1080, format: 'yuv422p' }).alloc(); ``` -------------------------------- ### Create Muxer Readable Stream Source: https://github.com/streampunk/beamcoder/blob/master/README.md Instantiate a Node.js Readable stream for a muxer with a specified highwater mark. This stream can then be piped to a destination. ```javascript let muxerStream = beamcoder.muxerStream({ highwaterMark: 65536 }); ``` -------------------------------- ### Create Demuxer for Raw Audio Stream Source: https://github.com/streampunk/beamcoder/blob/master/README.md Creates a demuxer for a raw audio stream, specifying format and options like sample rate, channels, and packet size. This is useful when the source stream does not inherently provide format information. ```javascript let demuxers = beamcoder.demuxers(); let iformat = demuxers[Object.keys(demuxers).find(k => demuxers[k].name === 's16le')]; let demuxerStream = beamcoder.demuxerStream({ highwaterMark: 1024 }); inStream.pipe(demuxerStream); let demuxer = demuxerStream.demuxer({ iformat: iformat, options: { sample_rate: 48000, channels: 2, packetsize: 1024 } }); ``` -------------------------------- ### Pipe Muxer Stream to File Source: https://github.com/streampunk/beamcoder/blob/master/README.md Pipe the created muxer stream to a file write stream to save the muxed data. ```javascript muxerStream.pipe(fs.createWriteStream('test.wav')); ``` -------------------------------- ### Write Muxer Header Source: https://github.com/streampunk/beamcoder/blob/master/README.md Call the asynchronous writeHeader() method to write the header to the file. This initializes internal data structures. Options can be passed to set private data fields. ```javascript await muxer.writeHeader(); ``` ```javascript await muxer.writeHeader({ options: { // Private class options write_peak: 'on', // Write Peak Envelope chunk - enum of 'off', 'on', 'only'. peak_format: 2, // The format of the peak envelope data (1: uint8, 2: uint16). write_bext: false // Write BEXT chunk. } }); ``` -------------------------------- ### JSON Serialization and Deserialization Source: https://github.com/streampunk/beamcoder/blob/master/README.md Shows how to convert Beamcoder objects to JSON strings using JSON.stringify and parse JSON strings back into objects using the factory method. Large binary data is not included in JSON. ```javascript let p = beamcoder.packet({ pts: 654321, stream_index: 3, data: Buffer.alloc(65536), duration: 1920}); console.log(JSON.stringify(p, null, 2)); /* { "type": "Packet", // Always includes the type name "pts": 654321, // pts is not the default value "size": 65536, // Size is carried as if a "Content-Length: " HTTP header "stream_index": 3, // stream_index always included "duration": 1920 } */ console.log(beamcoder.packet(JSON.stringify(p))); /* { type: 'Packet', pts: 654321, dts: null, data: null, // Large binary data has to be carried separately size: 0, stream_index: 3, flags: { KEY: false, CORRUPT: false, DISCARD: false, TRUSTED: false, DISPOSABLE: false }, side_data: null, // Side data values are serialized to JSON arrays duration: 1920, pos: -1 } */ ``` -------------------------------- ### Create Muxer Stream from Demuxer Stream Source: https://github.com/streampunk/beamcoder/blob/master/README.md Create a new muxer stream by directly referencing a stream from an existing demuxer. This is useful for transmuxing, where content is rewrapped without transcoding. ```javascript let muxAudioStream = muxer.newStream(demuxer.streams[1]); ``` -------------------------------- ### Create a Beamcoder Packet Manually Source: https://github.com/streampunk/beamcoder/blob/master/README.md Packets can be created directly without reading from a demuxer, by providing PTS, DTS, and data. Packet data buffers are shared between C and Javascript and can be modified directly. ```javascript beamcoder.packet({ pts: 43210, dts: 43210, data: Buffer.from(...) }); ``` -------------------------------- ### Query Available Decoders Source: https://github.com/streampunk/beamcoder/blob/master/README.md Retrieves an object containing all available decoders. The keys are decoder names, and values are objects with codec details like type, name, and capabilities. ```javascript let decs = beamcoder.decoders(); ``` -------------------------------- ### Guess Output Format Source: https://github.com/streampunk/beamcoder/blob/master/README.md Determine the appropriate output format object based on a filename, format name, or MIME type. This helps in automatically selecting the correct muxer settings. ```javascript of = beamcoder.guessFormat('mpegts'); // Finds the output format named 'mpegts' ``` ```javascript of = beamcoder.guessFormat('image/png'); // Output format for PNG image data ``` ```javascript of = beamcoder.guessFormat('fred.jpeg'); // Output format for '.jpeg' file extension ``` -------------------------------- ### Add Audio Stream to Muxer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Create a new audio stream for the muxer, specifying codec, time base, and detailed codec parameters. Ensure all necessary parameters like sample rate, channels, and format are set. ```javascript let muxer = beamcoder.muxer({ filename: 'test.wav' }); // Filename set muxer's 'url' property let stream = muxer.newStream({ name: 'pcm_s16le', time_base: [1, 48000 ], interleaved: false }); // Set to false for manual interleaving, true for automatic Object.assign(stream.codecpar, { // Object.assign copies over all properties channels: 2, sample_rate: 48000, format: 's16', channel_layout: 'stereo', block_align: 4, // Should be set for WAV bits_per_coded_sample: 16, bit_rate: 48000*4 }); ``` -------------------------------- ### Create Decoder with Specific Dimensions Source: https://github.com/streampunk/beamcoder/blob/master/README.md When initializing a decoder, you can provide specific properties like width and height, which will override default values. Note that some decoder properties might only become available after processing initial packets. ```javascript let decoder = beamcoder.decoder({ name: 'h264', width: 1920, height: 1080 }); ``` -------------------------------- ### Create Packet Source: https://github.com/streampunk/beamcoder/blob/master/README.md Create a packet object for decoding, specifying presentation timestamp (pts), decoding timestamp (dts), and data. ```APIDOC ## Create Packet ### Description Packets for decoding can be created without reading them from a demuxer. ### Method `beamcoder.packet(options)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **pts** (number) - Presentation timestamp. - **dts** (number) - Decoding timestamp. - **data** (Buffer) - The packet data. ### Request Example ```javascript let packet = beamcoder.packet({ pts: 43210, dts: 43210, data: Buffer.from('...') }); ``` ### Response #### Success Response (200) - **packet** (object) - A newly created packet object. ``` -------------------------------- ### Seek with Backward and Any Flags Source: https://github.com/streampunk/beamcoder/blob/master/README.md Advanced seeking options. `backward: false` searches for the nearest keyframe after the timestamp, while `any: true` allows seeking to both key and non-key frames. ```javascript await demuxer.seek({ frame: 31, stream_index: 0, backward: false, any: true}); ``` -------------------------------- ### Write Media Packets or Frames Source: https://github.com/streampunk/beamcoder/blob/master/README.md Send media data using the writeFrame() method. It accepts a packet directly, or an options object with either a 'packet' or 'frame' and 'stream_index'. Ensure the 'interleaved' property is set correctly before calling. ```javascript await muxer.writeFrame(packet); ``` ```javascript await muxer.writeFrame({ packet: packet }); ``` ```javascript await muxer.writeFrame({ frame: frame, stream_index: 0 }); ``` -------------------------------- ### Access and Modify JavaScript Properties Source: https://github.com/streampunk/beamcoder/blob/master/README.md Demonstrates how to read and write properties of Beamcoder objects using dot notation and array-style access. Note that not all properties are writable, and some are set by libav*. ```javascript let q_pts = q.pts; // Current value of pts for q, q_pts= 10 let same = q['pts'] === q.pts; // true ... the current value of pts for q = 10 q.pts = 12; // Set the value pts for q to 12 q.data = Buffer.from('Text data for this packet.'); // Set packet data ``` -------------------------------- ### List Available Demuxers Source: https://github.com/streampunk/beamcoder/blob/master/README.md Retrieves a list of all available demuxer input formats supported by Beamcoder. The output is an object where keys are demuxer names and values describe the input format. ```javascript let dms = beamcoder.demuxers(); ``` -------------------------------- ### Create Encoder by Codec ID Source: https://github.com/streampunk/beamcoder/blob/master/README.md Instantiate an encoder using a specific codec identifier, such as for 'aac' audio (codec_id: 86018). ```javascript // Create an encoder by codec identifier - in this case for 'aac' audio let a_encoder = beamcoder.encoder({ codec_id: 86018 }); ``` -------------------------------- ### Set FFmpeg Logging Callback Source: https://github.com/streampunk/beamcoder/blob/master/README.md Use this to bypass the default FFmpeg logger and direct all messages to a custom handler, such as console.log. Ensure the callback function accepts a single message argument. ```javascript beamcoder.setLoggingCallback(msg => console.log(msg)) ``` -------------------------------- ### Create Video Frame with Beamcoder Source: https://github.com/streampunk/beamcoder/blob/master/README.md Use beamcoder.frame to create video frames. Specify properties like pts, width, height, format, and data. The data is typically planar, with separate buffers for color components or audio channels. ```javascript beamcoder.frame({ pts: 43210, width: 1920, height: 1920, format: 'yuv420p', data: [ Buffer.from(...plane_1...), Buffer.from(...plane_2...), ... ] }); ``` -------------------------------- ### Create Demuxer Stream with Highwater Mark Source: https://github.com/streampunk/beamcoder/blob/master/README.md Creates a Node.js Writable stream interface for a demuxer with a specified highwater mark. Use this when you need to control the buffer size for streaming data into the demuxer. ```javascript let demuxerStream = beamcoder.demuxerStream({ highwaterMark: 65536 }); ``` -------------------------------- ### List Available Beamcoder Filters Source: https://github.com/streampunk/beamcoder/blob/master/README.md Call this function to retrieve a list of all available filters in Beamcoder. The output is an object where keys are filter names and values contain filter details. ```javascript let filters = beamcoder.filters(); ``` ```javascript { abench: { name: 'abench', description: 'Benchmark part of a filtergraph.', inputs: [ [Object] ], outputs: [ [Object] ], priv_class: { type: 'Class', class_name: 'abench', options: [Object] }, flags: { DYNAMIC_INPUTS: false, DYNAMIC_OUTPUTS: false, SLICE_THREADS: false, SUPPORT_TIMELINE_GENERIC: false, SUPPORT_TIMELINE_INTERNAL: false } }, acompressor: { name: 'acompressor', description: 'Audio compressor.', inputs: [ [Object] ], outputs: [ [Object] ], priv_class: { type: 'Class', class_name: 'acompressor', options: [Object] }, flags: { DYNAMIC_INPUTS: false, DYNAMIC_OUTPUTS: false, SLICE_THREADS: false, SUPPORT_TIMELINE_GENERIC: false, SUPPORT_TIMELINE_INTERNAL: false } }, /* ... */ } ``` -------------------------------- ### Create Demuxer from Stream Source: https://github.com/streampunk/beamcoder/blob/master/README.md Creates a demuxer instance by consuming data from a demuxer stream. This function returns a promise that resolves when sufficient format details have been determined from the source data. The process may wait indefinitely if not enough data is provided. ```javascript let demuxer = await demuxerStream.demuxer(); ``` -------------------------------- ### List Available Encoders Source: https://github.com/streampunk/beamcoder/blob/master/README.md Retrieve a list of all available encoders using the beamcoder.encoders() method. The output is structured similarly to decoders. ```javascript let encs = beamcoder.encoders(); ``` ```javascript // Find all encoders that can encode H.264 Object.values(encs).filter(x => x.id === 27).map(x => x.name); [ 'libx264', 'libx264rgb', 'h264_amf', 'h264_nvenc', 'h264_qsv', 'nvenc', 'nvenc_h264' ] etc.. ``` -------------------------------- ### Seek by File Position in Demuxer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Seeks to a specific byte offset within the file. This allows for precise positioning if the file structure or byte offsets are known. ```javascript await demuxer.seek({ pos: 11169836 }); ``` -------------------------------- ### List All Audio Decoders Source: https://github.com/streampunk/beamcoder/blob/master/README.md Filters the list of all decoders to retrieve only those with a 'codec_type' of 'audio'. This is useful for enumerating all available audio decoding capabilities. ```javascript Object.values(decs).filter(x => x.codec_type === 'audio').map(x => x.name); [ 'comfortnoise', 'dvaudio', '8svx_exp', '8svx_fib', 's302m', 'sdx2_dpcm', 'aac', 'aac_fixed', 'aac_latm' /* ... */ ] ``` -------------------------------- ### Codec Parameters from Demuxer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Extract codec parameters from a demuxer's stream to configure a decoder. Ensure to use `extractParams()` to create a copy when reusing parameters for an encoder to prevent side effects. ```javascript let demuxer = await beamcoder.demuxer('file:bbb_1080p_c.ts'); let videoParams = demuxer.streams.find(x => x.codecpar.codec_type === 'video').codecpar; // Set up a decoder using demuxer stream parameters let decoder = beamcoder.decoder({ params: videoParams }); let encParams = decoder.extractParams(); // Make a copy of the decoder paramerers encParams.name = 'h264'; // Change the codec but keep the other parameters ... let encoder = beamcoder.encoder({ params: videoParams }); // ... to set up an encoder let muxer = beamcoder.muxer({ filename: 'file:bbb.mp4' }); let stream = muxer.newStream({ name: encParams.name, time_base: [1, 90000], codecpar: encParams }); ``` -------------------------------- ### Pipe Source Data to Demuxer Stream Source: https://github.com/streampunk/beamcoder/blob/master/README.md Pipes data from a source stream, such as a file, into the Beamcoder demuxer stream. Ensure the source stream is correctly created before piping. ```javascript fs.createReadStream('file:media/bbb_1080p_ts').pipe(demuxerStream); ``` -------------------------------- ### Seek by Elapsed Time in Demuxer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Seeks to a position based on elapsed time from the beginning of the primary stream. This is useful for navigating to a specific point in time within the media. ```javascript await demuxer.seek({ time: 58.176 }); ``` -------------------------------- ### Decode Multiple Packets at Once Source: https://github.com/streampunk/beamcoder/blob/master/README.md The `decode` method can accept multiple packets simultaneously, either as an array or as a list of arguments, to improve processing efficiency. ```javascript let dec_result = await decoder.decode([packet1, packet2, packet3 /* ... */ ]); ``` ```javascript let dec_result = await decoder.decode(packet1, packet2, packet3 /* ... */ ); ``` -------------------------------- ### Read Data Packets from Demuxer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Reads data packets from a demuxer. Use this in a loop to process all packets. The loop terminates when `read()` returns null, indicating the end of the file. Check `packet.stream_index` to identify the stream type. ```javascript let wavDemuxer = await beamcoder.demuxer('file:my_audio.wav'); let packet = {}; while (packet != null) { packet = await wavDemuxer.read(); if (packet && wavDemuxer.streams[packet.stream_index].codecpar.codec_type === 'video') { // Do something with the image data } } ``` -------------------------------- ### Inspect Demuxer Information Source: https://github.com/streampunk/beamcoder/blob/master/README.md Filters the list of demuxers to find information about a specific format, such as '.mp4'. This helps in understanding the properties and capabilities of a demuxer. ```javascript Object.values(dms).filter(x => x.extensions.indexOf('mp4') >= 0); ``` -------------------------------- ### Seeking in a File Source: https://github.com/streampunk/beamcoder/blob/master/README.md Seeks to a specific frame in a file by time reference, frame count, or file position. The seek operation can be configured with various options and supports seeking backward or to any frame. ```APIDOC ## seek(options) ### Description Seeks to a specific frame in a file by time reference, frame count, or file position. The seek operation can be configured with various options and supports seeking backward or to any frame. All successful seek calls resolve to a `null` value, or reject if the kind of seek is not supported or an error occurs. ### Method `seek(options)` ### Parameters #### Options Object - **stream_index** (number) - Optional - The stream index to seek within. - **timestamp** (number) - Optional - The presentation timestamp to seek to, measured in the stream's timebase. - **time** (number) - Optional - The elapsed time in seconds from the beginning of the primary stream to seek to. - **pos** (number) - Optional - The byte offset position into the file to seek to. - **frame** (number) - Optional - The frame number to seek to within a given stream. - **backward** (boolean) - Optional - If true, finds the nearest key frame before the timestamp. If false, finds the nearest keyframe after the timestamp. Defaults to true. - **any** (boolean) - Optional - If true, enables seeking to both key and non-key frames. Defaults to false. ### Request Example (Seek by timestamp) ```javascript await demuxer.seek({ stream_index: 0, timestamp: 2792448 }); ``` ### Request Example (Seek by time) ```javascript await demuxer.seek({ time: 58.176 }); ``` ### Request Example (Seek by position) ```javascript await demuxer.seek({ pos: 11169836 }); ``` ### Request Example (Seek by frame) ```javascript await demuxer.seek({ frame: 42, stream_index: 0}); ``` ### Request Example (Seek with backward and any flags) ```javascript await demuxer.seek({ frame: 31, stream_index: 0, backward: false, any: true}); ``` ### Response #### Success Response - **null** - Indicates a successful seek operation. #### Error Response - **Error** - Rejects with an error message if the seek operation is not supported or an error occurs. ``` -------------------------------- ### Set Encoder Private Data Source: https://github.com/streampunk/beamcoder/blob/master/README.md Configure encoder-specific private data by assigning a complete object to the `priv_data` property. Partial updates are not supported. ```javascript v_encoder.priv_data = { preset: 'slow' }; // Only the included properties change ``` -------------------------------- ### Force Close Muxer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Use forceClose() to abandon the muxing process and forcibly close the file or stream without completion. This will leave the output in an incomplete and invalid state. ```javascript muxer.forceClose(); ``` -------------------------------- ### Flush Decoder for Remaining Frames Source: https://github.com/streampunk/beamcoder/blob/master/README.md After all packets have been sent to the decoder, call the asynchronous `flush()` method to retrieve any remaining buffered frames. This operation should only be called once, and the decoder should not be used for further decoding afterwards. ```javascript let flush_result = await decoder.flush(); // flush_result.frames - array of any remaining frames to be decoded // flush_result.total_time - microseconds taken to execute the flush operation ``` -------------------------------- ### Inspect Specific Decoder Source: https://github.com/streampunk/beamcoder/blob/master/README.md Accesses details for a specific decoder by its name. This provides information about the codec, such as its long name and type. ```javascript decs['h264']; { type: 'Codec', name: 'h264', long_name: 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10', codec_type: 'video', id: 27, /* ... */ } ``` -------------------------------- ### Reading Data Packets Source: https://github.com/streampunk/beamcoder/blob/master/README.md Reads the next blob of data from the demuxer. This method is asynchronous and returns a promise that resolves to a Packet object or null at the end of the file. It rejects with an error message if an error occurs. ```APIDOC ## read() ### Description Reads the next blob of data from the demuxer. This method is asynchronous and returns a promise that resolves to a Packet object or null at the end of the file. It rejects with an error message if an error occurs. ### Method `read()` ### Parameters This method takes no arguments. ### Response #### Success Response - **Packet** (object) - An object containing packet data, including pts, dts, data, size, stream_index, flags, duration, and pos. - **null** - Indicates the end of the file. #### Response Example (Packet) ```json { "type": "Packet", "pts": 2792448, "dts": 2792448, "data": , "size": 4160, "stream_index": 0, "flags": { "KEY": true, "CORRUPT": false, "DISCARD": false, "TRUSTED": false, "DISPOSABLE": false }, "duration": 1024, "pos": 11169836 } ``` ``` -------------------------------- ### Find Decoders by Long Name Source: https://github.com/streampunk/beamcoder/blob/master/README.md Filters decoders based on a substring match in their 'long_name' property. This allows searching for decoders that support a specific media format, like MP3. ```javascript Object.values(decs) .filter(x => x.long_name.indexOf('MP3') >= 0) .map(x => ({ name: x.name, long_name: x.long_name })); [ { name: 'mp3float', long_name: 'MP3 (MPEG audio layer 3)' }, { name: 'mp3', long_name: 'MP3 (MPEG audio layer 3)' }, { name: 'mp3adufloat', long_name: 'ADU (Application Data Unit) MP3 (MPEG audio layer 3)' }, { name: 'mp3adu', long_name: 'ADU (Application Data Unit) MP3 (MPEG audio layer 3)' }, { name: 'mp3on4float', long_name: 'MP3onMP4' }, { name: 'mp3on4', long_name: 'MP3onMP4' } ] ``` -------------------------------- ### Flush Encoder with Beamcoder Source: https://github.com/streampunk/beamcoder/blob/master/README.md Call the asynchronous encoder.flush() method after all frames have been passed to the encoder. This ensures any remaining packets are completed and provided. Do not use the encoder after flushing. ```javascript let flush_result = await encoder.flush(); // flush_result.frames - array of any remaining packets to be encoded // flush_result.total_time - microseconds taken to execute the flushing process ``` -------------------------------- ### Flush Decoder Source: https://github.com/streampunk/beamcoder/blob/master/README.md Asynchronously flush the decoder to retrieve any remaining buffered frames after all packets have been processed. ```APIDOC ## Flush Decoder ### Description Once all packets have been passed to the decoder, it is necessary to call its asynchronous `flush()` method. If any frames are yet to be delivered by the decoder, they will be provided in the resolved value. ### Method `await decoder.flush()` ### Parameters None ### Request Example ```javascript let flush_result = await decoder.flush(); // flush_result.frames - array of any remaining frames to be decoded // flush_result.total_time - microseconds taken to execute the flush operation ``` ### Response #### Success Response (200) - **frames** (Array) - An array of any remaining frames to be decoded. - **total_time** (number) - The time in microseconds the flush operation took to execute. ``` -------------------------------- ### Encode Multiple Frames Source: https://github.com/streampunk/beamcoder/blob/master/README.md Encode multiple frames at once by passing an array of frames or a sequence of frames as arguments to the encode method. ```javascript enc_result = await encoder.encode([ frame_1, frame_2, ... ]); enc_result = await encoder.encode(frame_1, frame_2, ... ); ``` -------------------------------- ### Decode Encoded Data Packets Source: https://github.com/streampunk/beamcoder/blob/master/README.md Use the asynchronous `decode` method to process encoded packets and generate uncompressed frames. Decoders may buffer packets and produce multiple frames per packet, especially for long-GOP formats. The result includes decoded frames and the time taken for the operation. ```javascript let packet = demuxer.read(); while (packet != null) { let dec_result = await decoder.decode(packet); // dec_result.frames - possibly empty array of frames for further processing // dec_result.total_time - microseconds that the operation took to complete // Get the next packet, e.g. packet = demuxer.read(); } ``` -------------------------------- ### Filter Uncompressed Frames Source: https://github.com/streampunk/beamcoder/blob/master/README.md Use the filter method to process uncompressed frames. Pass an array of input objects, each with a name and frames property. The name must match the filterSpec input parameter. ```javascript let filtFrames = await filterer.filter([ { name: 'in0:v', frames: frames0 }, { name: 'in1:v', frames: frames1 }, ]); ``` -------------------------------- ### Find Decoders by Codec ID Source: https://github.com/streampunk/beamcoder/blob/master/README.md Filters the list of all decoders to find those associated with a specific codec ID. This is useful for identifying all variants, including hardware-accelerated ones, that can decode a particular format. ```javascript Object.values(decs).filter(x => x.id === 27).map(x => x.name); [ 'h264', 'h264_qsv', 'h264_cuvid' ] // Note: h264_qsv and h264_cuvid are wrappers to hardware-accelerated decoders // Appearance in the list does not imply that the codec is supported by current hardware. ``` -------------------------------- ### Write Muxer Trailer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Call writeTrailer() after all packets and frames have been sent to finalize the file or stream. This method also closes the file or stream. ```javascript await muxer.writeTrailer(); ``` -------------------------------- ### Seek by Frame Number in Demuxer Source: https://github.com/streampunk/beamcoder/blob/master/README.md Seeks to a specific frame number within a given stream. This is useful when frame-based navigation is required. ```javascript await demuxer.seek({ frame: 42, stream_index: 0}); ```