OPC(Olympus Air)用望遠鏡アプリ。
Révision | 360a8f5e5e7b84af3dcbbf5bed7a018915de07e6 (tree) |
---|---|
l'heure | 2019-07-21 19:03:08 |
Auteur | MRSa <mrsa@myad...> |
Commiter | MRSa |
ズームとシャッターのコマンドを受け付けるようにした。
@@ -23,8 +23,6 @@ public interface IPanasonicInterfaceProvider | ||
23 | 23 | IZoomLensControl getZoomLensControl(); |
24 | 24 | ICaptureControl getCaptureControl(); |
25 | 25 | IDisplayInjector getDisplayInjector(); |
26 | - List<String> getApiCommands(); | |
27 | - IPanasonicCameraApi getCameraApi(); | |
28 | 26 | |
29 | 27 | IPanasonicCamera getPanasonicCamera(); |
30 | 28 | } |
@@ -279,7 +279,7 @@ public class PanasonicCameraApiListFragment extends ListFragment implements Send | ||
279 | 279 | @Override |
280 | 280 | public void run() |
281 | 281 | { |
282 | - SendRequestDialog dialog = SendRequestDialog.newInstance(interfaceProvider.getPanasonicInterface().getCameraApi(), apiName, apiCallback); | |
282 | + SendRequestDialog dialog = SendRequestDialog.newInstance(interfaceProvider.getPanasonicInterface().getPanasonicCamera(), apiName, apiCallback); | |
283 | 283 | FragmentManager manager = getFragmentManager(); |
284 | 284 | String tag = "dialog"; |
285 | 285 | if (manager != null) |
@@ -15,7 +15,7 @@ import android.widget.Spinner; | ||
15 | 15 | import android.widget.TextView; |
16 | 16 | |
17 | 17 | import net.osdn.gokigen.a01d.R; |
18 | -import net.osdn.gokigen.a01d.camera.panasonic.wrapper.IPanasonicCameraApi; | |
18 | +import net.osdn.gokigen.a01d.camera.panasonic.wrapper.IPanasonicCamera; | |
19 | 19 | |
20 | 20 | import androidx.annotation.NonNull; |
21 | 21 | import androidx.annotation.Nullable; |
@@ -29,9 +29,9 @@ import androidx.fragment.app.DialogFragment; | ||
29 | 29 | public class SendRequestDialog extends DialogFragment |
30 | 30 | { |
31 | 31 | private final String TAG = toString(); |
32 | - private IPanasonicCameraApi cameraApi; | |
33 | 32 | private String method = ""; |
34 | 33 | private int selectedPosition = 0; |
34 | + private IPanasonicCamera camera = null; | |
35 | 35 | private SendRequestDialog.Callback callback = null; |
36 | 36 | Dialog myDialog = null; |
37 | 37 |
@@ -39,10 +39,10 @@ public class SendRequestDialog extends DialogFragment | ||
39 | 39 | * |
40 | 40 | * |
41 | 41 | */ |
42 | - public static SendRequestDialog newInstance(@NonNull IPanasonicCameraApi cameraApi, @NonNull String method, @Nullable SendRequestDialog.Callback callback) | |
42 | + public static SendRequestDialog newInstance(@NonNull IPanasonicCamera camera, @NonNull String method, @Nullable SendRequestDialog.Callback callback) | |
43 | 43 | { |
44 | 44 | SendRequestDialog instance = new SendRequestDialog(); |
45 | - instance.prepare(cameraApi, method, callback); | |
45 | + instance.prepare(camera, method, callback); | |
46 | 46 | |
47 | 47 | // パラメータはBundleにまとめておく |
48 | 48 | Bundle arguments = new Bundle(); |
@@ -57,9 +57,9 @@ public class SendRequestDialog extends DialogFragment | ||
57 | 57 | * |
58 | 58 | * |
59 | 59 | */ |
60 | - private void prepare(@NonNull IPanasonicCameraApi cameraApi,@NonNull String method, @Nullable SendRequestDialog.Callback callback) | |
60 | + private void prepare(@NonNull IPanasonicCamera camera,@NonNull String method, @Nullable SendRequestDialog.Callback callback) | |
61 | 61 | { |
62 | - this.cameraApi = cameraApi; | |
62 | + this.camera = camera; | |
63 | 63 | this.method = method; |
64 | 64 | this.callback = callback; |
65 | 65 | } |
@@ -92,7 +92,7 @@ public class SendRequestDialog extends DialogFragment | ||
92 | 92 | methodName.setText(""); |
93 | 93 | version.setText(activity.getString(R.string.dialog_version_hint)); |
94 | 94 | ArrayAdapter<String> adapter = new ArrayAdapter<>(activity, android.R.layout.simple_spinner_item); |
95 | - adapter.addAll(cameraApi.getPanasonicApiServiceList()); | |
95 | + //adapter.addAll(cameraApi.getPanasonicApiServiceList()); | |
96 | 96 | |
97 | 97 | int defaultSelection; |
98 | 98 | for (defaultSelection = (adapter.getCount() - 1); defaultSelection >= 0; defaultSelection--) |
@@ -3,7 +3,7 @@ package net.osdn.gokigen.a01d.camera.panasonic.operation; | ||
3 | 3 | import android.util.Log; |
4 | 4 | |
5 | 5 | import net.osdn.gokigen.a01d.camera.ICaptureControl; |
6 | -import net.osdn.gokigen.a01d.camera.panasonic.wrapper.IPanasonicCameraApi; | |
6 | +import net.osdn.gokigen.a01d.camera.panasonic.wrapper.IPanasonicCamera; | |
7 | 7 | import net.osdn.gokigen.a01d.camera.panasonic.operation.takepicture.SingleShotControl; |
8 | 8 | import net.osdn.gokigen.a01d.liveview.IAutoFocusFrameDisplay; |
9 | 9 | import net.osdn.gokigen.a01d.liveview.IIndicatorControl; |
@@ -20,9 +20,9 @@ public class PanasonicCameraCaptureControl implements ICaptureControl | ||
20 | 20 | singleShotControl = new SingleShotControl(frameDisplayer, indicator); |
21 | 21 | } |
22 | 22 | |
23 | - public void setCameraApi(@NonNull IPanasonicCameraApi panasonicCameraApi) | |
23 | + public void setCamera(@NonNull IPanasonicCamera panasonicCamera) | |
24 | 24 | { |
25 | - singleShotControl.setCameraApi(panasonicCameraApi); | |
25 | + singleShotControl.setCamera(panasonicCamera); | |
26 | 26 | } |
27 | 27 | |
28 | 28 | /** |
@@ -3,26 +3,26 @@ package net.osdn.gokigen.a01d.camera.panasonic.operation; | ||
3 | 3 | import android.util.Log; |
4 | 4 | |
5 | 5 | import net.osdn.gokigen.a01d.camera.IZoomLensControl; |
6 | -import net.osdn.gokigen.a01d.camera.panasonic.wrapper.IPanasonicCameraApi; | |
7 | -import net.osdn.gokigen.a01d.camera.sony.wrapper.ISonyCameraApi; | |
8 | - | |
9 | -import org.json.JSONObject; | |
6 | +import net.osdn.gokigen.a01d.camera.panasonic.wrapper.IPanasonicCamera; | |
7 | +import net.osdn.gokigen.a01d.camera.utils.SimpleHttpClient; | |
10 | 8 | |
11 | 9 | import androidx.annotation.NonNull; |
12 | 10 | |
13 | 11 | public class PanasonicCameraZoomLensControl implements IZoomLensControl |
14 | 12 | { |
15 | 13 | private final String TAG = toString(); |
16 | - private IPanasonicCameraApi cameraApi = null; | |
14 | + private IPanasonicCamera camera = null; | |
15 | + private boolean isZooming = false; | |
16 | + private static final int TIMEOUT_MS = 3000; | |
17 | 17 | |
18 | 18 | public PanasonicCameraZoomLensControl() |
19 | 19 | { |
20 | - Log.v(TAG, "SonyCameraZoomLensControl()"); | |
20 | + Log.v(TAG, "PanasonicCameraZoomLensControl()"); | |
21 | 21 | } |
22 | 22 | |
23 | - public void setCameraApi(@NonNull IPanasonicCameraApi panasonicCameraApi) | |
23 | + public void setCamera(@NonNull IPanasonicCamera panasonicCamera) | |
24 | 24 | { |
25 | - cameraApi = panasonicCameraApi; | |
25 | + camera = panasonicCamera; | |
26 | 26 | } |
27 | 27 | |
28 | 28 | @Override |
@@ -74,7 +74,7 @@ public class PanasonicCameraZoomLensControl implements IZoomLensControl | ||
74 | 74 | public boolean isDrivingZoomLens() |
75 | 75 | { |
76 | 76 | Log.v(TAG, "isDrivingZoomLens()"); |
77 | - return (false); | |
77 | + return (isZooming); | |
78 | 78 | } |
79 | 79 | |
80 | 80 | /** |
@@ -85,15 +85,23 @@ public class PanasonicCameraZoomLensControl implements IZoomLensControl | ||
85 | 85 | public void driveZoomLens(boolean isZoomIn) |
86 | 86 | { |
87 | 87 | Log.v(TAG, "driveZoomLens() : " + isZoomIn); |
88 | - if (cameraApi == null) | |
88 | + if (camera == null) | |
89 | 89 | { |
90 | 90 | Log.v(TAG, "IPanasonicCameraApi is null..."); |
91 | 91 | return; |
92 | 92 | } |
93 | 93 | try |
94 | 94 | { |
95 | - final String direction = (isZoomIn) ? "in" : "out"; | |
96 | - final String movement = "1shot"; | |
95 | + String command; | |
96 | + if (isZooming) | |
97 | + { | |
98 | + command = "cam.cgi?mode=camcmd&value=zoomstop"; | |
99 | + } | |
100 | + else | |
101 | + { | |
102 | + command = (isZoomIn) ? "cam.cgi?mode=camcmd&value=tele-normal" : "cam.cgi?mode=camcmd&value=wide-normal"; | |
103 | + } | |
104 | + final String direction = command; | |
97 | 105 | Thread thread = new Thread(new Runnable() |
98 | 106 | { |
99 | 107 | @Override |
@@ -101,10 +109,14 @@ public class PanasonicCameraZoomLensControl implements IZoomLensControl | ||
101 | 109 | { |
102 | 110 | try |
103 | 111 | { |
104 | - JSONObject resultsObj = cameraApi.actZoom(direction, movement); | |
105 | - if (resultsObj == null) | |
112 | + String reply = SimpleHttpClient.httpGet(camera.getCmdUrl() + direction, TIMEOUT_MS); | |
113 | + if (reply.contains("ok")) | |
114 | + { | |
115 | + isZooming = !isZooming; | |
116 | + } | |
117 | + else | |
106 | 118 | { |
107 | - Log.v(TAG, "driveZoomLens() reply is null."); | |
119 | + Log.v(TAG, "driveZoomLens() reply is failure."); | |
108 | 120 | } |
109 | 121 | } |
110 | 122 | catch (Exception e) |
@@ -2,20 +2,20 @@ package net.osdn.gokigen.a01d.camera.panasonic.operation.takepicture; | ||
2 | 2 | |
3 | 3 | import android.util.Log; |
4 | 4 | |
5 | -import net.osdn.gokigen.a01d.camera.panasonic.wrapper.IPanasonicCameraApi; | |
5 | +import net.osdn.gokigen.a01d.camera.panasonic.wrapper.IPanasonicCamera; | |
6 | +import net.osdn.gokigen.a01d.camera.utils.SimpleHttpClient; | |
6 | 7 | import net.osdn.gokigen.a01d.liveview.IAutoFocusFrameDisplay; |
7 | 8 | import net.osdn.gokigen.a01d.liveview.IIndicatorControl; |
8 | 9 | |
9 | -import org.json.JSONObject; | |
10 | - | |
11 | 10 | import androidx.annotation.NonNull; |
12 | 11 | |
13 | 12 | public class SingleShotControl |
14 | 13 | { |
15 | 14 | private static final String TAG = SingleShotControl.class.getSimpleName(); |
15 | + private static final int TIMEOUT_MS = 3000; | |
16 | 16 | private final IAutoFocusFrameDisplay frameDisplayer; |
17 | 17 | private final IIndicatorControl indicator; |
18 | - private IPanasonicCameraApi cameraApi = null; | |
18 | + private IPanasonicCamera camera = null; | |
19 | 19 | |
20 | 20 | /** |
21 | 21 | * |
@@ -31,9 +31,9 @@ public class SingleShotControl | ||
31 | 31 | * |
32 | 32 | * |
33 | 33 | */ |
34 | - public void setCameraApi(@NonNull IPanasonicCameraApi panasonicCameraApi) | |
34 | + public void setCamera(@NonNull IPanasonicCamera panasonicCamera) | |
35 | 35 | { |
36 | - this.cameraApi = panasonicCameraApi; | |
36 | + this.camera = panasonicCamera; | |
37 | 37 | } |
38 | 38 | |
39 | 39 | /** |
@@ -43,9 +43,9 @@ public class SingleShotControl | ||
43 | 43 | public void singleShot() |
44 | 44 | { |
45 | 45 | Log.v(TAG, "singleShot()"); |
46 | - if (cameraApi == null) | |
46 | + if (camera == null) | |
47 | 47 | { |
48 | - Log.v(TAG, "ISonyCameraApi is null..."); | |
48 | + Log.v(TAG, "IPanasonicCamera is null..."); | |
49 | 49 | return; |
50 | 50 | } |
51 | 51 | try |
@@ -57,11 +57,10 @@ public class SingleShotControl | ||
57 | 57 | { |
58 | 58 | try |
59 | 59 | { |
60 | - //JSONObject resultsObj = cameraApi.awaitTakePicture(); | |
61 | - JSONObject resultsObj = cameraApi.actTakePicture(); | |
62 | - if (resultsObj == null) | |
60 | + String reply = SimpleHttpClient.httpGet(camera.getCmdUrl() + "cam.cgi?mode=camcmd&value=capture", TIMEOUT_MS); | |
61 | + if (!reply.contains("ok")) | |
63 | 62 | { |
64 | - Log.v(TAG, "setTouchAFPosition() reply is null."); | |
63 | + Log.v(TAG, "Capture Failure... : " + reply); | |
65 | 64 | } |
66 | 65 | } |
67 | 66 | catch (Exception e) |
@@ -21,6 +21,7 @@ import net.osdn.gokigen.a01d.camera.panasonic.wrapper.connection.PanasonicCamera | ||
21 | 21 | import net.osdn.gokigen.a01d.camera.panasonic.wrapper.eventlistener.CameraEventObserver; |
22 | 22 | import net.osdn.gokigen.a01d.camera.panasonic.wrapper.eventlistener.ICameraEventObserver; |
23 | 23 | import net.osdn.gokigen.a01d.camera.panasonic.wrapper.eventlistener.ICameraStatusHolder; |
24 | +import net.osdn.gokigen.a01d.camera.utils.SimpleHttpClient; | |
24 | 25 | import net.osdn.gokigen.a01d.liveview.IAutoFocusFrameDisplay; |
25 | 26 | import net.osdn.gokigen.a01d.liveview.IIndicatorControl; |
26 | 27 | import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener; |
@@ -36,6 +37,7 @@ public class PanasonicCameraWrapper implements IPanasonicCameraHolder, IPanasoni | ||
36 | 37 | { |
37 | 38 | private final String TAG = toString(); |
38 | 39 | private final Activity context; |
40 | + private static final int TIMEOUT_MS = 3000; | |
39 | 41 | private final ICameraStatusReceiver provider; |
40 | 42 | private final ICameraChangeListener listener; |
41 | 43 | private IPanasonicCamera panasonicCamera = null; |
@@ -61,11 +63,11 @@ public class PanasonicCameraWrapper implements IPanasonicCameraHolder, IPanasoni | ||
61 | 63 | { |
62 | 64 | this.panasonicCameraApi = PanasonicCameraApi.newInstance(panasonicCamera); |
63 | 65 | eventObserver = CameraEventObserver.newInstance(context, panasonicCameraApi); |
64 | - liveViewControl = new PanasonicLiveViewControl(panasonicCameraApi); | |
66 | + liveViewControl = new PanasonicLiveViewControl(panasonicCamera); | |
65 | 67 | |
66 | 68 | focusControl.setCameraApi(panasonicCameraApi); |
67 | - captureControl.setCameraApi(panasonicCameraApi); | |
68 | - zoomControl.setCameraApi(panasonicCameraApi); | |
69 | + captureControl.setCamera(panasonicCamera); | |
70 | + zoomControl.setCamera(panasonicCamera); | |
69 | 71 | } |
70 | 72 | catch (Exception e) |
71 | 73 | { |
@@ -76,22 +78,19 @@ public class PanasonicCameraWrapper implements IPanasonicCameraHolder, IPanasoni | ||
76 | 78 | @Override |
77 | 79 | public void startRecMode() |
78 | 80 | { |
79 | - try { | |
80 | - List<String> apiCommands = getApiCommands(); | |
81 | - int index = apiCommands.indexOf("startRecMode"); | |
82 | - if (index > 0) | |
81 | + try | |
82 | + { | |
83 | + // 撮影モード(RecMode)に切り替え | |
84 | + String reply = SimpleHttpClient.httpGet(this.panasonicCamera.getCmdUrl() + "cam.cgi?mode=camcmd&value=recmode", TIMEOUT_MS); | |
85 | + if (!reply.contains("ok")) | |
83 | 86 | { |
84 | - // startRecMode発行 | |
85 | - Log.v(TAG, "----- THIS CAMERA NEEDS COMMAND 'startRecMode'."); | |
86 | - panasonicCameraApi.startRecMode(); | |
87 | + Log.v(TAG, "CAMERA REPLIED ERROR : CHANGE RECMODE."); | |
87 | 88 | } |
88 | 89 | } |
89 | 90 | catch (Exception e) |
90 | 91 | { |
91 | 92 | e.printStackTrace(); |
92 | 93 | } |
93 | - | |
94 | - | |
95 | 94 | } |
96 | 95 | |
97 | 96 | @Override |
@@ -172,30 +171,6 @@ public class PanasonicCameraWrapper implements IPanasonicCameraHolder, IPanasoni | ||
172 | 171 | } |
173 | 172 | |
174 | 173 | @Override |
175 | - public List<String> getApiCommands() | |
176 | - { | |
177 | - List<String> availableApis = new ArrayList<>(); | |
178 | - try | |
179 | - { | |
180 | - String apiList = panasonicCameraApi.getAvailableApiList().getString("result"); | |
181 | - apiList = apiList.replace("[","").replace("]", "").replace("\"",""); | |
182 | - String[] apiListSplit = apiList.split(","); | |
183 | - availableApis = Arrays.asList(apiListSplit); | |
184 | - } | |
185 | - catch (Exception e) | |
186 | - { | |
187 | - e.printStackTrace(); | |
188 | - } | |
189 | - return (availableApis); | |
190 | - } | |
191 | - | |
192 | - @Override | |
193 | - public IPanasonicCameraApi getCameraApi() | |
194 | - { | |
195 | - return (panasonicCameraApi); | |
196 | - } | |
197 | - | |
198 | - @Override | |
199 | 174 | public IPanasonicCamera getPanasonicCamera() |
200 | 175 | { |
201 | 176 | return (panasonicCamera); |
@@ -1,30 +1,37 @@ | ||
1 | 1 | package net.osdn.gokigen.a01d.camera.panasonic.wrapper; |
2 | 2 | |
3 | - | |
4 | 3 | import android.util.Log; |
5 | 4 | |
6 | 5 | import net.osdn.gokigen.a01d.camera.ILiveViewControl; |
7 | -import net.osdn.gokigen.a01d.camera.utils.SimpleLiveviewSlicer; | |
6 | +import net.osdn.gokigen.a01d.camera.utils.SimpleHttpClient; | |
8 | 7 | import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener; |
9 | 8 | import net.osdn.gokigen.a01d.liveview.liveviewlistener.CameraLiveViewListenerImpl; |
10 | 9 | |
11 | -import org.json.JSONArray; | |
12 | -import org.json.JSONObject; | |
13 | - | |
14 | 10 | import androidx.annotation.NonNull; |
15 | 11 | |
12 | +import java.net.DatagramPacket; | |
13 | +import java.net.DatagramSocket; | |
14 | +import java.util.Arrays; | |
15 | + | |
16 | 16 | public class PanasonicLiveViewControl implements ILiveViewControl |
17 | 17 | { |
18 | 18 | private final String TAG = toString(); |
19 | - private final IPanasonicCameraApi cameraApi; | |
19 | + private final IPanasonicCamera camera; | |
20 | 20 | //private final BlockingQueue<byte[]> mJpegQueue = new ArrayBlockingQueue<>(2); |
21 | 21 | private final CameraLiveViewListenerImpl liveViewListener; |
22 | - private boolean whileFetching = false; | |
23 | - private static final int FETCH_ERROR_MAX = 30; | |
22 | + private DatagramSocket receiveSocket = null; | |
23 | + private boolean whileStreamReceive = false; | |
24 | + private int errorOccur = 0; | |
25 | + private static final int ERROR_MAX = 30; | |
26 | + private static final int RECEIVE_BUFFER_SIZE = 1024 * 1024 * 4; | |
27 | + private static final int TIMEOUT_MS = 3000; | |
28 | + private static final int LIVEVIEW_PORT = 49152; | |
29 | + private final String LIVEVIEW_START_REQUEST = "cam.cgi?mode=startstream&value=49152"; | |
30 | + private final String LIVEVIEW_STOP_REQUEST = "cam.cgi?mode=stopstream"; | |
24 | 31 | |
25 | - PanasonicLiveViewControl(@NonNull IPanasonicCameraApi cameraApi) | |
32 | + PanasonicLiveViewControl(@NonNull IPanasonicCamera camera) | |
26 | 33 | { |
27 | - this.cameraApi = cameraApi; | |
34 | + this.camera = camera; | |
28 | 35 | liveViewListener = new CameraLiveViewListenerImpl(); |
29 | 36 | } |
30 | 37 |
@@ -47,18 +54,32 @@ public class PanasonicLiveViewControl implements ILiveViewControl | ||
47 | 54 | { |
48 | 55 | try |
49 | 56 | { |
50 | - JSONObject replyJson; | |
51 | - replyJson = cameraApi.startLiveview(); | |
52 | - if (!PanasonicCameraApi.isErrorReply(replyJson)) | |
57 | + startReceiveStream(); | |
58 | + if (!whileStreamReceive) | |
59 | + { | |
60 | + Log.v(TAG, "CANNOT OPEN : UDP RECEIVE SOCKET"); | |
61 | + return; | |
62 | + } | |
63 | + String requestUrl = camera.getCmdUrl() + LIVEVIEW_START_REQUEST; | |
64 | + String reply = SimpleHttpClient.httpGet(requestUrl, TIMEOUT_MS); | |
65 | + if (!reply.contains("<result>ok</result>")) | |
53 | 66 | { |
54 | 67 | try |
55 | 68 | { |
56 | - JSONArray resultsObj = replyJson.getJSONArray("result"); | |
57 | - if (1 <= resultsObj.length()) | |
69 | + // エラー回数のカウントアップ | |
70 | + errorOccur++; | |
71 | + | |
72 | + // 少し待つ... | |
73 | + Thread.sleep(TIMEOUT_MS); | |
74 | + | |
75 | + if (errorOccur < ERROR_MAX) | |
58 | 76 | { |
59 | - // Obtain liveview URL from the result. | |
60 | - final String liveviewUrl = resultsObj.getString(0); | |
61 | - start(liveviewUrl); | |
77 | + Log.v(TAG, "RETRY START LIVEVIEW... : " + errorOccur); | |
78 | + startLiveView(); | |
79 | + } | |
80 | + else | |
81 | + { | |
82 | + Log.v(TAG, "RETRY OVER : START LIVEVIEW"); | |
62 | 83 | } |
63 | 84 | } |
64 | 85 | catch (Exception e) |
@@ -66,6 +87,10 @@ public class PanasonicLiveViewControl implements ILiveViewControl | ||
66 | 87 | e.printStackTrace(); |
67 | 88 | } |
68 | 89 | } |
90 | + else | |
91 | + { | |
92 | + Log.v(TAG, " ----- START LIVEVIEW ----- : " + requestUrl); | |
93 | + } | |
69 | 94 | } |
70 | 95 | catch (Exception e) |
71 | 96 | { |
@@ -94,10 +119,16 @@ public class PanasonicLiveViewControl implements ILiveViewControl | ||
94 | 119 | { |
95 | 120 | try |
96 | 121 | { |
97 | - JSONObject resultsObj = cameraApi.stopLiveview(); | |
98 | - if (resultsObj == null) | |
122 | + String reply = SimpleHttpClient.httpGet(camera.getCmdUrl() + LIVEVIEW_STOP_REQUEST, TIMEOUT_MS); | |
123 | + if (!reply.contains("<result>ok</result>")) | |
124 | + { | |
125 | + Log.v(TAG, "stopLiveview() reply is fail... "); | |
126 | + } | |
127 | + else | |
99 | 128 | { |
100 | - Log.v(TAG, "stopLiveview() reply is null."); | |
129 | + // ライブビューウォッチャーを止める | |
130 | + whileStreamReceive = false; | |
131 | + Log.v(TAG, "stopLiveview() is issued."); | |
101 | 132 | } |
102 | 133 | } |
103 | 134 | catch (Exception e) |
@@ -138,100 +169,124 @@ public class PanasonicLiveViewControl implements ILiveViewControl | ||
138 | 169 | return (1.0f); |
139 | 170 | } |
140 | 171 | |
141 | - | |
142 | - | |
143 | - public boolean start(final String streamUrl) | |
172 | + private void startReceiveStream() | |
144 | 173 | { |
145 | - if (streamUrl == null) | |
174 | + if (whileStreamReceive) | |
146 | 175 | { |
147 | - Log.e(TAG, "start() streamUrl is null."); | |
148 | - return (false); | |
176 | + Log.v(TAG, "startReceiveStream() : already starting."); | |
177 | + return; | |
149 | 178 | } |
150 | - if (whileFetching) | |
179 | + | |
180 | + // ソケットをあける (UDP) | |
181 | + try | |
151 | 182 | { |
152 | - Log.v(TAG, "start() already starting."); | |
183 | + receiveSocket = new DatagramSocket(LIVEVIEW_PORT); | |
184 | + whileStreamReceive = true; | |
185 | + } | |
186 | + catch (Exception e) | |
187 | + { | |
188 | + e.printStackTrace(); | |
189 | + whileStreamReceive = false; | |
190 | + receiveSocket = null; | |
153 | 191 | } |
154 | - whileFetching = true; | |
155 | 192 | |
156 | - // A thread for retrieving liveview data from server. | |
193 | + // 受信スレッドを動かす | |
194 | + Thread thread = new Thread(new Runnable() { | |
195 | + @Override | |
196 | + public void run() { | |
197 | + receiverThread(); | |
198 | + } | |
199 | + }); | |
157 | 200 | try |
158 | 201 | { |
159 | - Thread thread = new Thread(new Runnable() | |
202 | + thread.start(); | |
203 | + } | |
204 | + catch (Exception e) | |
205 | + { | |
206 | + e.printStackTrace(); | |
207 | + } | |
208 | + } | |
209 | + | |
210 | + private void checkReceiveImage(@NonNull DatagramPacket packet) | |
211 | + { | |
212 | + int dataLength = packet.getLength(); | |
213 | + int searchIndex = 0; | |
214 | + int startPosition = 0; | |
215 | + int[] startmarker = { 0xff, 0xd8 }; | |
216 | + byte[] receivedData = packet.getData(); | |
217 | + if (receivedData == null) | |
218 | + { | |
219 | + // 受信データが取れなかったので終了する | |
220 | + Log.v(TAG, "RECEIVED DATA IS NULL..."); | |
221 | + return; | |
222 | + } | |
223 | + //Log.v(TAG, "RECEIVED PACKET : " + dataLength); | |
224 | + while (startPosition < dataLength) | |
225 | + { | |
226 | + // 先頭のjpegマーカーが出てくるまで読み飛ばす | |
227 | + try | |
160 | 228 | { |
161 | - @Override | |
162 | - public void run() | |
229 | + if (receivedData[startPosition++] == (byte) startmarker[searchIndex]) | |
163 | 230 | { |
164 | - Log.d(TAG, "Starting retrieving streaming data from server."); | |
165 | - SimpleLiveviewSlicer slicer = null; | |
166 | - int continuousNullDataReceived = 0; | |
167 | - try | |
231 | + searchIndex++; | |
232 | + if (searchIndex >= startmarker.length) | |
168 | 233 | { |
169 | - // Create Slicer to open the stream and parse it. | |
170 | - slicer = new SimpleLiveviewSlicer(); | |
171 | - slicer.open(streamUrl); | |
172 | - | |
173 | - while (whileFetching) | |
174 | - { | |
175 | - final SimpleLiveviewSlicer.Payload payload = slicer.nextPayload(); | |
176 | - if (payload == null) | |
177 | - { | |
178 | - //Log.v(TAG, "Liveview Payload is null."); | |
179 | - continuousNullDataReceived++; | |
180 | - if (continuousNullDataReceived > FETCH_ERROR_MAX) | |
181 | - { | |
182 | - Log.d(TAG, " FETCH ERROR MAX OVER "); | |
183 | - break; | |
184 | - } | |
185 | - continue; | |
186 | - } | |
187 | - //if (mJpegQueue.size() == 2) | |
188 | - //{ | |
189 | - // mJpegQueue.remove(); | |
190 | - //} | |
191 | - //mJpegQueue.add(payload.getJpegData()); | |
192 | - liveViewListener.onUpdateLiveView(payload.getJpegData(), null); | |
193 | - continuousNullDataReceived = 0; | |
194 | - } | |
195 | - } | |
196 | - catch (Exception e) | |
197 | - { | |
198 | - e.printStackTrace(); | |
199 | - } | |
200 | - finally | |
201 | - { | |
202 | - try | |
203 | - { | |
204 | - if (slicer != null) | |
205 | - { | |
206 | - slicer.close(); | |
207 | - } | |
208 | - } | |
209 | - catch (Exception e) | |
210 | - { | |
211 | - e.printStackTrace(); | |
212 | - } | |
213 | - //mJpegQueue.clear(); | |
214 | - if ((!whileFetching)&&(continuousNullDataReceived > FETCH_ERROR_MAX)) | |
215 | - { | |
216 | - // 再度ライブビューのスタートをやってみる。 | |
217 | - whileFetching = false; | |
218 | - //continuousNullDataReceived = 0; | |
219 | - start(streamUrl); | |
220 | - } | |
234 | + break; | |
221 | 235 | } |
222 | 236 | } |
223 | - }); | |
224 | - thread.start(); | |
237 | + } | |
238 | + catch (Exception e) | |
239 | + { | |
240 | + e.printStackTrace(); | |
241 | + return; | |
242 | + } | |
243 | + } | |
244 | + int offset = startPosition - startmarker.length; | |
245 | + liveViewListener.onUpdateLiveView(Arrays.copyOfRange(receivedData, offset, dataLength - offset), null); | |
246 | + } | |
247 | + | |
248 | + private void receiverThread() | |
249 | + { | |
250 | + byte[] buffer = new byte[RECEIVE_BUFFER_SIZE]; | |
251 | + while (whileStreamReceive) | |
252 | + { | |
253 | + try | |
254 | + { | |
255 | + DatagramPacket receive_packet = new DatagramPacket(buffer, buffer.length); | |
256 | + if (receiveSocket != null) | |
257 | + { | |
258 | + receiveSocket.receive(receive_packet); | |
259 | + checkReceiveImage(receive_packet); | |
260 | + } | |
261 | + else | |
262 | + { | |
263 | + Log.v(TAG, "receiveSocket is NULL..."); | |
264 | + } | |
265 | + } | |
266 | + catch (Exception e) | |
267 | + { | |
268 | + e.printStackTrace(); | |
269 | + } | |
270 | + } | |
271 | + try | |
272 | + { | |
273 | + if (receiveSocket != null) | |
274 | + { | |
275 | + receiveSocket.close(); | |
276 | + receiveSocket = null; | |
277 | + } | |
225 | 278 | } |
226 | 279 | catch (Exception e) |
227 | 280 | { |
228 | 281 | e.printStackTrace(); |
229 | 282 | } |
230 | - return (true); | |
283 | + Log.v(TAG, " ----- startReceiveStream() : Finished."); | |
284 | + System.gc(); | |
231 | 285 | } |
232 | 286 | |
233 | 287 | public ILiveViewListener getLiveViewListener() |
234 | 288 | { |
235 | 289 | return (liveViewListener); |
236 | 290 | } |
291 | + | |
237 | 292 | } |
@@ -9,7 +9,6 @@ import net.osdn.gokigen.a01d.camera.ICameraConnection; | ||
9 | 9 | import net.osdn.gokigen.a01d.camera.ICameraStatusReceiver; |
10 | 10 | import net.osdn.gokigen.a01d.camera.panasonic.wrapper.IPanasonicCamera; |
11 | 11 | import net.osdn.gokigen.a01d.camera.panasonic.wrapper.IPanasonicCameraHolder; |
12 | -import net.osdn.gokigen.a01d.camera.utils.SimpleHttpClient; | |
13 | 12 | |
14 | 13 | import androidx.annotation.NonNull; |
15 | 14 |
@@ -123,6 +122,7 @@ public class PanasonicCameraConnectSequence implements Runnable, PanasonicSsdpCl | ||
123 | 122 | } |
124 | 123 | } |
125 | 124 | |
125 | +/* | |
126 | 126 | private void waitForAMoment(long mills) |
127 | 127 | { |
128 | 128 | if (mills > 0) |
@@ -135,11 +135,11 @@ public class PanasonicCameraConnectSequence implements Runnable, PanasonicSsdpCl | ||
135 | 135 | } |
136 | 136 | } |
137 | 137 | } |
138 | +*/ | |
138 | 139 | |
139 | 140 | @Override |
140 | 141 | public void onErrorFinished(String reason) |
141 | 142 | { |
142 | 143 | cameraConnection.alertConnectingFailed(reason); |
143 | 144 | } |
144 | - | |
145 | 145 | } |
@@ -55,7 +55,7 @@ public class CameraEventObserver implements ICameraEventObserver | ||
55 | 55 | return (false); |
56 | 56 | } |
57 | 57 | |
58 | - isEventMonitoring = true; | |
58 | + isEventMonitoring = false; | |
59 | 59 | try |
60 | 60 | { |
61 | 61 | Thread thread = new Thread() |