Данная статья предназначена для тех, кто заинтересован в сохранении воспроизводимости своих записей на случай внезапного системного сбоя. Далее будут описаны харатктерные особенности целых и поврежденных файлов, записанных в нескольких наиболее известных форматах как MP4, MOV, MKV, FLV, рассмотрены особенности изменений в структуре файлов при различных условиях записи. Данная группа файлов была записана в штатных условиях без угрозы внезапной остановки записи. Можно заметить, что файл состоит из четырех атомов корневого уровня ftyp, free, mdat, moov, в соответствии со структурой описанной в официальной спецификации формата медиаконтейнера MP4. Все величины в таблице представлены в байтах. В первом столбце отображено начало блока памяти для каждого атома, во втором - размер данных занимаемых атомом. Таким образом, расположение каждого следующего атома в памяти складывается из размеров всех предыдущих атомов. Содержимое moov атома имеет особо важное значение для воспроизведения видеоматериала, так как именно в этом месте находится описание информации о том как файл должен быть расшифрован. Для расшифровки файла, чтобы его воспроизвести необходимо установить однозначное соответствие между данными и способами их чтения. Поэтому необходимо знать количество потоков, какой формат данных содержат потоки, какие кодеки совместимы для декодирования. Следует обратить внимание на расположение moov атома в памяти файла. Обычно он расположен в конце файла, что не всегда полезно и безопасно при записи. По этой причине не рекомендуется вести запись в MP4 из-за угрозы получения невоспроизводимого файла в результате внезапного прекращения записи. Такая ситуация возможна при системных сбоях, потере питания и в случае непредвиденного завершения процесса записывающего ПО. Метаданные извлекаются с помощью ffprobe следующим образом. ffprobe -hide_banner video.mp4 2> mp4.txt В структуре MOV нет особых различий со структурой MP4, файл все также состоит из четырех атомов корневого уровня, но вместе атома free используется атом wide равный ему по размеру. В таких атомах содержится информация о неиспользуемом пространстве памяти. Узнать подробнее про формат медиаконтейнера MOV можно в официальной спецификации формата медиаконтейнера MOV. В MOV по аналогии с MP4 все метаданные находятся в moov атоме в конце файла. Метаданные извлекаются с помощью ffprobe следующим образом. ffprobe -hide_banner video.mov 2> mov.txt Структура MKV уже была описана ранее в официальной спецификации формата медиаконтейнера MKV. Основное отличие от прошлых двух контейнерных форматов в том, что данные по умолчанию записываются небольшими фрагментами, вместо одного общего блока информации в случае с mdat для MP4 и MOV. Такая особенность позволяет избавиться от проблемы критического повреждения файлов в случае внезапного прекращения записи, так как метаданные содержатся в каждом отдельном фрагменте. Метаданные извлекаются с помощью ffprobe следующим образом. ffprobe -hide_banner video.mkv 2> mkv.txt Структура MKV уже была описана ранее в официальной спецификации формата медиаконтейнера FLV. В хранении информации используется идентичный способ с MKV. Видео располагается в памяти фрагментами, но содержимое атомов отличается. Метаданные извлекаются с помощью ffprobe следующим образом. ffprobe -hide_banner video.flv 2> flv.txt Если запись была внезапно прервана есть довольно большая вероятность получить невоспроизводимый файл на выходе. Подробнее узнать причину ошибки можно узнать посмотрев логи через ffprobe в консоли ffprobe -v error video.mp4 2> mp4_error.txt Лог ошибки выглядит следующим образом для файла  По ошибке “moov atom not found” можно понять, что метаинформацию извлечь не получится, так как не найден moov атом. Дело в том, что запись закончилась раньше, чем планировалось и moov атом физически не был записан в память. Последний доступный атом в данном случае будет mdat.  Соответственно, если попробовать достать любую метаинформацию файла, то вывод будет пустой Например,  ffprobe -hide_banner video.mp4 2> mp4.txt В MOV файлах будет наблюдаться похожая ситуация, но как и в прошлый раз разница будет только в названии и размере некоторых корневых атомов структуры. Сам файл воспроизводиться не будет. ffprobe -v error video.mov 2> mov_error.txt Moov атом здесь не наблюдается, как и в MP4, что не позволяет извлечь метаинформацию  ffprobe -hide_banner video.mov 2> mov.txt Записанный в условиях внезапной остановки записи MKV файл пострадает меньше по сравнению с MP4 или MOV. Его можно будет воспроизвести, но нельзя перемотать и узнать продолжительность в некоторых плеерах. В этом можно убедиться после извлечения метаданных. Значению поля Duaration соответствует N/A, это значит, что оно не было определено. Также отсутствуют значения длительности для видео и аудио потоков и битрейт. Вывод метаданных для поврежденного MKV файла будет сопровождаться сообщением об преждевременном окончании файла, но в данном случае это повлияет лишь на последний фрагмент в течение записи которого была прервана запись. Поврежденный FLV файл воспроизводится, но так же не имеет определенного значения длины, записанного в поле Duration, как и поврежденный MKV файл, тем не менее информация о начальной отметке времени осталась. Что касается битрейта, то его все также нет. Дело в том, что значения полей Duration и Bitrate вычисляются в самом конце, а не пересчитываются каждый раз после окончания записи каждого отдельного фрагмента, так как это спровоцировало бы дополнительную нагрузку на систему. Вывод поломанного FLV файла содержит несколько больше информации о повреждениях. Видно на каком именно пакете прервалась запись и к какому потоку он относился. В данном случае проблема была обнаружена в момент декодирования пакета в потоке видео с dts = 9734. Более вероятно возникновение ошибки именно в видео потоке, так как обычно объем видеоданных занимает в разы больше места, чем аудио, соответственно и времени на его расшифровку тратится пропорционально больше. DTS (decoding time stamp) - время декодирования опорного кадра, который требуется для отображения текущего в базовых единицах. Может совпадать с PTS (presentation time stamp) если текущий кадр опорный. Как правило базовая единица задается в виде дроби с числом тактов в числителе и частотой тактового генератора в знаменателе. В итоге в процессе расшифровки декодировщик не может получить доступ к объекту в памяти, потому что его не существует и выполнение чтения заканчивается ошибкой. Предварительно настроенная запись отличается от обычной, тем что в качестве дополнительной настройки используется параметр faststart, который помогает предотвратить проблему критического повреждения MP4 и MOV файлов путем перемещения moov атома в начало файла. Для MKV и FLV данный параметр не имеет большого смысла, так как в их структуре отсутствует отдельный атом с общими метаданными, как moov. Теперь подверженный повреждению файл в условиях внезапной остановки записи удалось оставить воспроизводимым и читаемым. На изображении снизу можно изучить структуру полученного после записи файла. На этот раз moov атом был записан в начале файла после ftyp. Раньше он располагался в самом конце после атома mdat. Метаданные вновь читаются, причем значения для полей duration и bitrate определены, несмотря на то, что запись была прервана внезапно.   В структуре MOV файла произошли изменения в порядке записи корневых атомов, как и в MP4. Moov атом остался неповрежденным и расположен в начале файла. Воспроизведение файла не нарушено. Дополнительно убедиться в целостности файла можно после извлечения метаданных Для MKV файлов особого эффекта параметр “faststart” не имеет, файл имеет повреждения, полученные в результате внезапной остановки записи. Файл возможно воспроизвести, но как и в прошлый раз без значений длительности и битрейта. Вывод метаданных сопровождается ошибкой. Никаких особых изменений в лучшую сторону для flv файла использованный параметр не дал. Все старые проблемы остались. Длительность в результате записи осталась нулевой, битрейт неизвестен, тем не менее файл воспроизводится. Еще один вариант предварительной настройки записи, который позволяет добиться фрагментированной записи в файл вместо хранения всей информации в едином атоме. empty_moov приведет к фрагментации вывода на 100%; без этого первый фрагмент будет мультиплексирован, как короткий фильм (с использованием moov), за которым следуют остальные медиафайлы во фрагментах frag_keyframe вызывает фрагментированный вывод Использовав дополнительные параметры, удалось сохранить воспроизводимость файла в условиях внезапной остановки записи. В структуре файла наблюдаются заметные изменения. Moov атом расположен в начале файла, далее следует последовательность из двух повторяющихся практически до конца атомов moof и mdat. В этих двух атомах содержится вся необходимая информация о каждом отдельном фрагменте видео. Moof атом - аналог moov для фрагмента записи, mdat - атом содержащий потоки. Завершается файл атомом mfra. C извлечением метаданных нет особых в данном случае. В метаданных присутствует длительность, тем не менее в некоторых плеерах отсутствует возможность перемотки и не отображается длительность. Что касается структуры MOV файла, то она так же сильно изменена и больше напоминает структуру MKV или FLV файлов из-за последовательности фрагментов, записанных в атомы moof и mdat. Повреждений метаданных в данном случае не наблюдается. Особого эффекта или изменений в худшую или лучшую сторону не наблюдается. Особого эффекта или изменений в худшую или лучшую сторону не наблюдается. Мультиплексирование в obs осуществляется при помощи ffmpeg, соответственно все указанные в данном примере настройки имели бы следующий вид: ffmpeg -i input <encoding parameters> -movflags +frag_keyframe+empty_moov out.[mp4/mov] Пример создания фрагментированного MP4 файла (fMP4) из стандартного MP4 файла ffmpeg -i video.mp4 -g 52 -c:a aac -c:v libx264 -f mp4 -movflags frag_keyframe+empty_moov fragmented_video.mp4 Альтернативный вариант предварительной настройки записи, который позволяет добиться фрагментированной записи в файл вместо хранения всей информации в едином атоме. empty_moov приведет к фрагментации вывода на 100%; без этого первый фрагмент будет мультиплексирован, как короткий фильм (с использованием moov), за которым следуют остальные медиафайлы во фрагментах separate_moof инициирует создание отдельного атома moof (фрагмента видео) для каждого потока. Обычно пакеты для всех потоков записываются в moof atom (что немного эффективнее), но с этой установленной опцией мультиплексор записывает одну пару moof/mdat для каждой потоков, что упрощает разделение дорожек. frag_keyframe вызывает фрагментированный вывод omit_tfhd_offset отменяет запись абсолютного значения base_data_offset в атомах tfhd. Это позволяет избежать привязки фрагментов к абсолютным позициям байтов в файле/потоках. Следующие настройки позволяют создавать фрагментированный MP4 (fMP4), который вы сможете просмотреть во время преобразования. Однако для просмотра будут доступны только фрагменты, полностью закодированные на момент запуска файла. Чтобы просмотреть фрагменты, закодированные после этой точки, вам придется перезагрузить источник просмотра. Аналогично прошлому примеру с фрагментацией файл состоит из последовательности атомов корневого уровня mdat и moof и имеет moov атом вначале. Таким образом, данный способ наравне с предыдущим позволяет избежать повреждения метаданных файла в условиях внезапного прекращения записи, что фактически гарантирует возможность дальнейшего воспроизведения файла.  Эти настройки также применимы в случае с MOV файлами и на выходе дают сравнимый результат Как результат здесь так же сохраненные метаданные и нормальная воспроизводимость файла Особого эффекта или изменений в худшую или лучшую сторону не наблюдается. Особого эффекта или изменений в худшую или лучшую сторону не наблюдается. Мультиплексирование в obs осуществляется при помощи ffmpeg, соответственно все указанные в данном примере настройки имели бы следующий вид: ffmpeg -i input <encoding parameters> -movflags +frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov out.[mp4/mov] Чтобы уменьшить вероятность утраты доступа к записанным видеофайлам лучше задуматься сразу над тем, как избежать негативных последствий при возникновении аппаратных или системных проблем на записывающем устройстве. Сделать это можно, выбрав один из более отказоустойчивых форматов записи, как MKV/FLV или, если выходной формат принципиально важен, то воспользоваться одним из методов предотвращения крашей в MP4/MOV из статьи. Восстанавливать убитый файл, гораздо труднее и не всегда возможно. Для тех, кто уже столкнулся с этой проблемой и еще ищет решения возможно будет полезна следующая статья, посвященная теме восстановления MP4/MOV файлов. FFMPEG FFPROBE MP4 Specification / Краткое описание формата MP4 MOV Specification / Краткое описание формата MOV MKV Specification / Краткое описание формата MKV FLV Specification / Краткое описание формата FLV