{
  "schemaVersion": 1,
  "contentVersion": "ca42e61ede0a24f789d7287a0001244ad22f4abf",
  "id": "docs/guides/first-ffmpeg-encode",
  "collection": "docs",
  "title": "Your first FFmpeg encode",
  "description": "Make a good general-purpose H.264 encode with FFmpeg, then learn what CRF and presets do, how to pick streams, and how to test settings on a short clip.",
  "canonicalUrl": "https://encode.wiki/guides/first-ffmpeg-encode/",
  "apiUrl": "https://encode.wiki/api/v1/documents/docs/guides/first-ffmpeg-encode.json",
  "markdownUrl": "https://encode.wiki/api/v1/markdown/docs/guides/first-ffmpeg-encode.md",
  "status": "current",
  "tags": [
    "ffmpeg",
    "beginner"
  ],
  "license": "CC BY-SA 4.0",
  "dates": {
    "lastVerified": "2026-10-08T00:00:00.000Z"
  },
  "authors": [],
  "sources": [
    {
      "title": "FFmpeg documentation — stream selection and main options",
      "url": "https://ffmpeg.org/ffmpeg.html",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg ffmpeg_mux_init.c at n9.0.2 (automatic stream selection)",
      "url": "https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/fftools/ffmpeg_mux_init.c",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg codecs documentation — libx264 and libopus",
      "url": "https://ffmpeg.org/ffmpeg-codecs.html",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg wiki — H.264 encoding guide",
      "url": "https://trac.ffmpeg.org/wiki/Encode/H.264",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "x264 source repository (stable branch)",
      "url": "https://code.videolan.org/videolan/x264/-/tree/stable",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "Xiph.org — Opus recommended settings",
      "url": "https://wiki.xiph.org/Opus_Recommended_Settings",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg libopusenc.c at n9.0.2 (layout check and mapping families)",
      "url": "https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/libavcodec/libopusenc.c",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    }
  ],
  "headings": [
    {
      "depth": 2,
      "text": "Look at the input",
      "anchor": "look-at-the-input"
    },
    {
      "depth": 2,
      "text": "CRF and preset",
      "anchor": "crf-and-preset"
    },
    {
      "depth": 2,
      "text": "Test on a short clip first",
      "anchor": "test-on-a-short-clip-first"
    },
    {
      "depth": 2,
      "text": "Choose the streams you want",
      "anchor": "choose-the-streams-you-want"
    },
    {
      "depth": 2,
      "text": "Copy or re-encode the audio",
      "anchor": "copy-or-re-encode-the-audio"
    },
    {
      "depth": 2,
      "text": "Compatibility settings",
      "anchor": "compatibility-settings"
    },
    {
      "depth": 2,
      "text": "Common errors",
      "anchor": "common-errors"
    }
  ],
  "sections": [
    {
      "id": "_preamble",
      "title": "Page introduction",
      "depth": 0,
      "canonicalUrl": "https://encode.wiki/guides/first-ffmpeg-encode/",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/_preamble.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/_preamble.md",
      "checksum": "1884d3ce2e7607327b423f40e8c3964f2700b9f572a095429b7888486d4e2c6e",
      "bytes": 716
    },
    {
      "id": "look-at-the-input",
      "title": "Look at the input",
      "depth": 2,
      "anchor": "look-at-the-input",
      "canonicalUrl": "https://encode.wiki/guides/first-ffmpeg-encode/#look-at-the-input",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/look-at-the-input.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/look-at-the-input.md",
      "checksum": "463d4eddcefa32cf590558704859187828ef25ddaeed902d78ffc23ab3f3ac92",
      "bytes": 751
    },
    {
      "id": "crf-and-preset",
      "title": "CRF and preset",
      "depth": 2,
      "anchor": "crf-and-preset",
      "canonicalUrl": "https://encode.wiki/guides/first-ffmpeg-encode/#crf-and-preset",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/crf-and-preset.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/crf-and-preset.md",
      "checksum": "89d075ee131010abe5ef7bfb85a9b7d3da3ce89638fb85de546bbeaff002d8e0",
      "bytes": 1168
    },
    {
      "id": "test-on-a-short-clip-first",
      "title": "Test on a short clip first",
      "depth": 2,
      "anchor": "test-on-a-short-clip-first",
      "canonicalUrl": "https://encode.wiki/guides/first-ffmpeg-encode/#test-on-a-short-clip-first",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/test-on-a-short-clip-first.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/test-on-a-short-clip-first.md",
      "checksum": "649dd95b25482f56f5b5c43439067f5e3a12ffc70468f9075d20f233e44c5b62",
      "bytes": 657
    },
    {
      "id": "choose-the-streams-you-want",
      "title": "Choose the streams you want",
      "depth": 2,
      "anchor": "choose-the-streams-you-want",
      "canonicalUrl": "https://encode.wiki/guides/first-ffmpeg-encode/#choose-the-streams-you-want",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/choose-the-streams-you-want.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/choose-the-streams-you-want.md",
      "checksum": "9dace7f962578d68c5353e1fa9b593321bab6d6c2efbdb1704da6b042acce2b9",
      "bytes": 1216
    },
    {
      "id": "copy-or-re-encode-the-audio",
      "title": "Copy or re-encode the audio",
      "depth": 2,
      "anchor": "copy-or-re-encode-the-audio",
      "canonicalUrl": "https://encode.wiki/guides/first-ffmpeg-encode/#copy-or-re-encode-the-audio",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/copy-or-re-encode-the-audio.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/copy-or-re-encode-the-audio.md",
      "checksum": "3a982d9d4a179059b04b291891adfa80e85067ac5684b81ea08774fb7efa0092",
      "bytes": 1234
    },
    {
      "id": "compatibility-settings",
      "title": "Compatibility settings",
      "depth": 2,
      "anchor": "compatibility-settings",
      "canonicalUrl": "https://encode.wiki/guides/first-ffmpeg-encode/#compatibility-settings",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/compatibility-settings.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/compatibility-settings.md",
      "checksum": "ac358ef80713dc1dd33f2af31bcd8b59b60dfdbece2c9a3deddeffcf6371becc",
      "bytes": 471
    },
    {
      "id": "common-errors",
      "title": "Common errors",
      "depth": 2,
      "anchor": "common-errors",
      "canonicalUrl": "https://encode.wiki/guides/first-ffmpeg-encode/#common-errors",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/common-errors.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/guides/first-ffmpeg-encode/common-errors.md",
      "checksum": "d5dc5c65bb24feaea3cbb442cd54c7d924cec63a159c7bec483c5fcfc8636c97",
      "bytes": 1439
    }
  ],
  "outboundReferences": [
    "#copy-or-re-encode-the-audio",
    "/guides/audio-and-subtitles/",
    "/guides/compare-encoding-quality/",
    "/guides/preserve-color-and-hdr/",
    "/guides/quality-controls/"
  ],
  "checksum": "88a0f8d6bd58a4ec9450af71905728402f903e3f5368e826657d250ef11791b3",
  "contentFormat": "markdown",
  "markdown": "If your FFmpeg build includes libx264 and libopus (most distribution packages and the common\nWindows and macOS builds do), this is a good general-purpose encode:\n\n```sh\nffmpeg -i input.mkv -c:v libx264 -preset slow -crf 20 -c:a libopus -b:a 128k output.mkv\n```\n\nIt produces H.264 video, which plays on practically everything, with Opus audio in Matroska. If\nFFmpeg stops with `Invalid channel layout 5.1(side)`, see\n[copy or re-encode the audio](#copy-or-re-encode-the-audio); using `-c:a copy` instead is the quick\nfix. The rest of this page covers what the two numbers mean, how to test settings on a short clip, how to\nchoose streams when the source has several, and when to copy audio instead of re-encoding it.\n\n## Look at the input\n\n```sh\nffprobe -hide_banner input.mkv\n```\n\n`-hide_banner` skips FFmpeg's build-configuration header. The stream list looks like this\n(trimmed):\n\n```text\n  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080, 23.98 fps\n  Stream #0:1(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 640 kb/s (default)\n  Stream #0:2(jpn): Audio: flac, 48000 Hz, stereo, s16\n  Stream #0:3(eng): Subtitle: subrip (srt)\n```\n\nNote the audio and subtitle languages and the video pixel format. This recipe is for ordinary 8-bit\nSDR video. If you see `yuv420p10le` together with `bt2020` and `smpte2084` or `arib-std-b67`, the\nsource is HDR: use HEVC or AV1 and follow [preserve color and HDR](/guides/preserve-color-and-hdr/)\ninstead.\n\n## CRF and preset\n\n**`-crf`** sets the quality target. The encoder spends whatever bitrate each scene needs to reach\nit, so file size depends on the content. Lower is better quality and bigger. For x264 the default is\n23, and about ±6 halves or doubles the bitrate. Values around 17–18 usually look the same as the\nsource; most encodes land between 18 and 24. Pick the highest value that still looks good to you.\nCRF scales differ between encoders: x265, SVT-AV1 and others use different numbers for similar\nquality (see [quality controls](/guides/quality-controls/)).\n\n**`-preset`** trades encoding time for compression. The x264 presets run from `ultrafast` to\n`placebo`; the default is `medium`. Slower presets find better ways to code the same picture, so at\nthe same CRF you get a smaller file or more retained detail. `slow` is a common choice; `veryslow` is\nworth it for encodes you keep. `placebo` costs a lot of time for almost nothing.\n\n**`-tune`** is optional. `film`, `animation` and `grain` adjust x264's deblocking, psychovisual and\nadaptive-quantization settings for that kind of content; use `grain` for grainy film sources you\nwant to keep grainy.\n\n## Test on a short clip first\n\nEncode a minute from a demanding part of the source before committing to a full run:\n\n```sh\nffmpeg -ss 10:00 -i input.mkv -t 60 -c:v libx264 -preset slow -crf 20 -c:a libopus -b:a 128k test-crf20.mkv\n```\n\n`-ss` before `-i` seeks quickly in the input, and `-t 60` stops after 60 seconds. Because the video\nis re-encoded, the cut is frame-accurate. Make two or three versions at different CRF values, then\nwatch them at normal speed and pause on dark scenes, faces, grain and fast motion. Your eyes are the\nfinal judge; [compare encoding quality](/guides/compare-encoding-quality/) covers metrics when you\nwant numbers as well.\n\n## Choose the streams you want\n\nWithout `-map`, FFmpeg keeps one video stream (the highest resolution), one audio stream (the one\nwith the most channels) and the first subtitle stream the output format's default subtitle encoder\ncan handle. Within a file, a stream flagged default wins over a bigger one, so a default stereo\ntrack beats a non-default 5.1 track. Everything else is dropped without a warning. When writing\nMatroska, text subtitles are converted to ASS; MP4 output gets no subtitles at all.\n\nAs soon as you use `-map`, only the streams you list are written:\n\n```sh\nffmpeg -i input.mkv -map 0:v:0 -map 0:a:1 -map '0:s?' \\\n  -c:v libx264 -preset slow -crf 20 -c:a libopus -b:a 128k -c:s copy output.mkv\n```\n\n`0:a:1` is the second audio stream of the first input (counting from zero within each type), so with\nthe input above this keeps the Japanese track. `0:s?` takes every subtitle stream; the `?` means \"if\nthere are any\", and the quotes stop shells such as zsh from treating `?` as a wildcard. `-c:s copy`\nkeeps the subtitles in their original format. To keep every stream, use `-map 0`. The\n[audio and subtitles guide](/guides/audio-and-subtitles/) covers languages, default/forced flags and\nfonts.\n\n## Copy or re-encode the audio\n\nUse `-c:a copy` when the source audio already plays where you need it. It costs no quality and no\ntime. Re-encoding pays off for lossless or very large tracks (FLAC, PCM, TrueHD, DTS-HD MA), where\nOpus saves most of the space. Re-encoding a lossy track such as AC-3 or AAC adds another generation\nof loss, so do it only for size or compatibility.\n\nOpus at 128 kbit/s is close to transparent for stereo music; use roughly 256 kbit/s for 5.1. If the\nsource layout is `5.1(side)`, libopus refuses it with `Invalid channel layout 5.1(side)`. Convert it\nto plain 5.1:\n\n```sh\nffmpeg -i input.mkv -map 0:v:0 -map 0:a:0 -c:v libx264 -preset slow -crf 20 \\\n  -c:a libopus -b:a 256k -af aformat=channel_layouts=5.1 -mapping_family 1 output.mkv\n```\n\n`aformat` moves the side channels to the back positions; nothing is downmixed. `-mapping_family 1`\nswitches libopus to its surround encoder, which uses masking between channels to spend the bits\nbetter. `-af` applies to every audio stream you encode, so with several audio tracks use\n`-filter:a:N` instead (see the [audio and subtitles guide](/guides/audio-and-subtitles/)).\n\nFor MP4 output aimed at older devices, use AAC (`-c:a aac -b:a 192k`) instead of Opus.\n\n## Compatibility settings\n\nlibx264 keeps the input's bit depth and chroma format. A 10-bit or 4:2:2 source therefore becomes\nHigh 10 or High 4:2:2 H.264, which most hardware decoders and browsers cannot play. Add\n`-pix_fmt yuv420p` when you need 8-bit 4:2:0 output that plays everywhere.\n\nFor MP4 files that will be streamed over the web, add `-movflags +faststart`. It moves the index to\nthe start of the file so playback can begin before the whole file has downloaded.\n\n## Common errors\n\n| Message                                                                             | Cause and fix                                                                                                    |\n| ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |\n| `Unknown encoder 'libx264'`                                                         | Your FFmpeg build lacks that library. Install a build that includes it.                                          |\n| `Stream map '...' matches no streams`                                               | That stream does not exist. Check the ffprobe list, or add `?` if the stream is optional.                        |\n| `Invalid channel layout 5.1(side) for specified mapping family`                     | libopus does not accept that layout. Add `-af aformat=channel_layouts=5.1`.                                      |\n| `Automatic encoder selection failed` or `Could not find tag for codec subrip` (MP4) | MP4 cannot hold that subtitle format. Use `-c:s mov_text` for text subtitles, or leave them out.                 |\n| Colors look washed out or too dark                                                  | Usually an HDR source or a range/matrix mismatch. See [preserve color and HDR](/guides/preserve-color-and-hdr/). |\n"
}
