record MJPEG stream from Ip Camera
hi all,
I have some problems when I try to save the streaming data provided from my Ip camera to a file. I think it is the best way to record the MJPEG streaming in order to preview later the video from this file.
I have three classesAxisCamera, to connect to the camera, preview the MJPEG stream and save that into a file; RecordFile which takes an InputStream object and save continuosly the stream into a file; andPlayFile which read continously the data from a file and try to render the stream into a Frame.
all my aplication works great, but when I try to render this stream from the file to the Frame continously, only the first image go throw the Frame and when occours this Error:
this Error is produced when the class PlayFile tries to read the second image from the file...
Can anybody helpe?
thanks a lot!
faival@hotmail.com
com.sun.image.codec.jpeg.ImageFormatException:Not a JPEG file: starts with 0x43 0x45
at sun.awt.image.codec.JPEGImageDecoderImpl.readJPEGStream(Native Method)
at sun.awt.image.codec.JPEGImageDecoderImpl.decodeAsBufferedImage(Unknown Source)
This is my code:
CLASS AXISCAMERA
import java.net.*;
import java.nio.IntBuffer;
import com.sun.image.codec.jpeg.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
publicclass AxisCameraextends JPanelimplements Runnable{
publicboolean useMJPGStream =true;
InputStream isRecord;
DataInputStream dis;
FileOutputStream dos;
File recordFile;
private Image image=null;
public Dimension imageSize =null;
publicboolean connected =false;
privateboolean initCompleted =false;
HttpURLConnection huc=null, hucR=null;
URL u;
Component parent;
private String ip =null;
private String credentials =null;
private String jpgURL=null;
private String mjpgURL=null;
private Dimension dimension;
privatevolatile Thread blinker;
private Thread thisThread;
private RecordFile record;
/** Creates a new instance of AxisCamera */
public AxisCamera (Component parent_,CameraAccount account, Dimension dimension){
boolean openFile =false;
parent = parent_;
this.ip= account.getIp();
this.credentials =account.getCredentials();
this.dimension= dimension;
recordFile =new File("C:\\Documents and Settings\\oks_stud\\workspace\\Scenario2\\data\\video");
try{
dos =new FileOutputStream(recordFile);
openFile =true;
}catch (FileNotFoundException e){
e.printStackTrace();
}
if (openFile){
blinker =new Thread(this);
blinker.start();
init();
}
}
privatevoid init(){
String width =Integer.toString(dimension.width);
String height=Integer.toString(dimension.height);
this.jpgURL="http://"+this.ip+"/axis-cgi/jpg/image.cgi?resolution="+width+"x"+height;
this.mjpgURL="http://"+this.ip+"/axis-cgi/mjpg/video.cgi?resolution="+width+"x"+height;
}
public String getURL(){
return this.mjpgURL;
}
public Dimension getDimension(){
return this.dimension;
}
publicvoid connect(){
try{
u =new URL(mjpgURL);
huc = (HttpURLConnection) u.openConnection();
hucR= (HttpURLConnection)u.openConnection();
if(credentials !=null){
huc.setDoInput(true);
hucR.setDoInput(true);
huc.setRequestProperty("Authorization",credentials);
hucR.setRequestProperty("Authorization", credentials);
hucR.connect();
huc.connect();
}
InputStream is = huc.getInputStream();
isRecord = hucR.getInputStream();
connected =true;
BufferedInputStream bis =new BufferedInputStream(is);
dis=new DataInputStream(bis);
if (!initCompleted) initDisplay();
}catch(IOException e){//incase no connection exists wait and try again, instead of printing the error
e.printStackTrace();
try{
huc.disconnect();
Thread.sleep(60);
}catch(InterruptedException ie){huc.disconnect();connect();}
connect();
}catch(Exception e){;}
}
publicvoid initDisplay(){//setup the display
if (useMJPGStream)readMJPGStream();
else{readJPG();disconnect();}
imageSize =new Dimension(image.getWidth(this), image.getHeight(this));
setPreferredSize(imageSize);
parent.setSize(imageSize);
parent.validate();
initCompleted =true;
}
publicvoid disconnect(){
try{
if(connected){
dis.close();
connected =false;
}
}catch(Exception e){;}
}
publicvoid paint(Graphics g){//used to set the image on the panel
if (image !=null)
g.drawImage(image, 0, 0,this);
}
publicvoid readStream(){//the basic method to continuously read the stream
try{
if (useMJPGStream){
thisThread = Thread.currentThread();
record =new RecordFile(isRecord, dos);
Thread recordT =new Thread(record);
readMJPGStream();
recordT.start();
while (blinker == thisThread){
readMJPGStream();
parent.repaint();
}
}else{
while (blinker == thisThread){
connect();
readJPG();
parent.repaint();
disconnect();
}
}
disconnect();
}catch(Exception e){;}
}
publicvoid readMJPGStream(){//preprocess the mjpg stream to remove the mjpg encapsulation
readLine(4,dis);//discard the first 4 lines
readJPG();// Decode the JPEG image.
readLine(1,dis);//discard the last line
}
publicvoid readJPG(){//read the embedded jpeg image
try{
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(dis);
image = decoder.decodeAsBufferedImage();
}catch(Exception e){e.printStackTrace();disconnect();}
}
publicvoid readLine(int n, DataInputStream dis){//used to strip out the header lines
for (int i=0; i<n;i++){
readLine(dis);
}
}
publicvoid readLine(DataInputStream dis){
try{
boolean end =false;
String lineEnd ="\n";//assumes that the end of the line is marked with this
byte[] lineEndBytes = lineEnd.getBytes();
byte[] byteBuf =newbyte[lineEndBytes.length];
while(!end){
dis.read(byteBuf,0,lineEndBytes.length);
String t =new String(byteBuf);
//System.out.print(t); //uncomment if you want to see what the lines actually look like
if(t.equals(lineEnd)) end=true;
}
}catch(Exception e){e.printStackTrace();}
}
publicvoid changeResolution(Dimension dimension){
this.dimension= dimension;
init();
}
publicvoid run(){
connect();
readStream();
}
publicvoid stop(){
//record.stop();
blinker =null;
}
publicvoid play(){
blinker=new Thread(this);
blinker.start();
//run();
}
}
CLASS RECORDFILE
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
publicclass RecordFileimplements Runnable{
privatevolatile Thread blinker;
private InputStream input;
private FileOutputStream output;
byte[] byteBuf;
public RecordFile(InputStream input, FileOutputStream output){
this.input= input;
this.output= output;
String lineEnd ="\n";//assumes that the end of the line is marked with this
byte[] lineEndBytes = lineEnd.getBytes();
byteBuf =newbyte[lineEndBytes.length];
blinker =new Thread(this);
blinker.start();
}
publicvoid run(){
Thread thisThread = Thread.currentThread();
try{
while(blinker == thisThread && input.read(byteBuf, 0, byteBuf.length)!=-1){
output.write(byteBuf, 0, byteBuf.length);
}
}catch (IOException e){
e.printStackTrace();
}
}
publicvoid stop(){
blinker =null;
}
}
CLASS PLAYFILE
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.swing.JPanel;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageDecoder;
publicclass PlayFileextends JPanelimplements Runnable{
private Component parent;
private FileInputStream inputFile;
private Dimension dimension;
privatevolatile Thread blinker;
private Image image=null;
public PlayFile(String path, Component parent, Dimension dim){
this.parent = parent;
this.dimension= dim;
try{
inputFile =new FileInputStream(path);
}catch (FileNotFoundException e){
e.printStackTrace();
}
init();
blinker =new Thread(this);
blinker.start();
}
publicvoid run(){
Thread thisThread = Thread.currentThread();
while(blinker == thisThread){
readStream();
parent.repaint();
}
}
publicvoid stop(){
blinker =null;
}
privatevoid init(){
readStream();
Dimension imageSize =new Dimension(image.getWidth(this), image.getHeight(this));
setPreferredSize(imageSize);
parent.setSize(imageSize);
parent.validate();
}
publicvoid paint(Graphics g){
if (image !=null)
g.drawImage(image, 0, 0,this);
}
privatevoid readStream(){
readLine(4,inputFile);
readJPG();
readLine(1,inputFile);
System.out.println("LEO");
}
privatevoid readLine(int n, FileInputStream input){
for (int i=0; i><n;i++){
readLine(input);
}
}
privatevoid readLine(FileInputStream input){
try{
boolean end =false;
String lineEnd ="\n";//assumes that the end of the line is marked with this
byte[] lineEndBytes = lineEnd.getBytes();
byte[] byteBuf =newbyte[lineEndBytes.length];
while(!end){
if(input.read(byteBuf,0,lineEndBytes.length)== -1){stop();}
String t =new String(byteBuf);
//System.out.print(t); //uncomment if you want to see what the lines actually look like
if(t.equals(lineEnd)) end=true;
}
}catch(Exception e){e.printStackTrace();}
}
privatevoid readJPG(){
try{
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(inputFile);
image = decoder.decodeAsBufferedImage();
}catch(Exception e){e.printStackTrace();stop();}
}
}
>

