### Project Setup Source: https://github.com/seydx/node-av/blob/main/CONTRIBUTING.md Clone the repository, install dependencies, and build the project. Ensure Node.js 22.18+, Python 3.x, and pkg-config are installed. ```bash git clone https://github.com/YOUR_USERNAME/node-av.git cd node-av git submodule update --init --recursive npm install npm run build ``` -------------------------------- ### Capture Screen Example Source: https://github.com/seydx/node-av/blob/main/_autodocs/README.md This example shows how to capture screen content using the DeviceAPI.openScreen method, with options for frame rate. ```typescript const screen = await DeviceAPI.openScreen({ frameRate: 30 }); // Process screen stream ``` -------------------------------- ### Install node-av with npm Source: https://github.com/seydx/node-av/blob/main/README.md Install the node-av package using npm. This is the first step before using any of the library's features. ```bash npm install node-av ``` -------------------------------- ### Simple Transcode Pipeline Example Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/pipeline.md Demonstrates a basic video transcoding process using the pipeline function. This example shows how to set up input, decoder, encoder, and output, then execute and monitor the pipeline's progress. ```typescript import { pipeline, Demuxer, Decoder, Encoder, Muxer } from 'node-av/api'; import { FF_ENCODER_LIBX264 } from 'node-av/constants'; // Simple transcode pipeline const input = await Demuxer.open('input.mp4'); const decoder = await Decoder.create(input.video()!); const encoder = await Encoder.create(FF_ENCODER_LIBX264, { bitrate: '5M', decoder }); const output = await Muxer.open('output.mp4', { input }); const videoIndex = output.addStream(encoder, { inputStream: input.video() }); // Execute pipeline const control = pipeline(input, decoder, encoder, output); // Monitor progress const progressInterval = setInterval(() => { console.log(`${control.progress.frames} frames, ${control.progress.fps.toFixed(1)} fps`); }, 1000); // Wait for completion await control.completion; clearInterval(progressInterval); ``` -------------------------------- ### Input Setup for Media Files Source: https://github.com/seydx/node-av/blob/main/_autodocs/types.md Opens a media file for reading and selects the video stream. Ensure the file exists and is accessible. ```typescript const input = await Demuxer.open('file.mp4'); const stream = input.video(); ``` -------------------------------- ### Create Hardware Context Source: https://github.com/seydx/node-av/blob/main/_autodocs/configuration.md Examples of creating hardware contexts, either by auto-detection with preferred types or by specifying a particular device and type. ```typescript // Auto-detect with preference const hw = HardwareContext.auto({ prefer: [AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_VIDEOTOOLBOX] }); // Specific device const vaapi = HardwareContext.create( AV_HWDEVICE_TYPE_VAAPI, '/dev/dri/renderD128' ); ``` -------------------------------- ### Use Hardware Acceleration Example Source: https://github.com/seydx/node-av/blob/main/_autodocs/README.md This snippet demonstrates how to utilize hardware acceleration for decoding and encoding by creating a HardwareContext and passing it to the Decoder and Encoder. ```typescript const hw = HardwareContext.auto(); const decoder = await Decoder.create(stream, { hardware: hw }); const encoder = await Encoder.create(codec, { hardware: hw }); ``` -------------------------------- ### Install Cross-Platform Binaries Source: https://github.com/seydx/node-av/blob/main/README.md Install specific platform binaries for cross-compilation targets. Use npm's standard --os and --cpu flags to specify the target platform. ```bash npm install --os=win32 --cpu=x64 ``` -------------------------------- ### Initialize Scaler with Options Source: https://github.com/seydx/node-av/blob/main/_autodocs/configuration.md Example of initializing a Scaler with specific hardware context, higher quality bicubic scaling flags, and an increased cache size. ```typescript const scaler = new Scaler({ hardware: hw, flags: SWS_BICUBIC, // Higher quality maxCacheSize: 32 }); ``` -------------------------------- ### Create Encoder with Options Source: https://github.com/seydx/node-av/blob/main/_autodocs/configuration.md Example demonstrating how to create an encoder instance using specific configuration options. This includes setting bitrate limits, GOP size, and encoding preset. ```typescript const encoder = await Encoder.create(FF_ENCODER_LIBX264, { bitrate: '5M', minRate: '1M', maxRate: '10M', gopSize: 60, maxBFrames: 3, preset: 'medium', hardware: hw }); ``` -------------------------------- ### Encoding Setup with Specific Encoder Source: https://github.com/seydx/node-av/blob/main/_autodocs/types.md Initializes an encoder, such as libx264, with specified bitrate and a linked decoder. The decoder reference is copied from the source. ```typescript const encoder = await Encoder.create(FF_ENCODER_LIBX264, { bitrate: '5M', decoder // Copy from source }); ``` -------------------------------- ### Generate Thumbnails Example Source: https://github.com/seydx/node-av/blob/main/_autodocs/README.md This example shows how to generate a JPEG thumbnail from a video frame using the Scaler class, with options for resizing and quality. ```typescript const scaler = new Scaler(); const thumb = await scaler.jpeg(frame, { resize: { width: 320, height: 240 }, quality: 80 }); ``` -------------------------------- ### Create Decoder Instance Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/decoder.md Demonstrates creating a Decoder instance for a given stream. Includes examples for basic decoding, hardware acceleration, rescaling video, resampling audio, and configuring error handling. ```typescript import { Decoder, Demuxer, HardwareContext } from 'node-av/api'; import { AV_PIX_FMT_YUV420P } from 'node-av/constants'; // Basic decoding const demuxer = await Demuxer.open('input.mp4'); const videoStream = demuxer.video(); const decoder = await Decoder.create(videoStream); // With hardware acceleration const hw = HardwareContext.auto(); const hwDecoder = await Decoder.create(videoStream, { hardware: hw }); // With rescaling to fixed format const rescaledDecoder = await Decoder.create(videoStream, { rescale: { width: 1920, height: 1080, pixelFormat: AV_PIX_FMT_YUV420P } }); // Audio with resampling const audioStream = demuxer.audio(); const audioDecoder = await Decoder.create(audioStream, { resample: { sampleRate: 48000, channels: 2 } }); // With frame-dropping on error const robustDecoder = await Decoder.create(videoStream, { exitOnError: false }); ``` -------------------------------- ### Output Setup for Media Files Source: https://github.com/seydx/node-av/blob/main/_autodocs/types.md Opens an output file for writing and adds a stream to the muxer, using metadata from the input and configuration from the encoder. The input metadata is copied. ```typescript const output = await Muxer.open('output.mp4', { input // Copy metadata }); const index = output.addStream(encoder); ``` -------------------------------- ### Open Muxer with Options Source: https://github.com/seydx/node-av/blob/main/_autodocs/configuration.md Example of opening a muxer with specific format and format-specific options. Useful for controlling output file characteristics like faststart. ```typescript const muxer = await Muxer.open('output.mp4', { input: demuxer, format: 'mp4', bitrate: 5000000, maxDelay: 5000, seekable: true, formatOptions: { 'movflags': 'faststart' } }); ``` -------------------------------- ### Install Hardware Acceleration Packages Source: https://github.com/seydx/node-av/blob/main/README.md Install necessary packages for hardware-accelerated video processing with Intel GPUs on Linux. Ensure your OS version meets the minimum requirements (Ubuntu 24.04+ or Debian 13+). ```bash sudo apt install libmfx-gen1.2 mesa-va-drivers mesa-vulkan-drivers libva2 libva-drm2 vainfo libvulkan1 vulkan-tools ``` -------------------------------- ### Analyze Media Example Source: https://github.com/seydx/node-av/blob/main/_autodocs/README.md This snippet demonstrates how to analyze media files to retrieve information such as duration and video codec using the probe function. ```typescript const info = await probe('file.mp4'); console.log(`Duration: ${info.duration}s, Video: ${info.video?.codec}`); ``` -------------------------------- ### Transcode Video Example Source: https://github.com/seydx/node-av/blob/main/_autodocs/README.md This snippet demonstrates the basic steps for transcoding a video file using Demuxer, Decoder, Encoder, and Muxer. Refer to the respective references for detailed options. ```typescript const input = await Demuxer.open('input.mp4'); const decoder = await Decoder.create(input.video()!); const encoder = await Encoder.create(FF_ENCODER_LIBX265, { decoder }); const output = await Muxer.open('output.mkv', { input }); // ... write packets ``` -------------------------------- ### Create Decoder with Custom Options Source: https://github.com/seydx/node-av/blob/main/_autodocs/configuration.md Example of creating a decoder with error logging enabled, GPU acceleration, a forced framerate, and specific video rescaling. ```typescript const decoder = await Decoder.create(stream, { exitOnError: false, // Log errors but continue hardware: hw, // GPU acceleration forcedFramerate: { num: 30, den: 1 }, rescale: { width: 1920, height: 1080, pixelFormat: AV_PIX_FMT_YUV420P } }); ``` -------------------------------- ### Decoding Setup with Hardware Acceleration Source: https://github.com/seydx/node-av/blob/main/_autodocs/types.md Creates a decoder instance for a given stream, with options for hardware acceleration and pixel format rescaling. Requires a valid stream and hardware context. ```typescript const decoder = await Decoder.create(stream, { hardware: hw, rescale: { pixelFormat: AV_PIX_FMT_YUV420P } }); ``` -------------------------------- ### Create Filter with Options Source: https://github.com/seydx/node-av/blob/main/_autodocs/configuration.md Example of creating a video filter with specified scaling and framerate, enabling hardware acceleration, and forcing a constant framerate of 30 FPS. ```typescript const filter = await FilterAPI.create('scale=1920:1080,fps=30', { threads: 4, hardware: hw, cfr: true, framerate: { num: 30, den: 1 } }); ``` -------------------------------- ### Create Encoder and Encode Frames Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/encoder.md Example demonstrating how to create an encoder and iterate through encoded packets from a decoder's frame generator. ```typescript const encoder = await Encoder.create(FF_ENCODER_LIBX264, { bitrate: '5M' }); const decoderFrameGenerator = decoder.frames(demuxer.packets(videoIndex)); for await (using packet of encoder.packets(decoderFrameGenerator)) { console.log(`Encoded packet: ${packet.size} bytes, key: ${packet.isKeyframe}`); } ``` -------------------------------- ### Open Demuxer with Custom Options Source: https://github.com/seydx/node-av/blob/main/_autodocs/configuration.md Example of opening a demuxer with specific configurations like larger buffer size, TCP transport for RTSP, and skipping to the first keyframe. ```typescript const demuxer = await Demuxer.open('input.mp4', { bufferSize: 131072, // Larger buffer for network streams skipStreamInfo: false, startWithKeyframe: true, dtsDeltaThreshold: 5, formatOptions: { 'rtsp_transport': 'tcp' // Use TCP for RTSP } }); ``` -------------------------------- ### Pipeline Setup for Media Processing Source: https://github.com/seydx/node-av/blob/main/_autodocs/types.md Constructs a processing pipeline connecting input, decoder, encoder, and output components. Awaits the completion of the pipeline. ```typescript const control = pipeline(input, decoder, encoder, output); await control.completion; ``` -------------------------------- ### Create VAAPI Hardware Context Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/hardware-context.md Manually create a VAAPI hardware context on Linux by specifying the device path. Ensure libva is installed and the render node is accessible. ```typescript // VAAPI const vaapi = HardwareContext.create( AV_HWDEVICE_TYPE_VAAPI, '/dev/dri/renderD128' ); ``` -------------------------------- ### Verify Vulkan Support Source: https://github.com/seydx/node-av/blob/main/README.md Check if Vulkan is correctly configured and supported by your Intel GPU. This command should display information about your Vulkan installation. ```bash vulkaninfo ``` -------------------------------- ### Create Encoder with Constant Bitrate Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/encoder.md Example of creating an encoder with a fixed constant bitrate of 5 Mbps. Ensure the codec is correctly specified. ```typescript const encoder = await Encoder.create(codec, { bitrate: '5M' // Constant 5 Mbps }); ``` -------------------------------- ### Write Interleaved Packets with Muxer Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/muxer.md This example shows how to write video and audio packets to the muxer, allowing the muxer to handle the interleaving and ordering. Ensure streams are added and encoders are set up prior to writing packets. ```typescript const videoStreamIndex = muxer.addStream(videoEncoder); const audioStreamIndex = muxer.addStream(audioEncoder); const audioGenerator = audioDecoder.frames(audioDemuxer.packets(audioStream.index)); const audioPacketGen = audioEncoder.packets(audioGenerator); // Write interleaved packets (muxer handles ordering) for await (using videoPacket of videoEncoder.packets(videoFrames)) { await muxer.writePacket(videoPacket, videoStreamIndex); } for await (using audioPacket of audioPacketGen) { await muxer.writePacket(audioPacket, audioStreamIndex); } ``` -------------------------------- ### Open Default Camera Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/device-api.md Opens the default camera for video capture. This is the simplest way to start capturing video without specifying any options. ```typescript import { DeviceAPI } from 'node-av/api'; // Default camera const camera = await DeviceAPI.openCamera(); ``` -------------------------------- ### Initialize and Start WebRTC Stream Source: https://github.com/seydx/node-av/blob/main/examples/browser/webrtc/index.html Initiates the WebRTC stream by creating a PeerConnection, establishing a WebSocket connection for signaling, and sending an SDP offer. Handles different streaming modes (device or URL). ```javascript async function startStream() { console.log('Starting WebRTC stream...'); updateStatus(false, 'Connecting...'); // Connect to WebSocket server pc = await createPC(); ws = new WebSocket('ws://localhost:8081'); ws.addEventListener('open', () => { console.log('WebSocket connected'); updateStatus(true, 'Connected'); // Connection state pc.onconnectionstatechange = () => { console.log('Connection state:', pc.connectionState); connectionStateEl.textContent = pc.connectionState; updateStatus(pc.connectionState === 'connected', pc.connectionState); }; // ICE connection state pc.oniceconnectionstatechange = () => { console.log('ICE state:', pc.iceConnectionState); iceStateEl.textContent = pc.iceConnectionState; }; pc.onicecandidate = (ev) => { if (!ev.candidate) return; console.log('Sending ICE candidate to server', ev.candidate.candidate); const msg = { type: 'webrtc/candidate', value: ev.candidate.candidate }; ws.send(JSON.stringify(msg)); }; pc.createOffer() .then((offer) => pc.setLocalDescription(offer)) .then(() => { console.log('Negotiating...'); updateStatus(true, 'Negotiating...'); const offerMsg = { type: 'webrtc/offer', value: pc.localDescription.sdp, }; if (currentMode === 'device') { const deviceType = deviceTypeSelect.value; const device = deviceSelect.value; console.log('Sending SDP offer with device:', deviceType, device); offerMsg.source = 'device'; offerMsg.deviceType = deviceType; offerMsg.device = device; offerMsg.framerate = 30; if (deviceType === 'screen') { offerMsg.screenIndex = device; } if (deviceType === 'device') { offerMsg.audioDevice = audioDeviceSelect.value; } } else { const url = urlInput.value.trim(); if (!url) { console.error('No URL provided'); updateStatus(false, 'No URL provided'); return; } console.log('Sending SDP offer to server for URL:', url); offerMsg.url = url; } ws.send(JSON.stringify(offerMsg)); }); }); ws.addEventListener('message', (ev) => { const msg = JSON.parse(ev.data); if (msg.type === 'webrtc/candidate') { console.log('Received ICE candidate from server', msg.value); pc.addIceCandidate({ candidate: msg.value, sdpMid: '0' }); } else if (msg.type === 'webrtc/answer') { console.log('Received SDP answer from server', msg.value); pc.setRemoteDescription({ type: 'answer', sdp: msg.value }); } else if (msg.type === 'error') { console.error('Error from server:', msg.value); updateStatus(false, 'Error: ' + msg.value); stopStream(); } else if (msg.type === 'end') { console.log('Stream ended by server'); updateStatus(false, 'Stream ended'); stopStream(); } }); ws.addEventListener('close', () => { console.log('WebSocket disconnected'); stopStream(); }); // Hide play overlay, enable stop button playOverlay.classList.add('hidden'); stopButton.disabled = false; } ``` -------------------------------- ### FFmpegError Handling Example Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/demuxer.md Demonstrates how to catch and handle FFmpegError exceptions, checking for specific error codes like ENOENT (file not found) and EACCES (permission denied). ```typescript try { const input = await Demuxer.open('missing.mp4'); } catch (error) { if (error instanceof FFmpegError) { if (error.isENOENT) { console.log('File not found'); } else if (error.isEACCES) { console.log('Permission denied'); } } } ``` -------------------------------- ### Decode Video Frames with Low-Level API Source: https://github.com/seydx/node-av/blob/main/README.md Demonstrates opening an input file, finding a video stream, setting up a decoder, and processing packets to decode frames using the low-level API. Ensure FFmpeg is correctly installed and accessible. ```typescript import { AVERROR_EOF, AVMEDIA_TYPE_VIDEO } from 'node-av/constants'; import { Codec, CodecContext, FFmpegError, FormatContext, Frame, Packet, Rational } from 'node-av/lib'; // Open input file await using ifmtCtx = new FormatContext(); let ret = await ifmtCtx.openInput('input.mp4'); FFmpegError.throwIfError(ret, 'Could not open input file'); ret = await ifmtCtx.findStreamInfo(); FFmpegError.throwIfError(ret, 'Could not find stream info'); // Find video stream const videoStreamIndex = ifmtCtx.findBestStream(AVMEDIA_TYPE_VIDEO); const videoStream = ifmtCtx.streams?.[videoStreamIndex]; if (!videoStream) { throw new Error('No video stream found'); } // Create codec const codec = Codec.findDecoder(videoStream.codecpar.codecId); if (!codec) { throw new Error('Codec not found'); } // Allocate codec context for the decoder using decoderCtx = new CodecContext(); decoderCtx.allocContext3(codec); ret = decoderCtx.parametersToContext(videoStream.codecpar); FFmpegError.throwIfError(ret, 'Could not copy codec parameters to decoder context'); // Open decoder context ret = await decoderCtx.open2(codec, null); FFmpegError.throwIfError(ret, 'Could not open codec'); // Process packets using packet = new Packet(); packet.alloc(); using frame = new Frame(); frame.alloc(); while (true) { let ret = await ifmtCtx.readFrame(packet); if (ret < 0) { break; } if (packet.streamIndex === videoStreamIndex) { // Send packet to decoder ret = await decoderCtx.sendPacket(packet); if (ret < 0 && ret !== AVERROR_EOF) { FFmpegError.throwIfError(ret, 'Error sending packet to decoder'); } // Receive decoded frames while (true) { const ret = await decoderCtx.receiveFrame(frame); if (ret === AVERROR_EOF || ret < 0) { break; } console.log(`Decoded frame ${frame.pts}, size: ${frame.width}x${frame.height}`); // Process frame data... } } packet.unref(); } ``` -------------------------------- ### Open Linux Screen Capture on Second Display Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/device-api.md Opens a screen capture session on Linux using x11grab, targeting a specific display. This example assumes the display ':1' is available. ```typescript // Linux screen on second display const screen = await DeviceAPI.openScreen({ x11grab: { display: ':1' } }); ``` -------------------------------- ### Instantiate Scaler with Options Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/scaler.md Demonstrates creating a Scaler instance with different configurations, including software scaling, hardware acceleration, and custom scaling flags. ```typescript import { Scaler, HardwareContext } from 'node-av/api'; // Software scaler const scaler = new Scaler(); // With hardware acceleration const hw = HardwareContext.auto(); const gpuScaler = new Scaler({ hardware: hw }); // Custom flags const bilinearScaler = new Scaler({ flags: SWS_BILINEAR }); ``` -------------------------------- ### Change Encoder Bitrate Mid-Stream Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/encoder.md Example of dynamically changing an encoder parameter, such as bitrate, during the encoding process, provided the codec supports it. ```typescript // Change bitrate mid-encoding (if codec supports it) await encoder.setParameter('b', 8000000); // 8 Mbps ``` -------------------------------- ### Get First Video Stream Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/demuxer.md Retrieves the first video stream from the demuxer. Check if a video stream exists before accessing its properties. ```typescript const videoStream = demuxer.video(); if (videoStream) { console.log(`Video: ${videoStream.codecpar.width}x${videoStream.codecpar.height}`); } ``` -------------------------------- ### Create QSV Hardware Context Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/hardware-context.md Manually create a QSV hardware context on Linux. This is typically used for Intel Quick Sync Video acceleration. ```typescript // QSV const qsv = HardwareContext.create(AV_HWDEVICE_TYPE_QSV); ``` -------------------------------- ### Create Hardware Context with Fallback Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/hardware-context.md Demonstrates how to create a hardware context, specifically for CUDA, and includes a fallback to software if the hardware device is not available. Always implement a software fallback for robustness. ```typescript try { const hw = HardwareContext.create(AV_HWDEVICE_TYPE_CUDA); if (!hw) { console.log('CUDA not available, falling back to software'); // Use software codec instead } } catch (error) { console.error('Hardware context error:', error); } ``` -------------------------------- ### HardwareContext.create() Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/hardware-context.md Creates a hardware acceleration context for a specified device type, optionally targeting a specific device and providing custom initialization options. ```APIDOC ## HardwareContext.create() ### Description Create a hardware context for a specific device type. ### Method `static create( deviceType: AVHWDeviceType, device?: string, options?: Record ): HardwareContext | null` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - `deviceType` (AVHWDeviceType) - Required - Hardware type constant (e.g., AV_HWDEVICE_TYPE_CUDA). - `device` (string) - Optional - Device path or index. - `options` (Record) - Optional - Device initialization options. ### Returns `HardwareContext` instance or null if not available ### Request Example ```typescript import { HardwareContext } from 'node-av/api'; import { AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_VAAPI } from 'node-av/constants'; // NVIDIA CUDA const cuda = HardwareContext.create(AV_HWDEVICE_TYPE_CUDA); // Intel VAAPI on specific device const vaapi = HardwareContext.create( AV_HWDEVICE_TYPE_VAAPI, '/dev/dri/renderD128' ); // AMD with custom options const amd = HardwareContext.create( AV_HWDEVICE_TYPE_OPENCL, '0', { platform: '0', device: '0' } ); ``` ``` -------------------------------- ### DeviceAPI.list() Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/device-api.md Lists all available input devices on the system, including cameras and microphones, along with their capabilities. ```APIDOC ## DeviceAPI.list() ### Description List all input devices on the system. ### Method `static async list(): Promise` ### Returns Promise resolving to array of device information ### Example ```typescript import { DeviceAPI } from 'node-av/api'; const devices = await DeviceAPI.list(); for (const device of devices) { console.log(`${device.name} (${device.type})`); if (device.type === 'video') { console.log(` Resolution: ${device.width}x${device.height}`); console.log(` Frame rates: ${device.frameRates?.join(', ')}`); } else if (device.type === 'audio') { console.log(` Channels: ${device.channels}`); console.log(` Sample rates: ${device.sampleRates?.join(', ')}`); } } ``` ``` -------------------------------- ### Importing Modules Source: https://github.com/seydx/node-av/blob/main/_autodocs/README.md Demonstrates how to import different modules from the node-av package, including all APIs, high-level APIs, low-level APIs, constants, and FFmpeg binary utilities. ```APIDOC ## Importing Modules ### Description Import from the main package or specific entry points to access different functionalities of the node-av library. ### Code Examples ```typescript // All APIs import * as ffmpeg from 'node-av'; // High-level API import { Demuxer, Decoder, Encoder, Muxer, HardwareContext, DeviceAPI, Scaler, probe, probeSync, pipeline } from 'node-av/api'; // Low-level API import { FormatContext, CodecContext, Frame, Packet, FilterGraph, Codec, Dictionary } from 'node-av/lib'; // Constants import { AV_CODEC_ID_H264, AV_PIX_FMT_YUV420P, FF_ENCODER_LIBX264, FF_DECODER_H264 } from 'node-av/constants'; // FFmpeg binary utilities import { ffmpegPath, isFfmpegAvailable, ffmpegVersion } from 'node-av/ffmpeg'; ``` ``` -------------------------------- ### Open Media from Buffer Source: https://github.com/seydx/node-av/blob/main/README.md Load media directly from a Buffer object. This is useful when media is received in memory, for example, from an HTTP request or another process. ```typescript import { readFile } from 'fs/promises'; const buffer = await readFile('input.mp4'); const media = await Demuxer.open(buffer); ``` -------------------------------- ### Initialize WebRTC Client Source: https://github.com/seydx/node-av/blob/main/examples/browser/webrtc/index.html Logs initialization messages and checks for RTCPeerConnection support in the browser. Sets the initial status to 'Ready'. ```javascript console.log('WebRTC Streaming Client initialized'); console.log('RTCPeerConnection supported:', 'RTCPeerConnection' in window); updateStatus(false, 'Ready'); playOverlay.addEventListener('click', () => { console.log('Play button clicked'); startStream().catch((error) => { console.error('Failed to start stream:', error); updateStatus(false, 'Connection failed'); playOverlay.classList.remove('hidden'); stopButton.disabled = true; }); }); ``` -------------------------------- ### Encoder Creation and Usage with Hardware Acceleration Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/encoder.md Demonstrates how to create an Encoder instance, optionally with hardware acceleration using HardwareContext, and how to process frames for encoding. ```APIDOC ## Encoder Class ### Description The `Encoder` class is used for encoding media frames. It supports hardware acceleration for improved performance. ### Method `Encoder.create(codec: string, options?: EncoderOptions)` ### Parameters #### `codec` (string) - Required - The identifier for the codec to use (e.g., `FF_ENCODER_HEVC_NVENC`). #### `options` (EncoderOptions) - Optional - `hardware` (HardwareContext): An instance of `HardwareContext` for GPU acceleration. - `bitrate` (string): The desired bitrate for the encoded output (e.g., '10M'). ### Usage Example ```typescript // Using hardware acceleration (e.g., CUDA) const hw = HardwareContext.create(AV_HWDEVICE_TYPE_CUDA); const encoder = await Encoder.create(FF_ENCODER_HEVC_NVENC, { hardware: hw, bitrate: '10M' }); // Processing frames (frames can be on GPU or CPU) for await (using packet of encoder.packets(frames)) { // Process encoded packets } ``` ### Related Types - **Frame**: Represents raw media frames to be encoded. - **Packet**: Represents the output encoded data. - **HardwareContext**: Provides GPU acceleration capabilities. - **CodecContext**: The underlying FFmpeg codec context. ``` -------------------------------- ### Import Node-AV APIs Source: https://github.com/seydx/node-av/blob/main/_autodocs/README.md Demonstrates how to import different sets of APIs from the node-av package, including all APIs, high-level, low-level, constants, and FFmpeg binary utilities. ```typescript // All APIs import * as ffmpeg from 'node-av'; // High-level API import { Demuxer, Decoder, Encoder, Muxer, HardwareContext, DeviceAPI, Scaler, probe, probeSync, pipeline } from 'node-av/api'; // Low-level API import { FormatContext, CodecContext, Frame, Packet, FilterGraph, Codec, Dictionary } from 'node-av/lib'; // Constants import { AV_CODEC_ID_H264, AV_PIX_FMT_YUV420P, FF_ENCODER_LIBX264, FF_DECODER_H264 } from 'node-av/constants'; // FFmpeg binary utilities import { ffmpegPath, isFfmpegAvailable, ffmpegVersion } from 'node-av/ffmpeg'; ``` -------------------------------- ### Import Main Entry Point Source: https://github.com/seydx/node-av/blob/main/_autodocs/INDEX.md Import all functionalities from the main entry point of the node-av library. ```typescript // Main entry (includes everything) import * as ffmpeg from 'node-av'; ``` -------------------------------- ### Get Hardware Encoder Codec Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/hardware-context.md Retrieves the hardware-accelerated encoder codec for a given base codec name. Returns null if the codec is not supported by the hardware context. ```typescript const hw = HardwareContext.auto(); if (hw) { const h265Encoder = hw.getEncoderCodec('hevc'); const encoder = await Encoder.create( h265Encoder ?? FF_ENCODER_LIBX265, { hardware: hw } ); } ``` -------------------------------- ### Get Hardware Decoder Codec Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/hardware-context.md Retrieves the hardware-accelerated decoder codec for a given base codec name. Returns null if the codec is not supported by the hardware context. ```typescript const hw = HardwareContext.create(AV_HWDEVICE_TYPE_CUDA); if (hw) { const h264Decoder = hw.getDecoderCodec('h264'); if (h264Decoder) { const decoder = await Decoder.create(stream, { hardware: hw }); } } ``` -------------------------------- ### Auto Hardware Context and Decoder Creation Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/hardware-context.md Shows how to automatically select an available hardware context and then create a decoder, specifying the hardware context. If no hardware context is found, it defaults to a software codec. ```typescript const hw = HardwareContext.auto(); const decoderCodec = hw?.getDecoderCodec('h264') ?? FF_DECODER_H264; const decoder = await Decoder.create(stream, { hardware: hw }); ``` -------------------------------- ### Filtering Video Streams Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/pipeline.md Applies a video filter (e.g., scaling) during the pipeline process. This example scales the video to 1920x1080 before encoding it with H.264. Requires importing `FilterAPI`. ```typescript import { FilterAPI } from 'node-av/api'; const input = await Demuxer.open('input.mp4'); const decoder = await Decoder.create(input.video()!); const filter = await FilterAPI.create('scale=1920:1080'); const encoder = await Encoder.create(FF_ENCODER_LIBX264, { decoder }); const output = await Muxer.open('output.mp4', { input }); output.addStream(encoder, { inputStream: input.video() }); const control = pipeline(input, decoder, filter, encoder, output); await control.completion; ``` -------------------------------- ### Open Demuxer from Various Sources Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/demuxer.md Demonstrates opening a Demuxer instance from different input types like files, network streams, buffers, raw video, or custom I/O callbacks. Ensure correct import: `import { Demuxer } from 'node-av/api'`. For custom I/O, implement `read` and `seek` methods in `IOInputCallbacks`. ```typescript import { Demuxer } from 'node-av/api'; import fs from 'fs'; import { AV_PIX_FMT_YUV420P } from 'node-av/lib/constants'; import { IOInputCallbacks } from 'node-av/lib/types'; // From file const input = await Demuxer.open('input.mp4'); // From network stream const stream = await Demuxer.open('rtsp://camera.local/stream'); // From buffer const buffer = await fs.promises.readFile('input.mp4'); const buffered = await Demuxer.open(buffer); // Raw video input const rawVideo = await Demuxer.open({ type: 'video', input: 'raw.yuv', width: 1920, height: 1080, pixelFormat: AV_PIX_FMT_YUV420P, frameRate: { num: 30, den: 1 } }); // Custom I/O const inputCallbacks: IOInputCallbacks = { read: (size: number) => /* return Buffer or null */ null, seek: (offset: bigint, whence: number) => /* return new position */ 0n }; await using demuxer = await Demuxer.open(inputCallbacks, { format: 'mp4' }); ``` -------------------------------- ### Import FFmpeg Binary Utilities Source: https://github.com/seydx/node-av/blob/main/_autodocs/INDEX.md Import utilities for managing FFmpeg binary paths and availability. ```typescript // FFmpeg binary utilities import { ffmpegPath, isFfmpegAvailable } from 'node-av/ffmpeg'; ``` -------------------------------- ### Load Available Media Devices Source: https://github.com/seydx/node-av/blob/main/examples/browser/webrtc/index.html Establishes a WebSocket connection to 'ws://localhost:8081' to request a list of available media devices. It then populates the device dropdowns once the list is received. ```javascript function loadDevices() { const tmpWs = new WebSocket('ws://localhost:8081'); tmpWs.addEventListener('open', () => { tmpWs.send(JSON.stringify({ type: 'list-devices' })); }); tmpWs.addEventListener('message', (event) => { const msg = JSON.parse(event.data); if (msg.type === 'devices') { deviceList = msg.value; populateDeviceDropdown(); tmpWs.close(); } }); tmpWs.addEventListener('error', () => { console.error('Failed to load devices'); deviceSelect.innerHTML = ''; }); } ``` -------------------------------- ### Get Device Capture Modes Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/device-api.md Retrieves the supported capture modes for a specific input device. This includes various combinations of resolution, frame rate, and format that the device can handle. ```typescript const device = devices.find(d => d.type === 'video')!; const modes = await DeviceAPI.modes(device.name); for (const mode of modes) { if ('width' in mode) { const m = mode as VideoDeviceMode; console.log(`${m.width}x${m.height} @ ${m.frameRate} fps`); } } ``` -------------------------------- ### Load Available Devices via WebSocket Source: https://github.com/seydx/node-av/blob/main/examples/browser/fmp4/index.html Establishes a WebSocket connection to load the list of available media devices. Sends a 'list-devices' message and processes the response to populate the device list. ```javascript function loadDevices() { const tmpWs = new WebSocket('ws://localhost:8080'); tmpWs.addEventListener('open', () => { tmpWs.send(JSON.stringify({ type: 'list-devices' })); }); tmpWs.addEventListener('message', (event) => { const msg = JSON.parse(event.data); if (msg.type === 'devices') { deviceList = msg.value; populateDeviceDropdown(); tmpWs.close(); } }); tmpWs.addEventListener('error', () => { console.error('Failed to load devices'); deviceSelect.innerHTML = ''; }); } ``` -------------------------------- ### Start fMP4 Stream Source: https://github.com/seydx/node-av/blob/main/examples/browser/fmp4/index.html Initiates an fMP4 stream connection. Creates a MediaSource, connects to a WebSocket server, and sends a 'play' request based on the current mode (device or URL). ```javascript async function startStream() { console.log('Starting fMP4 stream...'); updateStatus(false, 'Connecting...'); // Create MediaSource first mediaSource = createMediaSource(); if (!mediaSource) { return; } // Connect to WebSocket server ws = new WebSocket('ws://localhost:8080'); ws.addEventListener('open', () => { console.log('WebSocket connected'); updateStatus(true, 'Connected'); const supportedCodecs = detectSupportedCodecs(); if (currentMode === 'device') { const deviceType = deviceTypeSelect.value; const device = deviceSelect.value; const msg = { type: 'play', source: 'device', deviceType, device, supportedCodecs, framerate: 30, }; if (deviceType === 'device') { msg.audioDevice = audioDeviceSelect.value; } console.log('Sending device play request:', deviceType, device); ws.send(JSON.stringify(msg)); } else { const url = urlInput.value.trim(); if (!url) { console.error('No URL provided'); updateStatus(false, 'No URL provided'); return; } console.log('Sending play request with URL and codecs:', url, supportedCodecs); ws.send( JSON.stringify({ type: 'play', url, supportedCodecs, }), ); } }); ws.addEventListener('message', async (event) => { if (event.data instanceof ArrayBuffer || event.data instanceof Blob) { handleBinaryData(event.data); return; } const data = JSON.parse(event.data); if (data.type === 'mse') { ``` -------------------------------- ### Handle Incoming Stream Data and Initialize SourceBuffer Source: https://github.com/seydx/node-av/blob/main/examples/browser/fmp4/index.html Processes incoming data, logs stream information, and creates a SourceBuffer. It handles cases where MediaSource is not yet ready by waiting for the 'sourceopen' event. ```javascript console.log('Received MSE codec string from server:', data.value); console.log('Stream resolution:', data.resolution); videoCodecsEl.textContent = data.value || 'none'; resolutionEl.textContent = `${data.resolution.width}x${data.resolution.height}`; // Create SourceBuffer with codec string from server if (mediaSource && mediaSource.readyState === 'open') { const success = createSourceBuffer(data.value); if (!success) { stopStream(); } } else { console.warn('MediaSource not ready yet, waiting...'); // Wait for sourceopen event mediaSource.addEventListener( 'sourceopen', () => { const success = createSourceBuffer(data.value); if (!success) { stopStream(); } }, { once: true }, ); } ``` -------------------------------- ### Create Encoder with Variable Bitrate Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/encoder.md Example of creating an encoder with variable bitrate control, specifying minimum, target, and maximum bitrates. This allows for dynamic adjustment within the defined range. ```typescript const encoder = await Encoder.create(codec, { minRate: '1M', bitrate: '5M', maxRate: '10M' }); ``` -------------------------------- ### MuxerOptions Interface Definition Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/muxer.md Defines the configuration options for creating and controlling the Muxer. This includes input sources, format, bitrate, delay, buffer size, start time, seekability, and format-specific options. ```typescript interface MuxerOptions { input?: Demuxer | RTPDemuxer; format?: F; bitrate?: number; maxDelay?: number; bufferSize?: number; startTime?: bigint; seekable?: boolean; formatOptions?: Record; } ``` -------------------------------- ### Hardware Encoding Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/hardware-context.md Illustrates how to set up a hardware encoder, specifically using CUDA for H.264 encoding. It checks for CUDA availability, retrieves an appropriate encoder codec, and configures the encoder with the hardware context and bitrate. ```APIDOC ## Hardware Encoding ### Description This example demonstrates hardware-accelerated video encoding using CUDA. It first attempts to create a CUDA hardware context. If successful, it finds a suitable H.264 encoder codec and initializes the `Encoder` with the hardware context and a specified bitrate. The loop then processes encoded packets. ### Usage ```typescript import { Encoder, HardwareContext } from 'node-av/api'; import { AV_HWDEVICE_TYPE_CUDA } from 'node-av/constants'; const cuda = HardwareContext.create(AV_HWDEVICE_TYPE_CUDA); if (!cuda) { console.log('CUDA not available'); return; } const encoderCodec = cuda.getEncoderCodec('h264') ?? FF_ENCODER_LIBX264; const encoder = await Encoder.create(encoderCodec, { hardware: cuda, bitrate: '5M' }); for await (using packet of encoder.packets(frames)) { // GPU-encoded packets } ``` ### Parameters * `cuda`: A `HardwareContext` instance for CUDA. * `encoderCodec`: The codec to use for encoding (e.g., H.264). * `encoder`: The configured `Encoder` instance. * `frames`: An iterable of video frames to be encoded. * `packet`: Each encoded video packet. ``` -------------------------------- ### Audio Conferencing Setup with Microphone Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/device-api.md Opens the default microphone for audio capture, configured for optimal speech recognition with a specific sample rate and mono channel. Filters devices to find audio inputs. ```typescript // List audio devices const devices = await DeviceAPI.list(); const mics = devices.filter(d => d.type === 'audio'); // Use first available microphone with speech rates const mic = await DeviceAPI.openMicrophone({ audioDevice: mics[0]?.name, sampleRate: 16000, // Optimal for speech recognition channels: 1 // Mono sufficient for speech }); ``` -------------------------------- ### Open Screen Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/device-api.md Opens a screen capture session with options for frame rate, mouse cursor visibility, and audio capture. ```APIDOC ## Open Screen ### Description Opens a screen capture session with options for frame rate, mouse cursor visibility, and audio capture. ### Method `DeviceAPI.openScreen(options)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **options** (object) - Required - Configuration for screen capture. - **frameRate** (number) - Required - The desired frame rate for the screen capture. - **drawMouse** (boolean) - Optional - Whether to draw the mouse cursor on the capture. - **avfoundation** (object) - Optional - Platform-specific options for AVFoundation. - **captureSystemAudio** (boolean) - Optional - Whether to capture system audio. - **audioSampleRate** (number) - Optional - The sample rate for captured audio. ### Request Example ```typescript const screen = await DeviceAPI.openScreen({ frameRate: 30, drawMouse: true, avfoundation: { captureSystemAudio: true, audioSampleRate: 48000 } }); ``` ### Response #### Success Response (200) - **ScreenDevice** - An object representing the screen capture device. #### Response Example (Implicitly returns a screen device object) ``` -------------------------------- ### Hardware Decoding Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/hardware-context.md Demonstrates how to initialize a hardware decoder and process frames using hardware acceleration. The `HardwareContext.auto()` method attempts to find an available hardware context, and the `rescale` option ensures frames are transferred to the CPU in the desired pixel format. ```APIDOC ## Hardware Decoding ### Description This example shows how to set up hardware-accelerated decoding. It opens an input file, selects the video stream, automatically detects a suitable hardware context, and configures the decoder to use it. The `rescale` option is used to specify the output pixel format on the CPU. ### Usage ```typescript import { Decoder, Demuxer, HardwareContext } from 'node-av/api'; const demuxer = await Demuxer.open('input.mp4'); const videoStream = demuxer.video(); // Hardware decoding const hw = HardwareContext.auto(); const decoder = await Decoder.create(videoStream, { hardware: hw, rescale: { pixelFormat: AV_PIX_FMT_YUV420P // Automatically transfer to CPU } }); for await (using frame of decoder.frames(demuxer.packets(videoStream.index))) { console.log(`Frame format: ${frame.pixelFormat}`); // YUV420P (on CPU) } ``` ### Parameters * `demuxer`: An instance of `Demuxer` opened with the input file. * `videoStream`: The video stream selected from the demuxer. * `hw`: An automatically detected `HardwareContext`. * `decoder`: The configured `Decoder` instance. * `frame`: Each decoded video frame. ### Response * Logs the pixel format of each decoded frame, which will be `AV_PIX_FMT_YUV420P` if the rescale option is used. ``` -------------------------------- ### Multi-Stream Processing with Audio Source: https://github.com/seydx/node-av/blob/main/_autodocs/api-reference/pipeline.md Handles both video and audio streams separately for encoding and muxing. Since `pipeline()` is for single streams, this example manually manages the encoders and muxer, writing packets to specific stream indices. ```typescript const input = await Demuxer.open('input.mp4'); const videoDecoder = await Decoder.create(input.video()!); const videoEncoder = await Encoder.create(FF_ENCODER_LIBX264, { decoder: videoDecoder }); const audioDecoder = await Decoder.create(input.audio()!); const audioEncoder = await Encoder.create(FF_ENCODER_LIBFDK_AAC, { decoder: audioDecoder }); const output = await Muxer.open('output.mp4', { input }); output.addStream(videoEncoder, { inputStream: input.video() }); output.addStream(audioEncoder, { inputStream: input.audio() }); // Note: pipeline() is primarily for single-stream workflows // For multi-stream, manually manage encoder/muxer: await Promise.all([ (async () => { for await (using pkt of videoEncoder.packets(videoDecoder.frames(input.packets(input.video()!.index)))) { await output.writePacket(pkt, 0); } })(), (async () => { for await (using pkt of audioEncoder.packets(audioDecoder.frames(input.packets(input.audio()!.index)))) { await output.writePacket(pkt, 1); } })() ]); await output.close(); ```