Недавно пришлось собирать ffmpeg под Windows компилятором MSVC. И знаете — я чуть не помер. Официальная документация по сборке проекта под Windows безнадежно устарела. В Интернете есть даже статьи, которые так и заявляют: "Официальная документация по сборке ffmpeg под Windows безнадежно устарела — вот как теперь это делается". И смех в том, что эти статьи уже тоже устарели и не дают работающего решения "press X to compile".

Поэтому я просто оставлю здесь инструкцию, которая работает на февраль 2026. И, возможно, устареет, как и все предыдущие. Но вы тогда мне просто об этом напишете, и я попробую актуализировать эту инструкцию.

Ставим MSYS2

В первую очередь мы поставим MSYS2, который позволит нам иметь Unix-подобное окружение в Windows: в частности возможность запускать configure и make

  • Загружаем и запускаем MSYS2

  • Идем в файл c:/msys64/msys2_shell.cmd и удаляем rem из строки rem set MSYS2_PATH_TYPE=inherit

  • Запускаем x64 Native Tools Command Prompt for VS 2022 (или ту версию VS, которая у вас есть)

  • Из под этого терминала запускаем c:/msys64/msys2_shell.cmd, запустится еще один терминал, в котором выполняем оставшиеся команды

  • pacman -Syu

  • pacman -S make

  • pacman -S nasm

  • Запускаем mv /usr/bin/link.exe /usr/bin/link.exe.bak. Да-да — фактически удаляем местный link.exe, поскольку он будет конфликтовать с link.exe тулчейна msvc

Поздравляем, вы настроили MSYS2 на возможность собрать ffmpeg тулчейном msvc в Unix-like окружении

Качаем ffmpeg

Клонируем ffmpeg-репозиторий командой

git clone https://git.ffmpeg.org/ffmpeg.git <ffmpeg-folder>

Собираем ffmpeg

Для начала снова запускаем "терминал через терминал":

  • Запускаем x64 Native Tools Command Prompt for VS 2022

  • Из под этого терминала запускаем терминал c:/msys64/msys2_shell.cmd

  • В этом терминале переходим в папку с ffmpeg-репозиторием

  • Для того, чтобы проверить, что все идет по плану, запустите команду cl. Вы должны увидеть что-то в духе:

Microsoft (R) C/C++ Optimizing Compiler Version 19.43.34809 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

Если терминал пишет, что он не знает, что такое cl.exe, у вас все пошло не так. Перечитывайте инструкцию, переустанавливайте все, молитесь.

Дальнейшая работа происходит в этом, втором MSYS2-терминале.

Дефолтная сборка

Самый минималистичный вариант сборки ffmpeg:

./configure --target-os=win64 --arch=x86_64 --toolchain=msvc
make -j16

Кастомная сборка

При желании вы можете добавлять в configure различные конфигурационные флаги, которые можно узнать из ./configure --help. Ffmpeg имеет очень обширную кастомизацию.

Пример:

./configure \
  --target-os=win64 \
  --arch=x86_64 \
  --toolchain=msvc \
  --disable-programs \
  --disable-doc \
  --disable-encoders \
  --disable-muxers \
  --disable-filters \
  --disable-devices \
  --disable-network \
  --disable-avfilter \
  --disable-avdevice \
  --disable-mediafoundation \
  --enable-decoder=aac,ac3,adpcm_ima_wav,adpcm_ms,alac,av1,bmp,eac3,dnxhd,ffv1,ffvhuff,flac,flc,flic,flv1,gif,h263,h263p,h264,hevc,indeo3,indeo4,indeo5,mjpeg,mp3,mpeg1video,mpeg2video,mpeg4,msmpeg4v2,msmpeg4v3,opus,pal8,paletteuse,pcm_s16le,pcm_s24le,prores,png,rawvideo,rv10,rv20,svq1,svq3,theora,tiff,vc1,vorbis,vp8,vp9,webp,wmv1,wmv2,wmv3 \
  --enable-demuxer=asf,avi,flc,flic,flv,gif,image2,image2pipe,matroska,mjpeg,mov,mp3,mp4,mpegps,mpegts,ogg,png,wav,webm,webp \
  --enable-parser=aac,ac3,flac,h263,h264,hevc,mpeg4video,mpegvideo,rawvideo,vorbis,vp8,vp9 \
  --enable-protocol=file \
  --enable-swscale \
  --enable-swresample \
  --enable-avformat \
  --enable-avcodec \
  --enable-avutil \
  --enable-zlib \
  --extra-cflags="-I../thirdparty/zlib" \
  --extra-ldflags="-LIBPATH:../bin/obj/thirdparty/zlib"

