Слогер Создать блог
Разработка

Почему ffmpeg.wasm пишет «FS error: readFile», хотя файл должен быть

Разбор ошибки, которая возникает, когда проверяют существование файла вместо наличия аудиодорожки. И почему ffmpeg.run() не сообщает о сбое.

Пользователь прислал два клипа и скриншот. Инструмент для склейки видео отработал до 100%, написал «Applying transitions…» и упал с ошибкой: FS error: readFile 'merged.mp4'.

Ошибка честная и бесполезная. merged.mp4 действительно не существует. Но почему — непонятно, потому что процесс, который должен был его создать, уже завершился и ушёл дальше.

Знакомо? Разберём, как такое получается.

Суть проблемы: проверяли не то

Инструмент сначала приводит клипы к одному размеру, частоте кадров и кодеку, а потом склеивает. Если нужен переход — картинка через xfade, звук через acrossfade.

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

Задумано было одно: если кодирование не удалось из-за отсутствия аудиодорожки, повторить с генератором тишины. Реализовано другое: если выходной файл отсутствует, повторить. Это не одно и то же.

ffmpeg, получив видео без звука и флаг -c:a libmp3lame, не падает. Он просто кодирует видео, не пишет аудиодорожку и выходит успешно. Файл существует. catch не срабатывает. А переход дальше строит фильтр [0:a][1:a]acrossfade — и не находит [0:a]. Всё падает уже на этапе склейки, а ошибка приходит поздно и показывает не ту строку.

Почему баг не всплывал раньше

Клипы со звуком работали идеально. Я тестировал на записях экрана с микрофоном и на телефонных видео. А вот файлы вообще без аудиодорожки — это AI-генерации, большинство экранных записей, видео, из которых звук уже вырезали. Это не экзотика, а целый класс обычных файлов.

Вторая причина интереснее. ffmpeg.wasm не отклоняет промис при ошибке ffmpeg. Метод run() разрешается независимо от того, успешно ли выполнилась команда. Поэтому любая ошибка внутри ffmpeg приходит поздно и валит не ту строку.

Что делать: проверять свойство, а не факт существования

Нельзя вывести «есть аудио» из «появился файл». Надо спросить напрямую. Функция hasAudio делает пробу: ffmpeg с параметрами -i, -vn, -map 0:a:0, -c copy, -t 0.05 пишет крошечный файл. Если в исходнике есть первая аудиодорожка — файл создаётся. Нет — не создаётся. Это стоит копейки по времени и отвечает на нужный вопрос.

Дальше команда выбирается один раз, без попытки починить результат: если звука нет, сразу добавляется anullsrc. Такой подход надёжнее, чем сначала запустить, потом ловить ошибку и переделывать.

Как тестировать код, который работает только в браузере

Ни на машине, ни на сервере ffmpeg-бинаря нет — весь смысл в том, что код исполняется в браузере пользователя через WebAssembly. Обычный headless-сценарий зависает, потому что виртуальное время в headless Chrome не сдвигает web worker.

Сработала страница, которая собирает фикстуры через lavfi, гоняет реальные проверки и отправляет результаты в PHP-файл POST-запросом. Один из тестов — проверка диагноза: acrossfade на двух клипах без звука не даёт выходного файла. Это важнее, чем тест самого исправления. Сначала докажи, что виноват именно тот компонент, который ты собрался чинить.

Общий паттерн ошибки

Завершение операции — не доказательство, что она сделала то, что нужно. Это доказательство, что она не упала.

Тот же паттерн встречается в другом виде:

  • файл существует — значит, запись прошла успешно
  • HTTP вернул 200 — значит, ответ содержит нужный ресурс
  • команда вышла с кодом 0 — значит, она выдала результат
  • catch не сработал — значит, всё пошло по плану

Каждая из этих проверок смотрит не на тот объект. Лечится одинаково: назвать свойство, от которого реально зависит код, и проверять именно его. Это всегда выглядит как лишняя работа, но именно она спасает от ошибок.

Косвенная проверкаПрямой вопрос
Выходной файл существуетВ исходнике есть аудиодорожка?
HTTP-статус 200В теле ответа нужные данные?
Код возврата 0В выводе есть результат?
catch не выполнилсяСценарий завершился без ошибки?

И добавляем подстраховку: если переход теперь упадёт по другой причине, инструмент склеит клипы без перехода и скажет об этом, а не выдаст бесполезное FS error.

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

По материалам: dev. Текст переработан редакцией Слогера.

← На главную

Рекламное место — Конец поста
Реклама · Слогер

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

Войдите, чтобы комментировать.

MdTaj Munshi 13.09.2026 11:11 ▲ 0
This is a very insightful and informative article. I really enjoyed reading it and appreciate the effort put into sharing these helpful details. Looking forward to reading more updates like this!
Маркетинг

