Я пытался создать инструмент для захвата кадров из потока mjpeg, который передается по http. Я не нашел никакой спецификации, поэтому посмотрел, что написано в википедии здесь:
В ответ на запрос GET для файла или потока MJPEG сервер передает последовательность кадров JPEG через HTTP. Специальный тип содержимого mime-типа
multipart/x-mixed-replace;boundary=<boundary-name>
сообщает клиенту, что он должен ожидать несколько частей (фреймов) в качестве ответа, разделенных<boundary-name>
. Это граничное имя явно раскрывается в самом объявлении MIME-типа.
Но на практике это кажется не очень точным. Скинул несколько потоков, чтобы узнать, как они себя ведут. Большинство потоков имеют следующий формат (где CRLF
- перевод строки возврата каретки, а частичный заголовок - это некоторые поля заголовка без строки состояния):
Status line (e.g. HTTP/1.0 200 OK) CRLF
Header fields (e.g. Cache-Control: no-cache) CRLF
Content-Type header field (e.g. Content-Type: multipart/x-mixed-replace; boundary=--myboundary) CRLF
CRLF (Denotes that the header is over)
Boundary (Denotes that the first frame is over) CRLF
Partial header fields (mostly: Content-type: image/jpeg) CRLF
CRLF (Denotes that this "partial header" is over)
Actual frame data CRLF
(Sometimes here is an optional CRLF)
Boundary
Starting again at partial header (line 6)
Первый кадр никогда не содержал реальных данных изображения. Все проанализированные потоки имели заголовок Content-Type с типом multipart/x-mixed-replace
.
Но некоторые потоки здесь ошибаются:
Два Сервера заявили boundary="MOBOTIX_Fast_Serverpush"
, но затем использовали --MOBOTIX_Fast_Serverpush
в качестве разделителя кадров.
Это меня немного раздражало, поэтому я подумал о другом подходе к получению кадров.
Поскольку каждый JPEG начинается с 0xFF 0xD8
в качестве маркера начала изображения и заканчивается 0xFF 0xD9
, я мог бы просто начать их искать. Это кажется очень грязным подходом, и мне он не очень нравится, но он может быть самым надежным.
Прежде чем я начну реализовывать это, есть ли какие-то моменты, которые я упустил из-за MJPEG через HTTP? Есть ли реальная спецификация передачи MJPEG через HTTP? Каковы предостережения, когда вы просто наблюдаете за маркерами начала и конца JPEG вместо использования границы для разделения кадров?