make -j16

Сборка динамической библиотеки

По умолчанию make собирает статические библиотеки. Если вам нужны dll, нужно добавить следующие флаги к configure:

./configure \
  ...
  --enable-shared \
  --disable-static

make -j16

Куда все собирается

Отдельный квест — найти собранные библиотеки и заголовочные файлы для того, чтобы потом можно было их использовать в своем проекте.

Библиотеки *.lib разбросаны по следующим папкам:

ffmpeg/libavcodec/avcodec.lib
ffmpeg/libavdevice/avdevice.lib
ffmpeg/libavfilter/avfilter.lib
ffmpeg/libavformat/avformat.lib
ffmpeg/libavutil/avutil.lib
ffmpeg/libswresample/swresample.lib
ffmpeg/libswscale/swscale.lib

При желании можете написать скрипт, который просто по всему репозиторию найдет все *.lib, *.dll, *.pdb и подложит в ваш проект.

Для заголовочников все немного сложнее. Вы должны, барабанная дробь.. Скопировать все заголовочные файлы *.h и *.hpp из репозитория и подложить их себе в проект с сохранением папочной структуры. Так же при желании можете написать скрипт, который сделает эту работу за вас. Задача со звездочкой для задротов — проанализировать скриптом каждый заголовочный файл, составить дерево зависимостей заголовочных файлов друг от друга и удалить те заголовочные файлы, на которые никто не ссылается %).


Раз уж я так козыряю возможностью написать под это все дело скрипты, было бы странно не показать, как с этим справляюсь лично я. Я делаю это питоном:

def make_dir(path):
    os.makedirs(path, exist_ok=True)

def remove_dir(path):
    shutil.rmtree(path, ignore_errors=True)

def copy_files(src, dst, extensisons: list[str], preserve_structure: bool = True):
    make_dir(dst)
    for root, dirs, files in os.walk(src):
        for file in files:
            if any(file.endswith(ext) for ext in extensisons):
                src_file = os.path.join(root, file)
                if preserve_structure:
                    rel_path = os.path.relpath(root, src)
                    dst_dir = os.path.join(dst, rel_path)
                    make_dir(dst_dir)
                    dst_file = os.path.join(dst_dir, file)
                else:
                    dst_file = os.path.join(dst, file)
                shutil.copy2(src_file, dst_file)

def copy_ffmpeg():
    remove_dir('app/ffmpeg_lib')
    remove_dir('app/ffmpeg_include')

    copy_files('ffmpeg', 'app/ffmpeg_lib', ['.lib', '.dll', '.pdb'], preserve_structure=False)
    copy_files('ffmpeg', 'app/ffmpeg_include', ['.h', '.hpp'], preserve_structure=True)

Выводы

Сборка ffmpeg под Windows — не самое приятное дело. Я хочу, чтобы эта инструкция сделала вашу жизнь с ffmpeg чуточку радостнее.

Любые поправки или альтернативные более простые способы сборки ffmpeg под Windows приветствуются в комментариях. Если вы просто хотите пожаловаться на ffmpeg — тоже пишите. Если вы хотите сказать, какой я нуб, и на самом деле все очень просто — это все я тоже с удовольствием почитаю.

