{"id":33422880,"url":"https://github.com/seydx/node-av","last_synced_at":"2026-02-10T11:02:40.262Z","repository":{"id":311784712,"uuid":"1034415948","full_name":"seydx/node-av","owner":"seydx","description":"FFmpeg bindings for Node.js. Features both low-level and high-level APIs, full hardware acceleration, TypeScript support, and modern async patterns","archived":false,"fork":false,"pushed_at":"2026-02-07T22:39:08.000Z","size":29585,"stargazers_count":206,"open_issues_count":5,"forks_count":12,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-08T06:57:11.668Z","etag":null,"topics":["av","av1","codec","electron","ffmpeg","ffmpeg-wrapper","fmp4","h264","h265","libav","mse","node-av","nodeav","nodejs","typescript","webrtc","whisper"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seydx.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"seydx","ko_fi":"seydx","custom":"https://paypal.me/seydx"}},"created_at":"2025-08-08T11:00:12.000Z","updated_at":"2026-02-07T22:39:10.000Z","dependencies_parsed_at":"2025-08-26T20:21:36.219Z","dependency_job_id":"005e397b-ea98-4b60-a756-382a9b023d0d","html_url":"https://github.com/seydx/node-av","commit_stats":null,"previous_names":["seydx/av","seydx/node-av"],"tags_count":46,"template":false,"template_full_name":null,"purl":"pkg:github/seydx/node-av","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seydx%2Fnode-av","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seydx%2Fnode-av/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seydx%2Fnode-av/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seydx%2Fnode-av/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seydx","download_url":"https://codeload.github.com/seydx/node-av/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seydx%2Fnode-av/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29298505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-10T10:40:02.018Z","status":"ssl_error","status_checked_at":"2026-02-10T10:38:28.459Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["av","av1","codec","electron","ffmpeg","ffmpeg-wrapper","fmp4","h264","h265","libav","mse","node-av","nodeav","nodejs","typescript","webrtc","whisper"],"created_at":"2025-11-24T03:04:45.657Z","updated_at":"2026-02-10T11:02:40.214Z","avatar_url":"https://github.com/seydx.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/seydx/node-av/blob/main/docs/logo.png?raw=true\" width=\"250px\"\u003e\n\u003c/p\u003e\n\n# NodeAV\n\n[![npm version](https://img.shields.io/npm/v/node-av.svg)](https://www.npmjs.com/package/node-av)\n[![npm downloads](https://img.shields.io/npm/dt/node-av.svg)](https://www.npmjs.com/package/node-av)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)\n[![FFmpeg](https://img.shields.io/badge/FFmpeg-8-green.svg)](https://ffmpeg.org)\n[![Platform](https://img.shields.io/badge/platform-Windows%20(MSVC%20%7C%20MinGW)%20%7C%20macOS%20%7C%20Linux-lightgrey.svg)](https://github.com/seydx/node-av)\n\nNative Node.js bindings for FFmpeg with full TypeScript support. Provides direct access to FFmpeg's C APIs through N-API. Includes both raw FFmpeg bindings for full control and higher-level abstractions. Automatic resource management via Disposable pattern, hardware acceleration support and prebuilt binaries for Windows, Linux, and macOS.\n\n📚 **[Documentation](https://seydx.github.io/node-av)**\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n  - [Low-Level API](#low-level-api)\n  - [High-Level API](#high-level-api)\n  - [Pipeline API](#pipeline-api)\n- [Key Features](#key-features)\n- [Hardware Acceleration](#hardware-acceleration)\n  - [Auto-Detection](#auto-detection)\n  - [Specific Hardware](#specific-hardware)\n- [Imports and Tree Shaking](#imports-and-tree-shaking)\n- [Stream Processing](#stream-processing)\n  - [From Files](#from-files)\n  - [From Network](#from-network)\n  - [From Buffers](#from-buffers)\n  - [Raw Media Processing](#raw-media-processing)\n- [Resource Management](#resource-management)\n- [FFmpeg Binary Access](#ffmpeg-binary-access)\n- [Performance](#performance)\n  - [Sync vs Async Operations](#sync-vs-async-operations)\n- [Memory Safety Considerations](#memory-safety-considerations)\n- [Examples](#examples)\n- [Prebuilt Binaries](#prebuilt-binaries)\n- [Troubleshooting](#troubleshooting)\n- [License](#license)\n- [Contributing](#contributing)\n- [Support](#support)\n- [See Also](#see-also)\n\n## Installation\n\n```bash\nnpm install node-av\n```\n\n## Quick Start\n\n### Low-Level API\n\nDirect access to FFmpeg's C APIs with minimal abstractions. Perfect when you need full control over FFmpeg functionality.\n\n```typescript\nimport { AVERROR_EOF, AVMEDIA_TYPE_VIDEO } from 'node-av/constants';\nimport { Codec, CodecContext, FFmpegError, FormatContext, Frame, Packet, Rational } from 'node-av/lib';\n\n// Open input file\nawait using ifmtCtx = new FormatContext();\n\nlet ret = await ifmtCtx.openInput('input.mp4');\nFFmpegError.throwIfError(ret, 'Could not open input file');\n\nret = await ifmtCtx.findStreamInfo();\nFFmpegError.throwIfError(ret, 'Could not find stream info');\n\n// Find video stream\nconst videoStreamIndex = ifmtCtx.findBestStream(AVMEDIA_TYPE_VIDEO);\nconst videoStream = ifmtCtx.streams?.[videoStreamIndex];\n\nif (!videoStream) {\n  throw new Error('No video stream found');\n}\n\n// Create codec\nconst codec = Codec.findDecoder(videoStream.codecpar.codecId);\nif (!codec) {\n  throw new Error('Codec not found');\n}\n\n// Allocate codec context for the decoder\nusing decoderCtx = new CodecContext();\ndecoderCtx.allocContext3(codec);\n\nret = decoderCtx.parametersToContext(videoStream.codecpar);\nFFmpegError.throwIfError(ret, 'Could not copy codec parameters to decoder context');\n\n// Open decoder context\nret = await decoderCtx.open2(codec, null);\nFFmpegError.throwIfError(ret, 'Could not open codec');\n\n// Process packets\nusing packet = new Packet();\npacket.alloc();\n\nusing frame = new Frame();\nframe.alloc();\n\nwhile (true) {\n  let ret = await ifmtCtx.readFrame(packet);\n  if (ret \u003c 0) {\n    break;\n  }\n\n  if (packet.streamIndex === videoStreamIndex) {\n    // Send packet to decoder\n    ret = await decoderCtx.sendPacket(packet);\n    if (ret \u003c 0 \u0026\u0026 ret !== AVERROR_EOF) {\n      FFmpegError.throwIfError(ret, 'Error sending packet to decoder');\n    }\n\n    // Receive decoded frames\n    while (true) {\n      const ret = await decoderCtx.receiveFrame(frame);\n      if (ret === AVERROR_EOF || ret \u003c 0) {\n        break;\n      }\n\n      console.log(`Decoded frame ${frame.pts}, size: ${frame.width}x${frame.height}`);\n\n      // Process frame data...\n    }\n  }\n\n  packet.unref();\n}\n```\n\n### High-Level API\n\nHigher-level abstractions for common tasks like decoding, encoding, filtering, and transcoding. Easier to use while still providing access to low-level details when needed.\n\n```typescript\nimport { Decoder, Demuxer, Encoder, HardwareContext, Muxer } from 'node-av/api';\nimport { FF_ENCODER_LIBX264 } from 'node-av/constants';\n\n// Open Demuxer\nawait using input = await Demuxer.open('input.mp4');\n\n// Get video stream\nconst videoStream = input.video()!;\n\n// Optional, setup hardware acceleration\nusing hw = HardwareContext.auto();\n\n// Create decoder\nusing decoder = await Decoder.create(videoStream, {\n  hardware: hw, // Optional, use hardware acceleration if available\n});\n\n// Create encoder\nusing encoder = await Encoder.create(FF_ENCODER_LIBX264, {\n  decoder, // Optional, copy settings from decoder\n});\n\n// Open Muxer\nawait using output = await Muxer.open('output.mp4', {\n  input, // Optional, used to copy global headers and metadata\n});\n\n// Add stream to output\nconst outputIndex = output.addStream(encoder, {\n  inputStream: videoStream, // Optional, copy settings from input stream\n});\n\n// Create processing generators\nconst inputGenerator = input.packets(videoStream.index);\nconst decoderGenerator = decoder.frames(inputGenerator);\nconst encoderGenerator = encoder.packets(decoderGenerator);\n\n// Process packets\nfor await (using packet of encoderGenerator) {\n  await output.writePacket(packet, outputIndex);\n}\n\n// Done\n```\n\n### Pipeline API\n\nA simple way to chain together multiple processing steps like decoding, filtering, encoding, and muxing.\n\n```typescript\nimport { Decoder, Demuxer, Encoder, HardwareContext, Muxer, pipeline } from 'node-av/api';\nimport { FF_ENCODER_LIBX264 } from 'node-av/constants';\n\n// Simple transcode pipeline: input → decoder → encoder → output\n\n// Open Demuxer\nawait using input = await Demuxer.open('input.mp4');\n\n// Get video stream\nconst videoStream = input.video()!;\n\n// Optional, setup hardware acceleration\nusing hw = HardwareContext.auto();\n\n// Create decoder\nusing decoder = await Decoder.create(videoStream, {\n  hardware: hw, // Optional, use hardware acceleration if available\n});\n\n// Create encoder\nusing encoder = await Encoder.create(FF_ENCODER_LIBX264, {\n  decoder, // Optional, copy settings from decoder\n});\n\n// Open Muxer\nawait using output = await Muxer.open('output.mp4', {\n  input, // Optional, used to copy global headers and metadata\n});\n\nconst control = pipeline(input, decoder, encoder, output);\nawait control.completion;\n```\n\n## Key Features\n\nBeyond basic transcoding, NodeAV provides advanced media processing capabilities:\n\n**Speech Recognition with Whisper**\nIntegrate automatic speech-to-text transcription using OpenAI's Whisper model through the whisper.cpp implementation. The library handles automatic model downloading from HuggingFace, supports multiple model sizes (tiny, base, small, medium, large) for different accuracy/performance tradeoffs, and provides hardware-accelerated inference through Metal (macOS), Vulkan (cross-platform), or OpenCL backends. Transcription results include precise timestamps and can be processed in real-time from any audio source.\n\n**Advanced Video Filtering with FilterComplexAPI**\nBuild sophisticated video processing pipelines using FFmpeg's complete filter ecosystem. The FilterComplexAPI provides direct access to complex filtergraphs with multiple inputs and outputs, enabling advanced operations like picture-in-picture overlays, multi-stream composition (side-by-side, grid layouts), real-time video effects, and custom processing chains. All filters support hardware acceleration where available, and filter configurations can be dynamically constructed based on runtime requirements.\n\n**Browser Streaming**\nStream any media source directly to web browsers through fragmented MP4 (fMP4) or WebRTC protocols. The library can process inputs from RTSP cameras, local files, network streams, or custom sources and package them for browser consumption with minimal latency. Complete examples demonstrate both Media Source Extensions (MSE) based playback for on-demand content and WebRTC integration for real-time streaming scenarios.\n\n**RTSP Backchannel / Talkback**\nImplements bidirectional RTSP communication for IP camera integration. The library provides native support for RTSP backchannel streams, enabling audio transmission to camera devices. Transport is handled automatically with support for both TCP (interleaved mode) and UDP protocols, with proper RTP packet formatting and stream synchronization.\n\nSee the [Examples](#examples) section for complete implementations.\n\n## Hardware Acceleration\n\nThe library supports all hardware acceleration methods available in FFmpeg. The specific hardware types available depend on your FFmpeg build and system configuration.\n\n### Auto-Detection\n\n```typescript\nimport { HardwareContext } from 'node-av/api';\nimport { FF_ENCODER_LIBX264 } from 'node-av/constants';\n\n// Automatically detect best available hardware\nconst hw = HardwareContext.auto();\nconsole.log(`Using hardware: ${hw.deviceTypeName}`);\n\n// Use with decoder\nconst decoder = await Decoder.create(stream, {\n  hardware: hw\n});\n\n// Use with encoder (use hardware-specific codec)\nconst encoderCodec = hw?.getEncoderCodec('h264') ?? FF_ENCODER_LIBX264;\nconst encoder = await Encoder.create(encoderCodec, {\n  decoder,\n});\n```\n\n### Specific Hardware\n\n```typescript\nimport { AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_VAAPI } from 'node-av/constants';\n\n// Use specific hardware type\nconst cuda = HardwareContext.create(AV_HWDEVICE_TYPE_CUDA);\nconst vaapi = HardwareContext.create(AV_HWDEVICE_TYPE_VAAPI, '/dev/dri/renderD128');\n```\n\n## Imports and Tree Shaking\n\nThe library provides multiple entry points for optimal tree shaking:\n\n```typescript\n// High-Level API only - Recommended for most use cases\nimport { Muxer, Muxer, Decoder, Encoder } from 'node-av/api';\n\n// Low-Level API only - Direct FFmpeg bindings\nimport { FormatContext, CodecContext, Frame, Packet } from 'node-av/lib';\n\n// Constants only - When you just need FFmpeg constants\nimport { AV_PIX_FMT_YUV420P, AV_CODEC_ID_H264 } from 'node-av/constants';\n\n// Channel layouts only - For audio channel configurations\nimport { AV_CHANNEL_LAYOUT_STEREO, AV_CHANNEL_LAYOUT_5POINT1 } from 'node-av/layouts';\n\n// Default export - Includes everything\nimport * as ffmpeg from 'node-av';\n```\n\n## Stream Processing\n\n### From Files or Network\n\n```typescript\nconst media = await Muxer.open('input.mp4');\n\n// or\n\nconst media = await Muxer.open('rtsp://example.com/stream');\n```\n\n### From Buffers\n\n```typescript\nimport { readFile } from 'fs/promises';\n\nconst buffer = await readFile('input.mp4');\nconst media = await Muxer.open(buffer);\n```\n\n### Custom I/O Callbacks\n\n```typescript\nimport type { IOInputCallbacks, IOOutputCallbacks } from 'node-av/api';\n\n// Custom input source\nconst inputCallbacks: IOInputCallbacks = {\n  read: (size: number) =\u003e {\n    // Read from your custom source\n    return buffer; // or null for EOF\n  },\n  seek: (offset: bigint, whence: number) =\u003e {\n    // Seek in your custom source\n    return newPosition;\n  }\n};\n\nawait using input = await Muxer.open(inputCallbacks, {\n  format: 'mp4'\n});\n```\n\n### Raw Media Processing\n\n```typescript\n// Raw video input\nconst rawVideo = await Muxer.open({\n  type: 'video',\n  input: 'input.yuv',\n  width: 1280,\n  height: 720,\n  pixelFormat: AV_PIX_FMT_YUV420P,\n  frameRate: { num: 30, den: 1 }\n});\n\n// Raw audio input\nconst rawAudio = await Muxer.open({\n  type: 'audio',\n  input: 'input.pcm',\n  sampleRate: 48000,\n  channels: 2,\n  sampleFormat: AV_SAMPLE_FMT_S16\n}, {\n  format: 's16le'\n});\n```\n\n## Resource Management\n\nThe library supports automatic resource cleanup using the Disposable pattern:\n\n```typescript\n// Automatic cleanup with 'using'\n{\n  await using media = await Muxer.open('input.mp4');\n  using decoder = await Decoder.create(media.video());\n  // Resources automatically cleaned up at end of scope\n}\n\n// Manual cleanup\nconst media = await Muxer.open('input.mp4');\ntry {\n  // Process media\n} finally {\n  await media.close();\n}\n```\n\n## FFmpeg Binary Access\n\nNeed direct access to the FFmpeg binary? The library provides an easy way to get FFmpeg binaries that automatically downloads and manages platform-specific builds.\n\n```typescript\nimport { ffmpegPath, isFfmpegAvailable } from 'node-av/ffmpeg';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\n\n// Check if FFmpeg binary is available\nif (isFfmpegAvailable()) {\n  console.log('FFmpeg binary found at:', ffmpegPath());\n\n  // Use FFmpeg binary directly\n  const { stdout } = await execFileAsync(ffmpegPath(), ['-version']);\n  console.log(stdout);\n} else {\n  console.log('FFmpeg binary not available - install may have failed');\n}\n\n// Direct usage example\nasync function convertVideo(input: string, output: string) {\n  const args = [\n    '-i', input,\n    '-c:v', 'libx264',\n    '-crf', '23',\n    '-c:a', 'aac',\n    output\n  ];\n\n  await execFileAsync(ffmpegPath(), args);\n}\n```\n\nThe FFmpeg binary is automatically downloaded during installation from GitHub releases and matches the same build used by the native bindings.\n\n## Performance\n\nNodeAV executes all media operations directly through FFmpeg's native C libraries. The Node.js bindings add minimal overhead - mostly just the JavaScript-to-C boundary crossings. During typical operations like transcoding or filtering, most processing time is spent in FFmpeg's optimized C code.\n\n### Sync vs Async Operations\n\nEvery async method in NodeAV has a corresponding synchronous variant with the `Sync` suffix:\n\n- **Async methods** (default) - Non-blocking operations using N-API's AsyncWorker. Methods like `decode()`, `encode()`, `read()`, `packets()` return Promises or AsyncGenerators.\n\n- **Sync methods** - Direct FFmpeg calls without AsyncWorker overhead. Same methods with `Sync` suffix: `decodeSync()`, `encodeSync()`, `readSync()`, `packetsSync()`.\n\nThe key difference: Async methods don't block the Node.js event loop, allowing other operations to run concurrently. Sync methods block until completion but avoid AsyncWorker overhead, making them faster for sequential processing.\n\n## Memory Safety Considerations\n\nNodeAV provides direct bindings to FFmpeg's C APIs, which work with raw memory pointers. The high-level API adds safety abstractions and automatic resource management, but incorrect usage can still cause crashes. Common issues include mismatched video dimensions, incompatible pixel formats, or improper frame buffer handling. The library validates parameters where possible, but can't guarantee complete memory safety without limiting functionality. When using the low-level API, pay attention to parameter consistency, resource cleanup, and format compatibility. Following the documented patterns helps avoid memory-related issues.\n\n## Examples\n\n| Example | FFmpeg | Low-Level API | High-Level API |\n|---------|--------|---------------|----------------|\n| `browser-fmp4` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/browser/fmp4) |\n| `browser-webrtc` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/browser/webrtc) |\n| `api-dash` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-dash.ts) |\n| `api-encode-decode` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-encode-decode.ts) |\n| `api-filter-complex` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-filter-complex.ts) |\n| `api-filter-complex-grid` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-filter-complex-grid.ts) |\n| `api-fmp4` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-fmp4.ts) |\n| `api-frame-extract` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-frame-extract.ts) |\n| `api-hw-codecs` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-codecs.ts) |\n| `api-hw-decode-sw-encode` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-decode-sw-encode.ts) |\n| `api-hw-raw` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-raw.ts) |\n| `api-hw-raw-output` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-raw-output.ts) |\n| `api-hw-rtsp` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-rtsp.ts) |\n| `api-hw-stream-custom-io` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-stream-custom-io.ts) |\n| `api-hw-transcode` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-transcode.ts) |\n| `api-hw-filter-sync` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-filter-sync.ts) |\n| `api-muxing` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-muxing.ts) |\n| `api-pipeline-hw-rtsp` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-pipeline-hw-rtsp.ts) |\n| `api-pipeline-raw-muxing` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-pipeline-raw-muxing.ts) |\n| `api-rtp` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-rtp.ts) |\n| `api-sdp-custom` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-sdp-custom.ts) |\n| `api-sdp-input` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-sdp-input.ts) |\n| `api-stream-input` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-stream-input.ts) |\n| `api-sw-decode-hw-encode` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-sw-decode-hw-encode.ts) |\n| `api-sw-transcode` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-sw-transcode.ts) |\n| `api-whisper-subtitles` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-whisper-subtitles.ts) |\n| `api-whisper-transcribe` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-whisper-transcribe.ts) |\n| `frame-utils` | | [✓](https://github.com/seydx/node-av/tree/main/examples/frame-utils.ts) | |\n| `avio-read-callback` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/avio_read_callback.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/avio-read-callback.ts) | |\n| `avio-async-read-callback` | | [✓](https://github.com/seydx/node-av/tree/main/examples/avio-async-read-callback.ts) | |\n| `decode-audio` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/decode_audio.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/decode-audio.ts) | |\n| `decode-filter-audio` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/decode_filter_audio.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/decode-filter-audio.ts) | |\n| `decode-filter-video` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/decode_filter_video.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/decode-filter-video.ts) | |\n| `decode-video` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/decode_video.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/decode-video.ts) | |\n| `demux-decode` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/demux_decode.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/demux-decode.ts) | |\n| `encode-audio` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/encode_audio.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/encode-audio.ts) | |\n| `encode-video` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/encode_video.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/encode-video.ts) | |\n| `ffprobe-metadata` | | [✓](https://github.com/seydx/node-av/tree/main/examples/ffprobe-metadata.ts) | |\n| `filter-audio` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/filter_audio.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/filter-audio.ts) | |\n| `hw-decode` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/hw_decode.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/hw-decode.ts) | |\n| `hw-encode` | | [✓](https://github.com/seydx/node-av/tree/main/examples/hw-encode.ts) | |\n| `hw-transcode` | | [✓](https://github.com/seydx/node-av/tree/main/examples/hw-transcode.ts) | |\n| `qsv-decode` | [✓](https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/qsv_decode.c) | | |\n| `qsv-transcode` | [✓](https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/qsv_transcode.c) | | |\n| `vaapi-encode` | [✓](https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/vaapi_encode.c) | | |\n| `vaapi-transcode` | [✓](https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/vaapi_transcode.c) | | |\n| `mux` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/mux.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/mux.ts) | |\n| `remux` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/remux.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/remux.ts) | |\n| `resample-audio` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/resample_audio.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/resample-audio.ts) | |\n| `rtsp-stream-info` | | [✓](https://github.com/seydx/node-av/tree/main/examples/rtsp-stream-info.ts) | |\n| `scale-video` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/scale_video.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/scale-video.ts) | |\n| `show-metadata` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/show_metadata.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/show-metadata.ts) | |\n| `transcode-aac` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/transcode_aac.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/transcode-aac.ts) | |\n| `transcode` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/transcode.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/transcode.ts) | |\n\n\n## Prebuilt Binaries\n\nPrebuilt binaries are available for multiple platforms:\n\n- **macOS**: x64, ARM64\n- **Linux**: x64, ARM64\n- **Windows**: x64, ARM64 (automatic MSVC/MinGW selection)\n\n## Troubleshooting\n\n### Hardware Acceleration on Linux (Intel/VAAPI)\n\nFor hardware-accelerated video processing with Intel GPUs on Linux, you need to install specific system packages. The FFmpeg binaries included with this library are built with **libva 2.20**, which requires **Ubuntu 24.04+** or **Debian 13+** as minimum OS versions.\n\n#### Installation Steps\n\n1. **Add Kisak-Mesa PPA** (recommended for newer Mesa versions with better hardware support):\n\n```bash\nsudo add-apt-repository ppa:kisak/kisak-mesa\nsudo apt update\n```\n\n2. **Install required packages**:\n\n```bash\nsudo apt install libmfx-gen1.2 mesa-va-drivers mesa-vulkan-drivers libva2 libva-drm2 vainfo libvulkan1 vulkan-tools\n```\n\nAfter installation, verify hardware acceleration is working:\n\n```bash\n# Check VAAPI support\nvainfo\n\n# Check Vulkan support\nvulkaninfo\n\n# Should show available profiles and entrypoints for your Intel GPU\n```\n\n**Note**: If you're running an older Ubuntu version (\u003c 24.04) or Debian version (\u003c 13), you'll need to upgrade your OS to use hardware acceleration with this library.\n\n## License\n\nThis project is licensed under the MIT License. See the LICENSE file for details.\n\n**Important**: FFmpeg itself is licensed under LGPL/GPL. Please ensure compliance with FFmpeg's license terms when using this library. The FFmpeg libraries themselves retain their original licenses, and this wrapper library does not change those terms. See [FFmpeg License](https://ffmpeg.org/legal.html) for details.\n\n## Contributing\n\nContributions are welcome! Please read [CONTRIBUTING.md](https://github.com/seydx/node-av/tree/main/CONTRIBUTING.md) for development setup, code standards, and contribution guidelines before submitting pull requests.\n\n## Support\n\nFor issues and questions, please use the GitHub issue tracker.\n\n## See Also\n\n- [FFmpeg Documentation](https://ffmpeg.org/documentation.html)\n- [FFmpeg Doxygen](https://ffmpeg.org/doxygen/trunk/)\n- [Jellyfin FFmpeg](https://github.com/seydx/jellyfin-ffmpeg)\n- [FFmpeg MSVC](https://github.com/seydx/ffmpeg-msvc-prebuilt)\n","funding_links":["https://github.com/sponsors/seydx","https://ko-fi.com/seydx","https://paypal.me/seydx"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseydx%2Fnode-av","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseydx%2Fnode-av","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseydx%2Fnode-av/lists"}