MJPEG, MPNG, MGIF, MSVG
Я вчера показывал вам «телевизор» про фестиваль в Самаре. Сделано очень просто — уменьшил все сделанные там снимки до 66×44 и сконвертировал их в анимированный ГИФ. Мелковато, конечно, но что делать — ГИФ не очень-то предназначен для фотографических изображений и размер анимации сильно растёт с увеличением размера кадра. Для фотографий в интернете принято использовать формат JPEG.
У JPEG есть свой формат анимации, если так можно выразиться, а точнее — скорее простенький формат видео, так как формат анимации, в моём представлении, помимо кадров должен содержать себе какую-то метаинформацию о кадре, например, задержку перед появлением следующего кадра. Этот формат — разновидность MJPEG (motion JPEG).
Мне давно хотелось посмотреть что у этого формата внутри, сегодня наконец посмотрел. Всё оказалось крайне просто.
В данном случае, MJPEG — формат стримминга (потоковой подачи) видео. Собственно, это даже не формат, а простое соединение JPEG и специального заголовка «multipart/x-mixed-replace», которым может применяться для стриминга чего угодно. Можно, например, подавать не JPEG, а PNG и «изобрести» формат видео MPNG, а то и M(JPEG+PNG+GIF), картинки разных форматов можно перемешивать в любых пропорциях.
Смысл этого заголовка — содержимое которое пришло раньше заменяется тем, что пришло позже. То есть MJPEG — это просто последовательность картинок, у которых этим заголовком указано — когда приходит следующая картинка, ею надо заменить предыдущую. Внутри выглядит это вот таким образом.
Content-type: multipart/x-mixed-replace;boundary=СТРОКАРАЗДЕЛИТЕЛЬ
--СТРОКАРАЗДЕЛИТЕЛЬ
Content-type: image/jpeg
Content-length: 232311
…бинарное содержимое первой картинки…
--СТРОКАРАЗДЕЛИТЕЛЬ
Content-type: image/jpeg
Content-length: 47474
…бинарное содержимое второй картинки…
СТРОКУРАЗДЕЛИТЕЛЬ надо выбирать так, чтобы она не встретилась в бинарных данных изображения.
Браузерам этот заголовок достался от фирмы Нетскейп, которая когда-то (ещё в версии 1.1) добавила её поддержку в свой браузер. «Микрософт», будучи конкурентом «Нетскейпа», поддержку заголовка в браузер не внедрила. Остальные браузеры заголовок понимают, но каждый немного по-разному.
Например для «Оперы», нужно выдавать данные с задержкой, то есть показали один кадр, ждём пару секунд, ничего с сервера не отдаём, потом следующий. Иначе, «Опера» «хитрит» — показывает следующий кадр, не дожидаясь загрузки предыдущего. Если канал хороший, то мы увидим только последний кадр.
«Файрфокс» единственный, кто хорошо справляется с тем, что кадры могут быть разных размеров — он отображает их правильно, «Опера» масштабирует по первой картинке, «Хром» и «Сафари» глючат — иногда пропускают кадр, иногда ничего не показывают, иногда показывают нормально.
Самое приятное в этом формате — что все современные браузеры считают его картинкой, то есть тег IMG его преспокойно показывает.
Любопытно, что браузеры позволяют сжимать содержимое всего файла и даже каждого кадра отдельно, то есть можно в заголовке кадра поставить «Content-encoding: gzip» и сжать кадр гзипом. Это полезно, если захочется сделать MSVG, например. Ведь SVG-изображения хорошо сжимаются.
Так что, если вы задумались сделать аналог какого-нибудь хостинга анимированных ГИФ и вам наплевать на «Эксплорер» (я посмотрел, девятая версия не поддерживает), сделайте ещё и поддержку MJPEG/MPNG.
Крутотенюшка!
Получается, что таким способом можно симулировать прогрессивную загрузку JPEG и чересстрочный GIF, но с другими целями — исключительно для красоты и поэтому с более сложными эффектами. Верно?
А как ведет себя IE? Вообще ничего не показывает?
Комментарий для stacmv.ya.ru:
Хм, в принципе можно. Только надо учитывать, что картинка заменяется, а не накладывается.
Показывает, что картинка битая. Если бы у меня IE был под рукой, можно было бы поэкспериментировать. Вполне возможно, что IE можно «убедить» показать хоть что-то :)
Комментарий для Евгения Степанищева:
Первый раз встречаю формулировку «mJPEG» — так еще никто не называл :) Обычно это M-JPEG. Motion JPEG, кстати, тоже неудачное название, так как на заре нелинейного монтажа под этим термином понималось иное, а именно — видеоизмененная кодировка JPEG несовместимая той, что нам известна сейчас.
Комментарий для alax.myopenid.com:
Вот я что-то сам не знаю почему я букву «m» маленькой написал :) А «MJPEG» пишут часто, в «Википедии» например.
MJPEG — это любой формат видео, где каждый кадр кодируется в JPEG без учёта разницы между кадрами.
Комментарий для alax.myopenid.com:
Сейчас поменяю букву :)
Комментарий для Евгения Степанищева:
<blockquote>MJPEG — это любой формат видео, где каждый кадр кодируется в JPEG без учёта разницы между кадрами. </blockquote>
Ну это не совсем так. Еще до появления x-mixed-replace в системах нелинейного монтажа использовался другой Motion JPEG, где каждый кадр был почти JPEG, но не JPEG.
Комментарий для alax.myopenid.com:
Как мне ещё написать, что HTML писать не надо? :-(
Вполне может быть, я не знаю.
Комментарий для Евгения Степанищева:
В интернете MJPEG имел ограниченное применение из-за неподдержки IE’ом, но тем не менее с тех еще давних пор не почил в истории из-за того, что был подхвачен производителямо оборудования и добрая половина IP камер умеет отдавать видео в том числе и так.
Но еще до этого времени профессиональное оборудование видеозахвата уже реализовывало сжатие в железе (скорость работы винчестеров не позволяла писатьь видео бес сжатия) и там были свои особенности. То ли из-за особенностей «железной» реализации, то ли еще из-за чего, часть оборудования или это было повально использовала модификацию формата — одна из таблиц была статической и исключалась из картинки, соотвественно кадр был чуть меньше (не думаю, что это было принципиально даеж тогда), но при этом оборудование тех времен вполне могло работать «в железе» с таким видеопотоком. Вот это все безобразие называлось так же Motion JPEG’ом (M-JPEG, MJPEG, MJPG).
С увеличением мощностей, от этой затеи быстро отказались, а server push JPEG over HTTP наоборот постепенно набрал обороты. Правда, сейчас эта технология опять является аутсайдером. Для передачи видео по сети стандартным является протокол RTP, в съемке JPEG сильно потеснен MPEG-4’ым. Но этот M-JPEG все еще жив благодаря своей простоте и врядли быстро растратит эту популярность.
Комментарий для alax.myopenid.com:
Даже PSP поддерживает два вида MJPEG ( http://ru.wikipedia.org/wiki/PSP ):
Комментарий для Евгения Степанищева:
Это бессмысленный набор слов. JPEG относится к видео, PCM и μ-Lau (правильно: μ-Law) — термины из мира аудио.
Так что это на wiki какая-то бессмысленная цитата, видимо поулчившаяся после какого-то неудачного перевода.
Скорее всего речь идео о том, что PSP умеет проиргывать файлы AVI, в которых видео часть — MJPEG, а аудио часть — PCM или ADPCM типа μ-Law.
Комментарий для alax.myopenid.com:
Наверное так, да.