Комментарии (20)


  1. Emelian
    26.02.2026 15:57

    Недавно пришлось собирать ffmpeg под Windows компилятором MSVC. И знаете — я чуть не помер.

    FFMpeg – большой, в его состав входит и FFPlay – консольный видео проигрыватель. А эта штука уже поинтересней будет для компиляции под «Форточки». Можно внедрить его в свое оконное приложение, как это, скажем, сделал я. Например, у меня есть неопубликованная программа «МедиаТекст».

    http://scholium.webservis.ru/Pics/MediaText.png

    Вот, с компиляцией «FFPlay.c» пришлось повозиться, поэтому, я вполне понимаю ваши трудности, тем более, что на Гитхабе я так ничего путного и не нашел.

    В итоге, я преобразовал Си-код в классы С++, что и позволило мне скомпилировать проект. Неплохо получилось, в итоге.


    1. AskePit Автор
      26.02.2026 15:57

      Очень интересное решение! Я правильно понял, что вы просто забрали исходный код и попытались скомпилировать его с нуля в обход их системы сборки?

      Так же интересуют подробности по внедрению целого ffplay в свое приложение. Я знаком с ffplay, и даже использовал его несколько раз в своих нуждах. Но я так понимаю - это само по себе готовое приложение, использующее библиотеку ffmpeg, просто очень тесно вплетенное в репозиторий и даже собирающееся по дефолту системой сборки. Вы судя по всему просто адаптировали код ffplay.c под свои нужды и как-то встроили в код своего приложения? Фактически, это модификация ffplay, или обвязка вокруг него, если можно так сказать?


      1. Emelian
        26.02.2026 15:57

        Очень интересное решение!

        Да, мне самому нравится! :)

        Я правильно понял, что вы просто забрали исходный код и попытались скомпилировать его с нуля в обход их системы сборки?

        Правильно!

        Так же интересуют подробности по внедрению целого ffplay в свое приложение. Я знаком с ffplay, и даже использовал его несколько раз в своих нуждах. Но я так понимаю - это само по себе готовое приложение, использующее библиотеку ffmpeg, просто очень тесно вплетенное в репозиторий и даже собирающееся по дефолту системой сборки. Вы судя по всему просто адаптировали код ffplay.c под свои нужды и как-то встроили в код своего приложения? Фактически, это модификация ffplay, или обвязка вокруг него, если можно так сказать?

        Да, это модификация файла «FFPlay.c», который был преобразован в классы «FFPlay.cpp».

        http://scholium.webservis.ru/Pics/FFPlay.png

        Каталоги включения:

        ./Main;./FFPlay;
        ../../Include;../../Include/FFmpeg;
        ../../Include/SDL2;
        $(VC_IncludePath);
        $(WindowsSdk_71A_IncludePath);
        $(VCInstallDir)include;
        $(VCInstallDir)atlmfc\include;
        $(WindowsSdkDir)include;
        $(FrameworkSDKDir)\include;

        Используемые библиотеки:

        avcodec.lib
        avdevice.lib
        avfilter.lib
        avformat.lib
        avutil.lib
        postproc.lib
        SDL2.lib
        swresample.lib
        swscale.lib

        Соответственно, для работы приложения нужны аналогичные dll.

        Код, за пределами модуля «FFPlay», я не модифицировал.

        В принципе, собираюсь делать вторую версию этой программы, тогда и опубликую ее код.

        P.S. Чем мне еще нравиться используемый медиа-проигрыватель, так это возможностью работы с mp3-файлами и файлами изображений (когда хочется, допустим, нецифровой pdf, т.е., просто набор сканов преобразовать, вручную, в текст. Для иностранных текстов это не слишком напрягает, так как, метод «запоминание руками» это базовый метод моей обучающей программы «L'école» (см. мои статьи здесь).


        1. AskePit Автор
          26.02.2026 15:57

          Вы заставили меня очень сильно задуматься) В том смысле, что я фактически сейчас пишу проигрыватель с нуля не опираясь на ffplay и сейчас задаюсь вопросом, действительно ли оно мне надо - все-таки это не так просто, особенно в паре с аудио.

          Я смотрел на реализацию плеера ffplay.c за вдохновением, но вдохновения не случилось, потому что там все очень заковыристо :) Но если пойти вашим путем и замести все эти заковырки за красивый фасад, то кому какое дело. Я попробую посмотреть в эту сторону, спасибо за идею


          1. Emelian
            26.02.2026 15:57

            если пойти вашим путем и замести все эти заковырки за красивый фасад, то кому какое дело

            Да, этот путь вполне рабочий. Все сопутствующие dll:

            avcodec-58.dll
            avdevice-58.dll
            avfilter-7.dll
            avformat-58.dll
            avutil-56.dll
            libfreetype-6.dll
            postproc-55.dll
            SDL2.dll
            swresample-3.dll
            swscale-5.dll

            занимают более 72 мегабайт, а моя программа Main64r.exe – менее 530 килобайт. Все вместе это немного громоздко, зато полностью собственное решение.

            Файлы «FFPlay.cpp» и «FFPlay.h» вместе дают чуть более 200 килобайт. Файл «Defs.h» почти 100%-но родной, я там поправил какую-то мелочь. Именно там идет ссылка на все библиотеки поддержки.

            Так, что переработать вручную 200 килобайт опенсорсного кода, не должно быть слишком трудной задачей.

            Еще большим плюсом, для себя, я считаю использование сверхлегкого фреймворка WTL, с общим размером, в исходниках, менее полутора мегабайт. В моем проекте, он мне сильно помог.


  1. Alexsey
    26.02.2026 15:57

    Что-то мне даже в голову не приходят причины почему можно захотеть собирать ffmpeg руками. На официальном сайте есть ссылки на аж два разных места где есть актуальные сборки из мастер ветки в разных вариантах.

    https://www.ffmpeg.org/download.html#build-windows

    Одно из мест собирает их на гитхабе поэтому если надо собрать какую-то особенную сборку можно просто форкнуть репозиторий и подкрутить CI/CD:

    https://github.com/BtbN/FFmpeg-Builds/blob/master/.github/workflows/build.yml


    1. AskePit Автор
      26.02.2026 15:57

      да, мне нужна была кастомная сборка

      мне если честно ваш вариант с форком не пришел в голову, так же как вам мой :) а что, таким образом можно будет получить сборку msvc-тулчейном?


      1. Alexsey
        26.02.2026 15:57

        В репозитории оно кросс-компилит через mingw32-gcc на линуксе насколько я вижу. Если нужен конкретно msvc, то тут, конечно не подойдет.

        Есть вот такой репо, но насколько там актуальный CI/CD для сборки последних версий - сложно сказать:

        https://github.com/System233/ffmpeg-msvc-prebuilt


    1. Siemargl
      26.02.2026 15:57

      Что-то мне даже в голову не приходят причины почему можно захотеть собирать ХХ руками.

      Джедаи опенсорса могут движением мысли исправлять баги, уязвимости и исправлять программы движением мысли.

      Так что это всего лишь желание познать путь


    1. Balling
      26.02.2026 15:57

      Там сборка gcc. А вообще msvc легко ломается https://github.com/FFmpeg/FFmpeg/commit/3c03048837dd72df38dabecc4c23258d67612548


  1. arteast
    26.02.2026 15:57

    Отдельный квест — найти собранные библиотеки и заголовочные файлы для того, чтобы потом можно было их использовать в своем проекте.

    `configure --prefix=...` и потом `make install` вам чем не нравится?


    1. AskePit Автор
      26.02.2026 15:57

      очень даже нравится


  1. Klochko
    26.02.2026 15:57

    А можно ли как-то собрать минимальную сборку? Допустим мне нужно работать только с аудио и только с ogg и mp3.

    Есть ли возможность скомпилировать крохотный ffmpeg?


    1. AskePit Автор
      26.02.2026 15:57

      Да, при сборке ffmpeg можно конфигурировать очень гибко и повыбрасывать из него очень многое. Я не уверен, до каких пределов его можно ужать и, боюсь, это придется проверять экспериментально методом проб, ошибок и крашей, если вырезал слишком много


  1. unreal_undead2
    26.02.2026 15:57

    Так а в чём сложность то? Насколько вижу - просто получили шелл msys с настроенным окружением VC и дальше ./configure;make , из нетривиального разве что спрятать link от msys и "удаляем rem из строки rem set MSYS2_PATH_TYPE=inherit".

    Лет пятнадцать назад надо было по работе собрать Chromium на Windows XP с немного пропатченным V8 - там танцы с бубном начинались уже с протаскиванием репозиторев через корпоративный прокси.


    1. AskePit Автор
      26.02.2026 15:57

      Ну, если следовать по проторенной инструкции, сложности нет :)
      А так вы правы - самое попившее кровь - это то, что вы перечислили. Просто мне не сразу довелось прийти к этим хакам - подсказки лежали то тут, то там в разных мануалах от разных людей


      1. unreal_undead2
        26.02.2026 15:57

        Я про сложность самой инструкции. Вот тут поинтереснее - исходники слегка побились. Несколько лет назад из интереса собирал оригинальную Adventure из этих исходников - то же самое, похоже применили форматирование, а старый фортран чувствителен к отступам, пришлось руками править.


  1. crackedmind
    26.02.2026 15:57

    В vcpkg давно есть рецепт под сборку этой хрени.


    1. AskePit Автор
      26.02.2026 15:57

      Супер! Можно какую-то ссылку? Боюсь найти не то


  1. fedorro
    26.02.2026 15:57

    На гитхабе есть кросс-компилятор прямо в образах докера - нужен просто докер под любой ОС и получаются хорошие бинарники - сам их использую, собирал в Убунте.