Motion - Perl Parse MJPEG Stream

Perl Parse MJPEG Stream

Introduction

This project is just for posting Perl code snippets for parsing an MJPEG Stream in real-time.

Detailed Description

I don't feel like attaching files just for code snippets right now so I'll just post my snippets here:

The MJPEG stream has a different record seperator than most records. Most records use "\n", the MJPEG stream uses "--myboundary\r\n".

To Parse an MJPEG Stream in real-time, you have to first set the record seperator and then open up a connection to the web cam. I do it like this:

$/="--myboundary\r\n";
open CURL, "curl -u $user:$pass -s -N 'http://url.com' |";

It is very important to use the -N option which will prevent buffering of the stream, this is what keeps the stream pumping in real-time. The -s is just a silent mode to prevent other crap from polluting our data stream.

Next, we loop indefintely:

while ( <CURL> ) {

Then you parse the frame and put any logic that you are interested in. Here I supply the code for parsing the frame, but after that, it's up to your imagination.

/Content-Type: image\/jpeg\r\nContent-Length: (\d+)\r\n\r\n(.*)/s;
my ($jpeg_length, $jpeg_data) = ($1, $2);
$jpeg_data =~ s/\r\n$//;
next if $jpeg_length != length($jpeg_data);
my ($comment_length, $comment_data) = ($jpeg_data =~ /\xFF\xFE(..)\x0A\x03(.{260})/s);
$comment_length = hex unpack("H4", $comment_length);
$comment_data =~ s/[^[:print:]]//gs;

At this point in your main loop, you have 4 major pieces of data: $jpeg_length (This is the length of the raw binary JPEG data), $jpeg_data (This is the raw binary JPEG data, dump this to a file and you have a JPEG image), $comment_length, and $comment_data (This is the data from the comment stored in the JPEG image (Axis, e.g., use the comment to store its trigger information so that you know if the camera has detected motion or not).

You can now manipulate these 4 pieces of data however you want, and remember that each progessive loop is a new JPEG frame from the MJPEG stream with the image and comments and lengths all seperated. Lastly, complete the end loop.

}

There are no requirements for these code snippets -- no special Modules or other code dependencies. To test your code, you will need an MJPEG Server to connect to, of course.

I am working on an application that connects to a camera and parses an MJPEG stream in real-time and uses the triggers set in each JPEG frame by the camera flagging motion or not in each frame and then building an MPEG movie from the stills. When I have a working prototype, I'll post it on SourceForge and reference it within motion's TWiki. Unil then, I just wanted to post the code necessary for parsing an MJPEG Stream in real-time. It's simple code but was difficult for me to figure out. Hopefully search engines will pick this up and make it easier for others to create programs for MJPEG Cameras.

Attached Files

None

Installation

None

Users Guide

This is just code snippets at this point so use the snippets where ever.

Comments and Bug Reports


RelatedProjectsForm edit

ProjectSummary This for now is just a code snippet of how to use Perl to parse an MJPEG Stream from cameras, specifically in my tested case, the Axis 211.
ProjectStatus Alpha
ReleaseVersion 0.1
ProjectSubmitter StefanAdams
Topic revision: r5 - 29 Jan 2005, KennethLavrsen
Copyright © 1999-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Please do not email Kenneth for support questions (read why). Use the Support Requests page or join the Mailing List.
This website only use harmless session cookies. See Cookie Policy for details. By using this website you accept the use of these cookies.