http://www.walking-productions.com/notslop/2010/04/20/motion-jpeg-in-flash-and-java/

——————————————————————————————————————————————————————————————

I recently had the opportunity to develop a solution in both Java and Flash for pulling Motion JPEG streams from IP cameras and thought it might be nice to document a bit.

Motion JPEG is generally served via HTTP from IP cameras as a single file. Meaning, the connection stays open and the camera just keeps sending individual JPEG images down the pipe. The images should start with a MIME boundary message such as:

--myboundary
Content-Type: image/jpeg
Content-Length: 22517

or

--randomstring
Content-Type: image/jpeg
Content-Length: 22598

The key in the development is to find the boundary and save the bytes between each and treat that as a JPEG image. Neither of these snippets are great or even complete but they should give you a bit of a start.

Java:

package com.mobvcasting.mjpegparser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URL;

public class MJPEGParser {

    /**
     * 
@param args
     
*/
    public static void main(String[] args) {
        MJPEGParser mp = new MJPEGParser("http://192.168.1.10/mjpg/video.mjpg", "username", "password");
    }

    public MJPEGParser(String mjpeg_url)
    {
        this(mjpeg_url,null,null);
    }

    public MJPEGParser(String mjpeg_url, String username, String password)
    {
        int imageCount = 0;

        try {
            if (username != null && password != null)
            {
                Authenticator.setDefault(new HTTPAuthenticator(username, password));
            }

            URL url = new URL(mjpeg_url);
            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            String inputLine;
            int lineCount = 0;
            boolean lineCountStart = false;
            boolean saveImage = false;
            while ((inputLine = in.readLine()) != null) {
                // Should be checking just for "--" probably
                if (inputLine.lastIndexOf("--myboundary") > -1)
                {
                    // Got an image boundary, stop last image
                    
// Start counting lines to get past:
                    
// Content-Type: image/jpeg
                    
// Content-Length: 22517

                    saveImage = false;
                    lineCountStart = true;

                    System.out.println("Got a new boundary");
                    System.out.println(inputLine);
                }
                else if (lineCountStart)
                {
                    lineCount++;
                    if (lineCount >= 2)
                    {
                        lineCount = 0;
                        lineCountStart = false;
                        imageCount++;
                        saveImage = true;
                        System.out.println("Starting a new image");

                    }
                }
                else if (saveImage)
                {
                    System.out.println("Saving an image line");
                }
                else {

                    System.out.println("What's this:");
                    System.out.println(inputLine);
                }
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }        

    }

    static class HTTPAuthenticator extends Authenticator {
        private String username, password;

        public HTTPAuthenticator(String user, String pass) {
          username = user;
          password = pass;
        }

        protected PasswordAuthentication getPasswordAuthentication() {
          System.out.println("Requesting Host  : " + getRequestingHost());
          System.out.println("Requesting Port  : " + getRequestingPort());
          System.out.println("Requesting Prompt : " + getRequestingPrompt());
          System.out.println("Requesting Protocol: "
              + getRequestingProtocol());
          System.out.println("Requesting Scheme : " + getRequestingScheme());
          System.out.println("Requesting Site  : " + getRequestingSite());
          return new PasswordAuthentication(username, password.toCharArray());
        }
      }
}

 

 

 

 

ActionScript 3

 

import flash.display.Sprite;
    import flash.errors.*;
    import flash.events.*;
    import flash.net.URLRequest;
    import flash.net.URLStream;
    import flash.utils.ByteArray;

    var stream:URLStream;
    var mjpegBuffer:ByteArray = new ByteArray();
    // The actual image
    var imageBytes:ByteArray; // = new ByteArray();
    
// The chars at the end of the image
    var endPos:String = "\n--myboundary";

    // Started to find, finished finding
    var done:Boolean = false;
    var started:Boolean = false;

    // Don't know why I have to save these to a ByteArray to do the comparisons but it seems I do
    var startBytes:ByteArray = new ByteArray();
    var startByte:int = 0xFF;
    var secondByte:int = 0xD8;
    startBytes.writeByte(0xFF);
    startBytes.writeByte(0xD8);
    trace(startBytes.length);
    var startNum:int = startBytes[0];
    trace(startNum);
    var nextNum:int = startBytes[1];
    trace(nextNum);

    // Open the stream
    stream = new URLStream();
    var request:URLRequest = new URLRequest("http://192.168.1.10/mjpg/video.mjpg?resolution=160x90&fps=1");
    configureListeners(stream);
    try {
        stream.load(request);
    } catch (error:Error) {
        trace("Unable to load requested URL.");
    }

    function configureListeners(dispatcher:EventDispatcher):void {
            dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
    }

         function progressHandler(event:Event):void
         {
             trace("Running");
            stream.readBytes(mjpegBuffer,mjpegBuffer.length,stream.bytesAvailable);
            for (var i:int = 0; i < mjpegBuffer.length; i++)
            {
                var currentByte:int = mjpegBuffer[i];
                var nextByte:int = mjpegBuffer[i+1];
                var thirdByte:int = mjpegBuffer[i+2];
                var fourthByte:int = mjpegBuffer[i+3];

                //var randNum:Number = Math.random();
                
//if (randNum > .5 && randNum < .6) { trace(currentByte); }

                if (!started)
                {
                    if (currentByte == startNum && nextByte == nextNum)
                    {
                            trace("Started");
                            started = true;
                            imageBytes = new ByteArray();
                            imageBytes.writeByte(currentByte);
                            //imageBytes.writeByte(0xD8); // Gets written in the else
                    }
                }
                else
                {
                    if (currentByte == endPos.charCodeAt(0) && nextByte == endPos.charCodeAt(1) && thirdByte == endPos.charCodeAt(2) && fourthByte == endPos.charCodeAt(3))
                    {
                        trace("done");
                        trace(imageBytes);
                        done = true;
                        started = false;

                        var loader:Loader = new Loader();
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onByteArrayLoaded)
                        loader.loadBytes(imageBytes);
                        //stream.close();
                    }
                    else
                    {
                        imageBytes.writeByte(currentByte);
                    }
                }
            }
        }

        function onByteArrayLoaded(e:Event):void
        {
            var loader:Loader = Loader(e.target.loader);
            loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onByteArrayLoaded);

            var bitmapData:BitmapData = Bitmap(e.target.content).bitmapData;

            //sprLoaded.graphics.clear();
            graphics.beginBitmapFill(bitmapData);
            graphics.drawRect(0,0,bitmapData.width, bitmapData.height);
            graphics.endFill();

        }

 

posted on 2012-01-11 00:06  网络大豆  阅读(266)  评论(0编辑  收藏  举报