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.