MKV
MKV (Matroska Video, читается "матрёшка", а не "матроска") – это открытый контейнерный формат мультимедиа, разработанный в 2002 году. Он предназначен для хранения видео, аудио, субтитров и метаданных в одном файле. Формат является гибким и расширяемым, что позволяет использовать его для различных целей, включая потоковую передачу данных, создание Blu-ray дисков и многое другое. Основная цель разработки MKV заключалась в создании универсального контейнера, который мог бы поддерживать множество форматов видео и аудио без привязки к конкретным кодекам.
Несмотря на солидный возраст, MKV получил ограниченную поддержку. Вы не можете рассчитывать, что он откроется в произвольной программе. Поэтому он плохо подходит для хранения архивов и рабочих материалов. Но распространенные программные плееры его открывают хорошо, чего нельзя сказать про аппаратные плееры, веб-сервисы, оболочки NAS тд.
Основные характеристики MKV:
- Открытый стандарт: проект Matroska поддерживается сообществом разработчиков и доступен под лицензией LGPL.
- Поддержка множества потоков: может содержать несколько видеопотоков, аудиодорожек и субтитров одновременно.
- Расширяемость: благодаря модульному подходу, формат легко адаптируется под новые технологии и стандарты.
- Совместимость: поддерживает широкий спектр видео- и аудиоформатов, таких как H.264/AVC, HEVC/H.265, AAC, MP3 и многие другие.
Структура файла MKV
Файл MKV состоит из блоков EBML (Extensible Binary Meta Language), которые определяют структуру контейнера. Вот основные элементы структуры:
- EBML Header: Заголовок, содержащий информацию о версии формата и глобальные настройки.
- Segment: Основной блок, включающий все остальные элементы.
- Cluster: Блок, содержащий фрагменты видео и аудио данных.
- Tracks: Описывают потоки видео, аудио и субтитры.
- Attachments: Дополнительная информация, такая как обложки альбомов, шрифты для субтитров и т.п.
- Chapters: Разделы внутри видео, позволяющие переходить между ними.
- Tags: Метаданные, такие как название фильма, автор, жанр и др.
Пример структуры файла MKV:
EBML Header
Segment
SeekHead (информация для быстрого поиска)
Info (общая информация о сегменте)
Tracks (описание видеопотока, аудиопоотов и субтитров)
Chapters (разделы видео)
Attachments (вложенные файлы)
Tags (метаданные)
Cluster (видео и аудиофрагменты)
::: success При записи MKV записывает метаданные параллельно с медиаданными. Это делает файл устойчивым к аварийному прерыванию записи -- уже записанные данные будут читаться, если запись неожиданно прервать.
:::
Преобразование видео в MKV c перекодированием в FFMPEG
Для преобразования видео из одного формата в другой с сохранением в контейнере MKV можно использовать следующую команду:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mkv
Где:
input.mp4– исходный файл,libx264– кодек для сжатия видео (H.264),crf 23– параметр качества видео (чем меньше значение, тем выше качество),aac– кодек для сжатия аудио (Advanced Audio Coding),128k– битрейт аудио,output.mkv– выходной файл в формате MKV.
Добавление нескольких аудиодорожек
Чтобы добавить несколько аудиодорожек в один файл MKV, можно воспользоваться следующей командой:
ffmpeg -i video.mp4 -i audio1.wav -i audio2.wav \
-map 0:v -map 1:a -map 2:a \
-c copy output.mkv
Здесь:
video.mp4,audio1.wav,audio2.wav– исходные файлы,-map 0:v– копирование видеопотока из первого файла,-map 1:aи-map 2:a– добавление двух аудиодорожек из второго и третьего файлов,-c copy– копирование потоков без перекодирования,output.mkv– результирующий файл.
Извлечение отдельных дорожек
Для извлечения отдельной дорожки (например, субтитров) из файла MKV можно использовать такую команду:
ffmpeg -i input.mkv -map 0:s:0 subtitles.srt
Где:
input.mkv– входной файл,-map 0:s:0– выбор первой субтитровой дорожки,subtitles.srt– выходной файл с субтитрами в формате SRT.
Перенос потоков из MKV в MP4 без перекодирования
::: success При записи внешних потоков лучше использовать контейнер MKV на случай аварийного прерывания записи (отключение питания, программный сбой) -- уже записанная до сбоя часть файла будет читаться. Но для большей совместимости удобнее хранить файлы в контейнере MP4. Следующая команда поможет переложить запись между контейнерами быстро и без потери качества, здесь не используется пережатие содержимого, только меняется контейнер.
:::
ffmpeg -i input.mkv -c copy output.mp4
Где:
-i input.mkv: указывает путь к входному файлу в формате MKV.-c copy: сообщаетffmpegо необходимости копирования всех потоков без их перекодирования.output.mp4: имя выходного файла в формате MP4.
Работа с MKV через GStreamer
GStreamer – это фреймворк для обработки мультимедийных данных, также поддерживающий работу с файлами MKV. Рассмотрим пример создания простого плеера на основе GStreamer.
Простое воспроизведение видео
Для воспроизведения видео в формате MKV можно использовать следующий код на Python:
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst
Gst.init(None)
pipeline = Gst.Pipeline()
source = Gst.ElementFactory.make("filesrc", None)
source.set_property("location", "video.mkv")
demuxer = Gst.ElementFactory.make("matroskamux", None)
decoder = Gst.ElementFactory.make("decodebin", None)
sink = Gst.ElementFactory.make("autovideosink", None)
pipeline.add(source, demuxer, decoder, sink)
Gst.element_link_many(source, demuxer, decoder, sink)
loop = GObject.MainLoop()
pipeline.set_state(Gst.State.PLAYING)
try:
loop.run()
except KeyboardInterrupt:
pass
finally:
pipeline.set_state(Gst.State.NULL)
Этот скрипт создает простой граф потока, состоящий из источника (filesrc), демультиплексора (matroskamux), декодера (decodebin) и вывода (autovideosink). При запуске он воспроизводит видео из файла video.mkv.
Демонстрация поддержки метаданных
GStreamer также позволяет работать с метаданными, содержащимися в файлах MKV. Например, можно получить информацию о названии фильма, жанре и других параметрах:
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst
def on_tag(bus, msg):
taglist = msg.parse_tag()
if taglist is not None:
for key in ["title", "genre"]:
value = taglist.get_string(key)[1]
print(f"{key}: {value}")
Gst.init(None)
pipeline = Gst.Pipeline()
source = Gst.ElementFactory.make("filesrc", None)
source.set_property("location", "video.mkv")
demuxer = Gst.ElementFactory.make("matroskamux", None)
decoder = Gst.ElementFactory.make("decodebin", None)
sink = Gst.ElementFactory.make("autovideosink", None)
bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect("message::tag", on_tag)
pipeline.add(source, demuxer, decoder, sink)
Gst.element_link_many(source, demuxer, decoder, sink)
loop = GObject.MainLoop()
pipeline.set_state(Gst.State.PLAYING)
try:
loop.run()
except KeyboardInterrupt:
pass
finally:
pipeline.set_state(Gst.State.NULL)
Этот скрипт выводит метаданные, такие как название и жанр, при воспроизведении файла video.mkv. Для этого используется сигнал message::tag шины сообщений GStreamer.