Как писать рассылки для клиентов на бесплатных инструментах: разбор рабочего процесса

Один ретейнер на $450 в месяц за восемь выпусков в год показал: услуга по написанию email-рассылок держится не на платных сервисах, а на голосе бренда и редакторской дисциплине. Разбираю стек, процесс, цены и типичные провалы.

Слогер 29.09.2026 ▲ 0
Карьера

Разбор: как устроен рынок Gmail-аккаунтов на продажу и почему покупка почти всегда убыточна

Свежие, PVA и aged-аккаунты продают за 1–5 долларов, обещая мгновенный старт и полную конфиденциальность. Разбираем, что скрывается за этими объявлениями, где тут риск и какие есть легальные способы получить нужное количество ящиков.

Слогер 29.09.2026 ▲ 1
Разработка

Почему «сколько кода я написал» — плохая метрика: как оценивать себя как программиста

Считать строки и гордиться тем, что всё написано из памяти, — привычка, которая мешает доводить проекты до конца. Разбираю, какие вопросы о своём коде стоит задавать вместо этого.

Слогер 29.09.2026 ▲ 0
Разработка

Как получать деньги через GitHub Sponsors: выплаты, налоги и частые ошибки

Sponsors не превратился в новую платёжную систему — изменилась обвязка вокруг выплат: налоги, фискальные хосты и биллинг. Разбираем, что нужно настроить до того, как профиль станет публичным.

Слогер 29.09.2026 ▲ 0
Fluxs lenta
Реклама · fluxs.ru
Разработка

Электронный документооборот в Fluxs: как договор перестаёт теряться между кабинетами

Во вторник договор ушёл юристу. В четверг клиент спрашивает, когда подпишем. Юрист говорит, что давно отдал в бухгалтерию. Бухгалтерия ничего не получала. В пятницу вечером договор находится — в почте у финансового директора, который в отпуске. Никто не ленился. Просто у документа не было маршрута. Мы сделали в Fluxs модуль «Документооборот». Коротко, что в нём есть: — маршрут согласования рисуется схемой: параллельные ветки, условие «если сумма больше миллиона — к финдиректору»; — сроки в рабочих часах, напоминания, передача руководителю при просрочке; — подпись кодом из письма или КЭП через КриптоПро прямо в браузере; — клиент согласует договор по ссылке, без регистрации; — ознакомление с приказами без листа с подписями. И отдельно про безопасность: если кто-то поправит решение или подпись прямо в базе, это будет видно в карточке документа. Модуль бесплатный с тарифа «Бизнес». Как

Слогер 28.09.2026 ▲ 0
Карьера

Как зарабатывать на переводе и локализации без диплома: разбор воркфлоу на бесплатных инструментах

Процесс, который позволяет брать $340 за один заказ и превращать разовые сделки в ежемесячные ретейнеры — без дорогого софта и профильного образования.

Слогер 28.09.2026 ▲ 0
Образование

Как проверить старые соцсети перед визой и учёбой за рубежом: 6 категорий и порядок действий

Аккаунты — единственный пункт в списке документов, который нельзя восстановить задним числом. Разбираем, что искать в собственных постах и почему удаление поста — лишь первый шаг.

Слогер 28.09.2026 ▲ 0
Карьера

Чистка цифрового следа перед собеседованием: график на 6 недель и что уже поздно начинать

Рекрутеры чаще гуглят кандидата не на этапе отклика, а когда он уже в шортлисте. Отсюда и запас времени, и жёсткий дедлайн — разбираем обратный отсчёт по неделям.

Слогер 28.09.2026 ▲ 0
Fluxs lenta
Реклама · fluxs.ru
Образование

Как учиться сложным вещам: система, где знания проверяются действием, а не перечитыванием

Пять приёмов из практики преподавания и self-learning в кибербезопасности: карта вместо первой страницы, worked examples, извлечение из памяти, интервалы и цикл «сломал — починил — объяснил».

Слогер 28.09.2026 ▲ 0
Карьера

Как подготовиться к собеседованию по кодингу: 7 книг и порядок, в котором их читать

Провал на интервью редко связан с тем, что вы не умеете программировать. Чаще не хватает системы, словаря для разговора о дизайне и практики объяснять решение вслух — и всё это можно закрыть книгами.

Слогер 27.09.2026 ▲ 0
Карьера

Как откликаться на вакансии без диплома: разбор фильтра, который отсеивает за две минуты

Junior-вакансия с Python, SQL и автоматизацией, три документа от кандидата — и отказ через 120 секунд после отправки. Разбираем, что здесь происходит и как проходить такие воронки, если диплома нет.

Слогер 27.09.2026 ▲ 0
Fluxs lenta
Реклама · fluxs.ru