edu.xjtu.qxcamerabridge.LiveviewImageExtractor.java Source code

Java tutorial

Introduction

Here is the source code for edu.xjtu.qxcamerabridge.LiveviewImageExtractor.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.xjtu.qxcamerabridge;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.collections4.queue.CircularFifoQueue;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.fluent.Request;

/**
 *
 * @author ZhipingJiang
 */
public class LiveviewImageExtractor {

    private static LiveviewPayload liveviewPayload;
    private static final CircularFifoQueue<LiveviewPayload> payloadQueue = new CircularFifoQueue<>(300);
    private static String dumpFolder;
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY.MM.dd.hh.mm.ss.SSSS");

    public static void liveviewPipeLine(String liveviewURL, String folder) throws IOException {

        dumpFolder = folder;
        final InputStream liveviewStream = getLiveviewInputStream(liveviewURL);

        Thread liveviewFetcherThread = new Thread() {

            @Override
            public void run() {
                while (true) {
                    extractLiveviewPayload(liveviewStream);
                    if (liveviewPayload.fetchDone) {

                        payloadQueue.add(liveviewPayload);
                        //                        System.out.println("add queue"+payloadQueue.size());
                    }
                }
            }

        };

        Thread liveviewDiskDumpThread = new Thread() {

            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(LiveviewImageExtractor.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    //                    System.out.println("poll queue"+payloadQueue.size());
                    if (payloadQueue.size() > 0) {
                        //                        System.out.println("not empty");
                        dumpToDisk(dumpFolder, payloadQueue.poll());
                    }
                }
            }

        };

        liveviewFetcherThread.start();
        liveviewDiskDumpThread.start();

    }

    /**
     * fetch data from the stream, and parse the data strucutre to the static liveviewPayload object.
     * @param liveviewStream
     * @return 
     */
    private static LiveviewPayload extractLiveviewPayload(InputStream liveviewStream) {

        liveviewPayload = new LiveviewPayload();
        try {
            //common header
            int readLength = 1 + 1 + 2 + 4;
            byte[] commonHeader = new byte[readLength];
            IOUtils.read(liveviewStream, commonHeader, 0, readLength);
            if (commonHeader[0] != (byte) 0xFF || commonHeader[1] != (byte) 0x1) {
                throw new IOException("parse payload error in common header");
            }

            liveviewPayload.sequenceNumber = (int) bytesToInt(commonHeader, 2, 2);
            liveviewPayload.timestamp = bytesToInt(commonHeader, 4, 4);

            System.out.println(liveviewPayload.timestamp + " " + liveviewPayload.sequenceNumber);
            // Payload Header
            readLength = 4 + 3 + 1 + 4 + 1 + 115;
            byte[] payloadHeader = new byte[readLength];
            IOUtils.read(liveviewStream, payloadHeader, 0, readLength);
            if (payloadHeader[0] != (byte) 0x24 || payloadHeader[1] != (byte) 0x35
                    || payloadHeader[2] != (byte) 0x68 || payloadHeader[3] != (byte) 0x79) {
                throw new IOException("parse payload error in payload header");
            }
            liveviewPayload.jpegSize = bytesToInt(payloadHeader, 4, 3);
            liveviewPayload.padding = (int) bytesToInt(payloadHeader, 7, 1);

            liveviewPayload.jpegData = new byte[(int) liveviewPayload.jpegSize];
            liveviewPayload.paddingData = new byte[liveviewPayload.padding];
            IOUtils.read(liveviewStream, liveviewPayload.jpegData, 0, (int) liveviewPayload.jpegSize);
            IOUtils.read(liveviewStream, liveviewPayload.paddingData, 0, liveviewPayload.padding);
            liveviewPayload.fetchDone = true;
        } catch (IOException iOException) {
        }
        return liveviewPayload;
    }

    private static long bytesToInt(byte[] byteData, int startIndex, int count) {
        long ret = 0;
        for (int i = startIndex; i < startIndex + count; i++) {
            ret = (ret << 8) | (byteData[i] & 0xff);
        }
        return ret;
    }

    private static void dumpToDisk(String dumpFolder, LiveviewPayload payload) {
        //        System.out.println("dumping");
        String targetFileName = "liveview_" + payload.timestamp + "_" + payload.sequenceNumber + ".jpg";
        try {
            FileUtils.writeByteArrayToFile(new File(dumpFolder, targetFileName), payload.jpegData);
        } catch (IOException ex) {
            Logger.getLogger(LiveviewImageExtractor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private static InputStream getLiveviewInputStream(String liveviewURL)
            throws MalformedURLException, IOException {
        URL url = new URL(liveviewURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setReadTimeout(2000);
        connection.connect();

        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            return connection.getInputStream();
        }
        return null;
    }
}