OSDN Git Service

Theta用のLV表示部分の作りこみ。(まだ動かしていない。)
authorMRSa <mrsa@myad.jp>
Thu, 23 Jan 2020 15:10:02 +0000 (00:10 +0900)
committerMRSa <mrsa@myad.jp>
Thu, 23 Jan 2020 15:10:02 +0000 (00:10 +0900)
app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/IThetaSessionIdNotifier.java [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/IThetaSessionIdProvider.java [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/ThetaFocusControl.java
app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/ThetaInterfaceProvider.java
app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/ThetaLiveViewControl.java
app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/ThetaZoomLensControl.java
app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/connection/ThetaCameraConnectSequence.java
app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/connection/ThetaCameraDisconnectSequence.java
app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/connection/ThetaConnection.java
app/src/main/java/net/osdn/gokigen/a01d/camera/utils/SimpleLiveviewSlicer.java

diff --git a/app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/IThetaSessionIdNotifier.java b/app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/IThetaSessionIdNotifier.java
new file mode 100644 (file)
index 0000000..ef47cdc
--- /dev/null
@@ -0,0 +1,6 @@
+package net.osdn.gokigen.a01d.camera.theta.wrapper;
+
+public interface IThetaSessionIdNotifier
+{
+    void receivedSessionId(String sessionId);
+}
diff --git a/app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/IThetaSessionIdProvider.java b/app/src/main/java/net/osdn/gokigen/a01d/camera/theta/wrapper/IThetaSessionIdProvider.java
new file mode 100644 (file)
index 0000000..abc9e0a
--- /dev/null
@@ -0,0 +1,6 @@
+package net.osdn.gokigen.a01d.camera.theta.wrapper;
+
+public interface IThetaSessionIdProvider
+{
+    String getSessionId();
+}
index a8f67ed..d82626f 100644 (file)
@@ -1,43 +1,30 @@
 package net.osdn.gokigen.a01d.camera.theta.wrapper;
 
-import android.graphics.PointF;
 import android.util.Log;
 import android.view.MotionEvent;
 
 import androidx.annotation.NonNull;
 
 import net.osdn.gokigen.a01d.camera.IFocusingControl;
-import net.osdn.gokigen.a01d.camera.olympuspen.operation.OlympusPenAutoFocusControl;
 import net.osdn.gokigen.a01d.liveview.IAutoFocusFrameDisplay;
-import net.osdn.gokigen.a01d.liveview.IIndicatorControl;
 
 public class ThetaFocusControl implements IFocusingControl
 {
     private final String TAG = toString();
-    //private final OlympusPenAutoFocusControl afControl;
     private final IAutoFocusFrameDisplay frameDisplay;
 
-    ThetaFocusControl(@NonNull final IAutoFocusFrameDisplay frameDisplayer, @NonNull final IIndicatorControl indicator)
+    ThetaFocusControl(@NonNull final IAutoFocusFrameDisplay frameDisplayer)
     {
         this.frameDisplay = frameDisplayer;
-        //afControl = new OlympusPenAutoFocusControl(frameDisplayer, indicator);
     }
 
     @Override
     public boolean driveAutoFocus(final MotionEvent motionEvent)
     {
         Log.v(TAG, "driveAutoFocus()");
-        if (motionEvent.getAction() != MotionEvent.ACTION_DOWN)
-        {
-            return (false);
-        }
         try
         {
-            PointF point = frameDisplay.getPointWithEvent(motionEvent);
-            if (frameDisplay.isContainsPoint(point))
-            {
-               //afControl.lockAutoFocus(point);
-            }
+            frameDisplay.hideFocusFrame();
         }
         catch (Exception e)
         {
@@ -52,7 +39,6 @@ public class ThetaFocusControl implements IFocusingControl
         Log.v(TAG, "unlockAutoFocus()");
         try
         {
-            //afControl.unlockAutoFocus();
             frameDisplay.hideFocusFrame();
         }
         catch (Exception e)
@@ -67,13 +53,7 @@ public class ThetaFocusControl implements IFocusingControl
         Log.v(TAG, "halfPressShutter() " + isPressed);
         try
         {
-            //afControl.halfPressShutter(isPressed);
-            if (!isPressed)
-            {
-                // フォーカスを外す
-                frameDisplay.hideFocusFrame();
-                //afControl.unlockAutoFocus();
-            }
+            frameDisplay.hideFocusFrame();
         }
         catch (Exception e)
         {
index a512646..d16352b 100644 (file)
@@ -30,7 +30,7 @@ import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener;
  *
  *
  */
-public class ThetaInterfaceProvider implements IThetaInterfaceProvider, IDisplayInjector
+public class ThetaInterfaceProvider implements IThetaInterfaceProvider, IDisplayInjector, IThetaSessionIdNotifier, IThetaSessionIdProvider
 {
     private final String TAG = toString();
     private final ThetaConnection thetaConnection;
@@ -41,8 +41,9 @@ public class ThetaInterfaceProvider implements IThetaInterfaceProvider, IDisplay
     private final ThetaCameraInformation cameraInformation;
     private final ThetaCameraStatusWatcher statusWatcher;
     private final CameraStatusListener statusListener;
-    private  ThetaFocusControl focusControl = null;
-    private  ThetaCaptureControl captureControl = null;
+    private ThetaFocusControl focusControl = null;
+    private ThetaCaptureControl captureControl = null;
+    private String sessionId = "";
 
     /**
      *
@@ -69,11 +70,11 @@ public class ThetaInterfaceProvider implements IThetaInterfaceProvider, IDisplay
         //this.activity = context;
         //this.provider = provider;
         this.statusListener = statusListener;
-        thetaConnection = new ThetaConnection(context, provider);
+        thetaConnection = new ThetaConnection(context, provider, this);
         hardwareStatus = new ThetaHardwareStatus();
         statusWatcher = new ThetaCameraStatusWatcher();
         runMode = new ThetaRunMode();
-        liveViewControl = new ThetaLiveViewControl(statusWatcher, statusListener);
+        liveViewControl = new ThetaLiveViewControl(context, this);
         zoomLensControl = new ThetaZoomLensControl(hardwareStatus);
         cameraInformation = new ThetaCameraInformation();
     }
@@ -87,7 +88,7 @@ public class ThetaInterfaceProvider implements IThetaInterfaceProvider, IDisplay
     public void injectDisplay(IAutoFocusFrameDisplay frameDisplayer, IIndicatorControl indicator, IFocusingModeNotify focusingModeNotify)
     {
         Log.v(TAG, "injectDisplay()");
-        focusControl = new ThetaFocusControl(frameDisplayer, indicator);
+        focusControl = new ThetaFocusControl(frameDisplayer);
         captureControl = new ThetaCaptureControl(frameDisplayer, indicator);
     }
 
@@ -161,4 +162,15 @@ public class ThetaInterfaceProvider implements IThetaInterfaceProvider, IDisplay
         return (statusWatcher);
     }
 
+    @Override
+    public void receivedSessionId(String sessionId)
+    {
+        this.sessionId = sessionId;
+    }
+
+    @Override
+    public String getSessionId()
+    {
+        return (this.sessionId);
+    }
 }
index da3dfc7..6026aef 100644 (file)
 package net.osdn.gokigen.a01d.camera.theta.wrapper;
 
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
 import androidx.annotation.NonNull;
 
-import net.osdn.gokigen.a01d.camera.CameraStatusListener;
 import net.osdn.gokigen.a01d.camera.ILiveViewControl;
-import net.osdn.gokigen.a01d.camera.theta.wrapper.status.ThetaCameraStatusWatcher;
-import net.osdn.gokigen.a01d.liveview.liveviewlistener.IImageDataReceiver;
+import net.osdn.gokigen.a01d.camera.utils.SimpleLiveviewSlicer;
+import net.osdn.gokigen.a01d.liveview.liveviewlistener.CameraLiveViewListenerImpl;
 import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener;
+import net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor;
 
 
-public class ThetaLiveViewControl implements ILiveViewControl, ILiveViewListener
+public class ThetaLiveViewControl implements ILiveViewControl
 {
-    ThetaLiveViewControl(@NonNull ThetaCameraStatusWatcher statusHolder, @NonNull CameraStatusListener statusListener)
-    {
-
-    }
-
-    ILiveViewListener getLiveViewListener()
+    private final String TAG = toString();
+    //private final Context context;
+    private final CameraLiveViewListenerImpl liveViewListener;
+    private final IThetaSessionIdProvider sessionIdProvider;
+    private boolean useOscV2 = false;
+    private boolean whileFetching = false;
+    private static final int FETCH_ERROR_MAX = 30;
+
+    ThetaLiveViewControl(@NonNull final Context context, @NonNull final IThetaSessionIdProvider sessionIdProvider)
     {
-        return (this);
+        this.sessionIdProvider = sessionIdProvider;
+        liveViewListener = new CameraLiveViewListenerImpl();
+        try
+        {
+            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+            useOscV2 = preferences.getBoolean(IPreferencePropertyAccessor.USE_OSC_THETA_V21, false);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
     }
 
     @Override
-    public void changeLiveViewSize(String size) {
+    public void changeLiveViewSize(String size)
+    {
+        //
 
     }
 
     @Override
-    public void startLiveView() {
+    public void startLiveView()
+    {
+        Log.v(TAG, "startLiveView()");
+        //prepare();
+        try
+        {
+            Thread thread = new Thread(new Runnable()
+            {
+                @Override
+                public void run()
+                {
+                    try
+                    {
+                        start();
+                    }
+                    catch (Exception e)
+                    {
+                        e.printStackTrace();
+                    }
+                }
+            });
+            thread.start();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
 
     }
 
     @Override
-    public void stopLiveView() {
-
+    public void stopLiveView()
+    {
+        whileFetching = false;
     }
 
-    @Override
-    public void updateDigitalZoom() {
-
+    private void start()
+    {
+        if (whileFetching)
+        {
+            Log.v(TAG, "start() already starting.");
+            return;
+        }
+        whileFetching = true;
+
+        // A thread for retrieving liveview data from server.
+        try
+        {
+            Thread thread = new Thread(new Runnable()
+            {
+                @Override
+                public void run()
+                {
+                    Log.d(TAG, "Starting retrieving streaming data from server.");
+                    SimpleLiveviewSlicer slicer = null;
+                    int continuousNullDataReceived = 0;
+                    try
+                    {
+                        String streamUrl = "http://192.168.1.1/osc/commands/execute";
+                        final String paramData = (useOscV2) ? "{\"name\":\"camera.getLivePreview\",\"parameters\":{\"timeout\":0}}" : "{\"name\":\"camera._getLivePreview\",\"parameters\":{\"sessionId\": \"" + sessionIdProvider.getSessionId() + "\"}}";
+                        Log.v(TAG, " >>>>> START THETA PREVIEW : " + streamUrl + " " + paramData);
+
+                        // Create Slicer to open the stream and parse it.
+                        slicer = new SimpleLiveviewSlicer();
+                        slicer.open(streamUrl, paramData);
+
+                        while (whileFetching)
+                        {
+                            final SimpleLiveviewSlicer.Payload payload = slicer.nextPayloadForMotionJpeg();
+                            if (payload == null)
+                            {
+                                //Log.v(TAG, "Liveview Payload is null.");
+                                continuousNullDataReceived++;
+                                if (continuousNullDataReceived > FETCH_ERROR_MAX)
+                                {
+                                    Log.d(TAG, " FETCH ERROR MAX OVER ");
+                                    break;
+                                }
+                                continue;
+                            }
+                            //if (mJpegQueue.size() == 2)
+                            //{
+                            //    mJpegQueue.remove();
+                            //}
+                            //mJpegQueue.add(payload.getJpegData());
+                            liveViewListener.onUpdateLiveView(payload.getJpegData(), null);
+                            continuousNullDataReceived = 0;
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        e.printStackTrace();
+                    }
+                    finally
+                    {
+                        try
+                        {
+                            if (slicer != null)
+                            {
+                                slicer.close();
+                            }
+                        }
+                        catch (Exception e)
+                        {
+                            e.printStackTrace();
+                        }
+                        //mJpegQueue.clear();
+                        if ((whileFetching)&&(continuousNullDataReceived > FETCH_ERROR_MAX))
+                        {
+                            // 再度ライブビューのスタートをやってみる。
+                            whileFetching = false;
+                            //continuousNullDataReceived = 0;
+                            start();
+                        }
+                    }
+                }
+            });
+            thread.start();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
     }
 
-    @Override
-    public void updateMagnifyingLiveViewScale(boolean isChangeScale) {
 
+    @Override
+    public void updateDigitalZoom()
+    {
+        Log.v(TAG, "updateDigitalZoom() ");
     }
 
+    /**
+     *   デジタルズーム倍率の設定値を応答する
+     *
+     */
     @Override
-    public float getMagnifyingLiveViewScale() {
-        return 0;
+    public float getDigitalZoomScale()
+    {
+        return (1.0f);
     }
 
+    /**
+     *   クロップサイズを変更する
+     *
+     */
     @Override
-    public float getDigitalZoomScale() {
-        return 0;
+    public void updateMagnifyingLiveViewScale(final boolean isChangeScale)
+    {
+        Log.v(TAG, "updateMagnifyingLiveViewScale() : " + isChangeScale);
     }
 
+    /**
+     *   ライブビュー拡大倍率の設定値を応答する
+     *
+     */
     @Override
-    public void setCameraLiveImageView(IImageDataReceiver target) {
+    public float getMagnifyingLiveViewScale()
+    {
+        return (1.0f);
+    }
 
+    public ILiveViewListener getLiveViewListener()
+    {
+        return (liveViewListener);
     }
 }
index 1f43940..ba37c89 100644 (file)
@@ -5,7 +5,6 @@ import android.util.Log;
 import androidx.annotation.NonNull;
 
 import net.osdn.gokigen.a01d.camera.IZoomLensControl;
-import net.osdn.gokigen.a01d.camera.olympuspen.wrapper.hardware.OlympusPenHardwareStatus;
 import net.osdn.gokigen.a01d.camera.theta.wrapper.hardware.ThetaHardwareStatus;
 import net.osdn.gokigen.a01d.camera.utils.SimpleHttpClient;
 
index d067505..cc4d68f 100644 (file)
@@ -10,6 +10,7 @@ import androidx.preference.PreferenceManager;
 import net.osdn.gokigen.a01d.R;
 import net.osdn.gokigen.a01d.camera.ICameraConnection;
 import net.osdn.gokigen.a01d.camera.ICameraStatusReceiver;
+import net.osdn.gokigen.a01d.camera.theta.wrapper.IThetaSessionIdNotifier;
 import net.osdn.gokigen.a01d.camera.utils.SimpleHttpClient;
 import net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor;
 
@@ -26,13 +27,15 @@ public class ThetaCameraConnectSequence implements Runnable
     private final Activity context;
     private final ICameraConnection cameraConnection;
     private final ICameraStatusReceiver cameraStatusReceiver;
+    private final IThetaSessionIdNotifier sessionIdNotifier;
 
-    ThetaCameraConnectSequence(@NonNull Activity context, @NonNull ICameraStatusReceiver statusReceiver, @NonNull final ICameraConnection cameraConnection)
+    ThetaCameraConnectSequence(@NonNull Activity context, @NonNull ICameraStatusReceiver statusReceiver, @NonNull final ICameraConnection cameraConnection, @NonNull IThetaSessionIdNotifier sessionIdNotifier)
     {
         Log.v(TAG, "ThetaCameraConnectSequence");
         this.context = context;
         this.cameraConnection = cameraConnection;
         this.cameraStatusReceiver = statusReceiver;
+        this.sessionIdNotifier = sessionIdNotifier;
     }
 
     @Override
@@ -125,6 +128,7 @@ public class ThetaCameraConnectSequence implements Runnable
             if (response.length() > 0)
             {
                 int apiLevel = 1;
+                String sessionId = null;
                JSONObject object = new JSONObject(response);
                try
                {
@@ -134,12 +138,18 @@ public class ThetaCameraConnectSequence implements Runnable
                {
                    e.printStackTrace();
                }
+                try
+                {
+                    sessionId = object.getJSONObject("state").getString("sessionId");
+                    sessionIdNotifier.receivedSessionId(sessionId);
+                }
+                catch (Exception e)
+                {
+                    e.printStackTrace();
+                }
                if (apiLevel != 2)
                {
-                   JSONObject jsonObject = object.getJSONObject("state");
-                   String sessionId = jsonObject.getString("sessionId");
                    String setApiLevelData = "{\"name\":\"camera.setOptions\",\"parameters\":{" + "\"sessionId\" : \"" + sessionId + "\", \"options\":{ \"clientVersion\":2}}}";
-
                    String response3 = SimpleHttpClient.httpPost(commandsExecuteUrl, setApiLevelData, TIMEOUT_MS);
                    Log.v(TAG, " " + commandsExecuteUrl + " " + setApiLevelData + " " + response3);
                }
index ae556e8..fa6f1d6 100644 (file)
@@ -1,14 +1,13 @@
 package net.osdn.gokigen.a01d.camera.theta.wrapper.connection;
 
-import android.app.Activity;
-
 public class ThetaCameraDisconnectSequence implements Runnable
 {
-    private final String TAG = this.toString();
+    //private final String TAG = this.toString();
 
-    ThetaCameraDisconnectSequence(Activity activity, boolean isOff)
+    ThetaCameraDisconnectSequence()
+    //ThetaCameraDisconnectSequence(Activity activity, boolean isOff)
     {
-        //
+
     }
 
     @Override
index 63a1e50..261a87a 100644 (file)
@@ -18,6 +18,7 @@ import androidx.appcompat.app.AlertDialog;
 import net.osdn.gokigen.a01d.R;
 import net.osdn.gokigen.a01d.camera.ICameraConnection;
 import net.osdn.gokigen.a01d.camera.ICameraStatusReceiver;
+import net.osdn.gokigen.a01d.camera.theta.wrapper.IThetaSessionIdNotifier;
 
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
@@ -28,6 +29,7 @@ public class ThetaConnection implements ICameraConnection
     private final Activity context;
     private final ICameraStatusReceiver statusReceiver;
     private final BroadcastReceiver connectionReceiver;
+    private final IThetaSessionIdNotifier sessionIdNotifier;
     //private final ConnectivityManager connectivityManager;
     private final Executor cameraExecutor = Executors.newFixedThreadPool(1);
     //private final Handler networkConnectionTimeoutHandler;
@@ -39,11 +41,12 @@ public class ThetaConnection implements ICameraConnection
      *
      *
      */
-    public ThetaConnection(@NonNull final Activity context, @NonNull final ICameraStatusReceiver statusReceiver)
+    public ThetaConnection(@NonNull final Activity context, @NonNull final ICameraStatusReceiver statusReceiver, @NonNull final IThetaSessionIdNotifier sessionIdNotifier)
     {
         Log.v(TAG, "ThetaConnection()");
         this.context = context;
         this.statusReceiver = statusReceiver;
+        this.sessionIdNotifier = sessionIdNotifier;
         connectionReceiver = new BroadcastReceiver()
         {
             @Override
@@ -239,10 +242,11 @@ public class ThetaConnection implements ICameraConnection
      */
     private void disconnectFromCamera(final boolean powerOff)
     {
-        Log.v(TAG, "disconnectFromCamera()");
+        Log.v(TAG, "disconnectFromCamera() : " + powerOff);
         try
         {
-            cameraExecutor.execute(new ThetaCameraDisconnectSequence(context, powerOff));
+            //cameraExecutor.execute(new ThetaCameraDisconnectSequence(context, powerOff));
+            cameraExecutor.execute(new ThetaCameraDisconnectSequence());
         }
         catch (Exception e)
         {
@@ -259,7 +263,7 @@ public class ThetaConnection implements ICameraConnection
         connectionStatus = CameraConnectionStatus.CONNECTING;
         try
         {
-            cameraExecutor.execute(new ThetaCameraConnectSequence(context, statusReceiver, this));
+            cameraExecutor.execute(new ThetaCameraConnectSequence(context, statusReceiver, this, sessionIdNotifier));
         }
         catch (Exception e)
         {
index 2898e56..8f4f001 100644 (file)
@@ -4,7 +4,10 @@ import android.util.Log;
 
 import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.net.HttpURLConnection;
 import java.net.Socket;
 import java.net.URL;
@@ -43,6 +46,70 @@ public class SimpleLiveviewSlicer
             mInputStream = inputStream;
     }
 
+    public void open(String liveviewUrl, String postData)
+    {
+        OutputStream outputStream = null;
+        OutputStreamWriter writer = null;
+        try
+        {
+            if ((mInputStream != null)||(mHttpConn != null))
+            {
+                Log.v(TAG, "Slicer is already open.");
+                return;
+            }
+
+            final URL urlObj = new URL(liveviewUrl);
+            mHttpConn = (HttpURLConnection) urlObj.openConnection();
+            mHttpConn.setRequestMethod("POST");
+            mHttpConn.setConnectTimeout(CONNECTION_TIMEOUT);
+            {
+                mHttpConn.setDoInput(true);
+                mHttpConn.setDoOutput(true);
+                outputStream = mHttpConn.getOutputStream();
+                writer = new OutputStreamWriter(outputStream, "UTF-8");
+                writer.write(postData);
+                writer.flush();
+                writer.close();
+                writer = null;
+                outputStream.close();
+                outputStream = null;
+            }
+            if (mHttpConn.getResponseCode() == HttpURLConnection.HTTP_OK)
+            {
+                mInputStream = mHttpConn.getInputStream();
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        finally
+        {
+            try
+            {
+                if (writer != null)
+                {
+                    writer.close();
+                }
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+            try
+            {
+                if (outputStream != null)
+                {
+                    outputStream.close();
+                }
+            }
+            catch (IOException e)
+            {
+                e.printStackTrace();
+            }
+        }
+    }
+
     public void open(String liveviewUrl)
     {
         try