Недавно пришлось собирать 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 -Syupacman -S makepacman -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)

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

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

Alexsey
26.02.2026 15:57В репозитории оно кросс-компилит через mingw32-gcc на линуксе насколько я вижу. Если нужен конкретно msvc, то тут, конечно не подойдет.
Есть вот такой репо, но насколько там актуальный CI/CD для сборки последних версий - сложно сказать:

Siemargl
26.02.2026 15:57Что-то мне даже в голову не приходят причины почему можно захотеть собирать ХХ руками.
Джедаи опенсорса могут движением мысли исправлять баги, уязвимости и исправлять программы движением мысли.
Так что это всего лишь желание познать путь

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

Klochko
26.02.2026 15:57А можно ли как-то собрать минимальную сборку? Допустим мне нужно работать только с аудио и только с ogg и mp3.
Есть ли возможность скомпилировать крохотный ffmpeg?

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

unreal_undead2
26.02.2026 15:57Так а в чём сложность то? Насколько вижу - просто получили шелл msys с настроенным окружением VC и дальше ./configure;make , из нетривиального разве что спрятать link от msys и "удаляем
remиз строкиrem set MSYS2_PATH_TYPE=inherit".Лет пятнадцать назад надо было по работе собрать Chromium на Windows XP с немного пропатченным V8 - там танцы с бубном начинались уже с протаскиванием репозиторев через корпоративный прокси.

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

fedorro
26.02.2026 15:57На гитхабе есть кросс-компилятор прямо в образах докера - нужен просто докер под любой ОС и получаются хорошие бинарники - сам их использую, собирал в Убунте.
Emelian
FFMpeg – большой, в его состав входит и FFPlay – консольный видео проигрыватель. А эта штука уже поинтересней будет для компиляции под «Форточки». Можно внедрить его в свое оконное приложение, как это, скажем, сделал я. Например, у меня есть неопубликованная программа «МедиаТекст».
http://scholium.webservis.ru/Pics/MediaText.png
Вот, с компиляцией «FFPlay.c» пришлось повозиться, поэтому, я вполне понимаю ваши трудности, тем более, что на Гитхабе я так ничего путного и не нашел.
В итоге, я преобразовал Си-код в классы С++, что и позволило мне скомпилировать проект. Неплохо получилось, в итоге.
AskePit Автор
Очень интересное решение! Я правильно понял, что вы просто забрали исходный код и попытались скомпилировать его с нуля в обход их системы сборки?
Так же интересуют подробности по внедрению целого ffplay в свое приложение. Я знаком с ffplay, и даже использовал его несколько раз в своих нуждах. Но я так понимаю - это само по себе готовое приложение, использующее библиотеку ffmpeg, просто очень тесно вплетенное в репозиторий и даже собирающееся по дефолту системой сборки. Вы судя по всему просто адаптировали код ffplay.c под свои нужды и как-то встроили в код своего приложения? Фактически, это модификация ffplay, или обвязка вокруг него, если можно так сказать?
Emelian
Да, мне самому нравится! :)
Правильно!
Да, это модификация файла «FFPlay.c», который был преобразован в классы «FFPlay.cpp».
http://scholium.webservis.ru/Pics/FFPlay.png
Каталоги включения:
Используемые библиотеки:
Соответственно, для работы приложения нужны аналогичные dll.
Код, за пределами модуля «FFPlay», я не модифицировал.
В принципе, собираюсь делать вторую версию этой программы, тогда и опубликую ее код.
P.S. Чем мне еще нравиться используемый медиа-проигрыватель, так это возможностью работы с mp3-файлами и файлами изображений (когда хочется, допустим, нецифровой pdf, т.е., просто набор сканов преобразовать, вручную, в текст. Для иностранных текстов это не слишком напрягает, так как, метод «запоминание руками» это базовый метод моей обучающей программы «L'école» (см. мои статьи здесь).
AskePit Автор
Вы заставили меня очень сильно задуматься) В том смысле, что я фактически сейчас пишу проигрыватель с нуля не опираясь на ffplay и сейчас задаюсь вопросом, действительно ли оно мне надо - все-таки это не так просто, особенно в паре с аудио.
Я смотрел на реализацию плеера ffplay.c за вдохновением, но вдохновения не случилось, потому что там все очень заковыристо :) Но если пойти вашим путем и замести все эти заковырки за красивый фасад, то кому какое дело. Я попробую посмотреть в эту сторону, спасибо за идею
Emelian
Да, этот путь вполне рабочий. Все сопутствующие dll:
занимают более 72 мегабайт, а моя программа Main64r.exe – менее 530 килобайт. Все вместе это немного громоздко, зато полностью собственное решение.
Файлы «FFPlay.cpp» и «FFPlay.h» вместе дают чуть более 200 килобайт. Файл «Defs.h» почти 100%-но родной, я там поправил какую-то мелочь. Именно там идет ссылка на все библиотеки поддержки.
Так, что переработать вручную 200 килобайт опенсорсного кода, не должно быть слишком трудной задачей.
Еще большим плюсом, для себя, я считаю использование сверхлегкого фреймворка WTL, с общим размером, в исходниках, менее полутора мегабайт. В моем проекте, он мне сильно помог.