OPC(Olympus Air)用望遠鏡アプリ。
Revisão | 3bafcc2d212846acd6b6754e7af240b95111fa9c (tree) |
---|---|
Hora | 2020-09-26 11:58:09 |
Autor | MRSa <mrsa@myad...> |
Commiter | MRSa |
FujiXのLiveView取得部分をkotlin化。
@@ -0,0 +1,295 @@ | ||
1 | +package net.osdn.gokigen.a01d.camera.fujix.wrapper.liveview | |
2 | + | |
3 | +import android.app.Activity | |
4 | +import android.util.Log | |
5 | +import androidx.preference.PreferenceManager | |
6 | +import net.osdn.gokigen.a01d.camera.ILiveViewControl | |
7 | +import net.osdn.gokigen.a01d.camera.fujix.wrapper.command.IFujiXCommunication | |
8 | +import net.osdn.gokigen.a01d.camera.utils.SimpleLogDumper | |
9 | +import net.osdn.gokigen.a01d.liveview.liveviewlistener.CameraLiveViewListenerImpl | |
10 | +import net.osdn.gokigen.a01d.liveview.liveviewlistener.ILiveViewListener | |
11 | +import net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor | |
12 | +import java.net.Socket | |
13 | +import java.util.* | |
14 | + | |
15 | +class FujiXLiveViewControl(activity: Activity, private val ipAddress: String, private val portNumber: Int) : ILiveViewControl, IFujiXCommunication | |
16 | +{ | |
17 | + private val TAG = toString() | |
18 | + private val liveViewListener = CameraLiveViewListenerImpl() | |
19 | + private var waitMs = 0 | |
20 | + private var isStart = false | |
21 | + private val logcat = false | |
22 | + private val preferences = PreferenceManager.getDefaultSharedPreferences(activity) | |
23 | + | |
24 | + init | |
25 | + { | |
26 | + try | |
27 | + { | |
28 | + val waitMsStr = preferences.getString(IPreferencePropertyAccessor.FUJIX_LIVEVIEW_WAIT, IPreferencePropertyAccessor.FUJIX_LIVEVIEW_WAIT_DEFAULT_VALUE) | |
29 | + logcat(" waitMS : $waitMsStr") | |
30 | + if (waitMsStr != null) | |
31 | + { | |
32 | + val wait = waitMsStr.toInt() | |
33 | + if (wait in 20 .. 800) | |
34 | + { | |
35 | + waitMs = wait | |
36 | + } | |
37 | + } | |
38 | + } | |
39 | + catch (e: Exception) | |
40 | + { | |
41 | + e.printStackTrace() | |
42 | + waitMs = 100 | |
43 | + } | |
44 | + Log.v(TAG, " LOOP WAIT : $waitMs ms") | |
45 | + } | |
46 | + | |
47 | + override fun startLiveView() | |
48 | + { | |
49 | + if (isStart) | |
50 | + { | |
51 | + // すでに受信スレッド動作中なので抜ける | |
52 | + Log.v(TAG, " LiveView IS ALREADY STARTED") | |
53 | + return | |
54 | + } | |
55 | + isStart = true | |
56 | + try | |
57 | + { | |
58 | + Thread { | |
59 | + try | |
60 | + { | |
61 | + startReceive(Socket(ipAddress, portNumber)) | |
62 | + } | |
63 | + catch (e: Exception) | |
64 | + { | |
65 | + Log.v(TAG, " IP : $ipAddress port : $portNumber") | |
66 | + e.printStackTrace() | |
67 | + } | |
68 | + }.start() | |
69 | + } | |
70 | + catch (e : Exception) | |
71 | + { | |
72 | + e.printStackTrace() | |
73 | + } | |
74 | + } | |
75 | + | |
76 | + override fun stopLiveView() | |
77 | + { | |
78 | + isStart = false | |
79 | + } | |
80 | + | |
81 | + override fun updateDigitalZoom() | |
82 | + { | |
83 | + | |
84 | + } | |
85 | + | |
86 | + override fun updateMagnifyingLiveViewScale(isChangeScale: Boolean) | |
87 | + { | |
88 | + | |
89 | + } | |
90 | + | |
91 | + override fun getMagnifyingLiveViewScale(): Float | |
92 | + { | |
93 | + return (1.0f) | |
94 | + } | |
95 | + | |
96 | + override fun changeLiveViewSize(size: String) | |
97 | + { | |
98 | + | |
99 | + } | |
100 | + | |
101 | + override fun getDigitalZoomScale(): Float | |
102 | + { | |
103 | + return (1.0f) | |
104 | + } | |
105 | + | |
106 | + fun getLiveViewListener(): ILiveViewListener | |
107 | + { | |
108 | + return (liveViewListener) | |
109 | + } | |
110 | + | |
111 | + override fun connect(): Boolean | |
112 | + { | |
113 | + return (true) | |
114 | + } | |
115 | + | |
116 | + override fun disconnect() | |
117 | + { | |
118 | + isStart = false | |
119 | + } | |
120 | + | |
121 | + private fun logcat(message: String) | |
122 | + { | |
123 | + if (logcat) | |
124 | + { | |
125 | + Log.v(TAG, message) | |
126 | + } | |
127 | + } | |
128 | + | |
129 | + private fun dump_bytes(header : String, byteArray: ByteArray, size : Int = 24) | |
130 | + { | |
131 | + if (logcat) | |
132 | + { | |
133 | + SimpleLogDumper.dump_bytes(header, byteArray.copyOf(size)) | |
134 | + } | |
135 | + } | |
136 | + | |
137 | + private fun startReceive(socket: Socket) | |
138 | + { | |
139 | + var errorCount = 0 | |
140 | + val isr = socket.getInputStream() | |
141 | + val byteArray = ByteArray(BUFFER_SIZE + 32) | |
142 | + | |
143 | + while (isStart) | |
144 | + { | |
145 | + try | |
146 | + { | |
147 | + var findJpeg = false | |
148 | + var length_bytes: Int | |
149 | + var read_bytes = isr.read(byteArray, 0, BUFFER_SIZE) | |
150 | + if (read_bytes > DATA_HEADER_OFFSET) | |
151 | + { | |
152 | + // メッセージボディの先頭にあるメッセージ長分は読み込む | |
153 | + length_bytes = (byteArray[3].toInt() and 0xff shl 24) + (byteArray[2].toInt() and 0xff shl 16) + (byteArray[1].toInt() and 0xff shl 8) + (byteArray[0].toInt() and 0xff) | |
154 | + if (byteArray[18] == 0xff.toByte() && byteArray[19] == 0xd8.toByte()) | |
155 | + { | |
156 | + findJpeg = true | |
157 | + while (read_bytes < length_bytes && read_bytes < BUFFER_SIZE && length_bytes <= BUFFER_SIZE) | |
158 | + { | |
159 | + val append_bytes = isr.read(byteArray, read_bytes, length_bytes - read_bytes) | |
160 | + logcat("READ AGAIN : $append_bytes [$read_bytes]") | |
161 | + if (append_bytes < 0) | |
162 | + { | |
163 | + break | |
164 | + } | |
165 | + read_bytes = read_bytes + append_bytes | |
166 | + } | |
167 | + logcat("READ BYTES : " + read_bytes + " (" + length_bytes + " bytes, " + waitMs + "ms)") | |
168 | + } | |
169 | + else | |
170 | + { | |
171 | + // ウェイトを短めに入れてマーカーを拾うまで待つ | |
172 | + Thread.sleep(waitMs / 4.toLong()) | |
173 | + logcat(" --- wait LiveView ---") | |
174 | + continue | |
175 | + } | |
176 | + } | |
177 | + | |
178 | + // 先頭データをダンプする | |
179 | + dump_bytes("[LV]", byteArray) | |
180 | + if (findJpeg) | |
181 | + { | |
182 | + liveViewListener.onUpdateLiveView(Arrays.copyOfRange(byteArray, DATA_HEADER_OFFSET, read_bytes - DATA_HEADER_OFFSET), null) | |
183 | + errorCount = 0 | |
184 | + } | |
185 | + Thread.sleep(waitMs.toLong()) | |
186 | + } | |
187 | + catch (e: Exception) | |
188 | + { | |
189 | + e.printStackTrace() | |
190 | + errorCount++ | |
191 | + } | |
192 | + | |
193 | + if (errorCount > ERROR_LIMIT) | |
194 | + { | |
195 | + // エラーが連続でたくさん出たらループをストップ(ライブビューを停止)させる | |
196 | + isStart = false | |
197 | + } | |
198 | + } | |
199 | + | |
200 | + try | |
201 | + { | |
202 | + isr.close() | |
203 | + socket.close() | |
204 | + } | |
205 | + catch (e: Exception) | |
206 | + { | |
207 | + e.printStackTrace() | |
208 | + } | |
209 | + } | |
210 | + | |
211 | + private fun startReceiveAlter(socket: Socket) | |
212 | + { | |
213 | + var errorCount = 0 | |
214 | + val isr = socket.getInputStream() | |
215 | + val byteArray = ByteArray(BUFFER_SIZE + 32) | |
216 | + | |
217 | + while (isStart) | |
218 | + { | |
219 | + try | |
220 | + { | |
221 | + var findJpeg = false | |
222 | + var length_bytes: Int | |
223 | + var read_bytes = isr.read(byteArray, 0, BUFFER_SIZE) | |
224 | + | |
225 | + // 先頭データ(48バイト分)をダンプ | |
226 | + // dump_bytes("[lv]", byteArray, 48) | |
227 | + if (read_bytes > DATA_HEADER_OFFSET) | |
228 | + { | |
229 | + // メッセージボディの先頭にあるメッセージ長分は読み込む | |
230 | + length_bytes = (byteArray[3].toInt() and 0xff shl 24) + (byteArray[2].toInt() and 0xff shl 16) + (byteArray[1].toInt() and 0xff shl 8) + (byteArray[0].toInt() and 0xff) | |
231 | + if (byteArray[18] == 0xff.toByte() && byteArray[19] == 0xd8.toByte()) | |
232 | + { | |
233 | + findJpeg = true | |
234 | + while (read_bytes < length_bytes && read_bytes < BUFFER_SIZE && length_bytes <= BUFFER_SIZE) | |
235 | + { | |
236 | + val append_bytes = isr.read(byteArray, read_bytes, length_bytes - read_bytes) | |
237 | + logcat("READ AGAIN : $append_bytes [$read_bytes]") | |
238 | + if (append_bytes < 0) | |
239 | + { | |
240 | + break | |
241 | + } | |
242 | + read_bytes = read_bytes + append_bytes | |
243 | + } | |
244 | + logcat("READ BYTES : " + read_bytes + " (" + length_bytes + " bytes, " + waitMs + "ms)") | |
245 | + } | |
246 | + else | |
247 | + { | |
248 | + // ウェイトを短めに入れてマーカーを拾うまで待つ | |
249 | + Thread.sleep(waitMs / 4.toLong()) | |
250 | + logcat(" --- wait LiveView ---") | |
251 | + continue | |
252 | + } | |
253 | + } | |
254 | + | |
255 | + // 先頭データをダンプする | |
256 | + dump_bytes("[LV]", byteArray) | |
257 | + if (findJpeg) | |
258 | + { | |
259 | + liveViewListener.onUpdateLiveView(Arrays.copyOfRange(byteArray, DATA_HEADER_OFFSET, read_bytes - DATA_HEADER_OFFSET), null) | |
260 | + errorCount = 0 | |
261 | + } | |
262 | + Thread.sleep(waitMs.toLong()) | |
263 | + } | |
264 | + catch (e: Exception) | |
265 | + { | |
266 | + e.printStackTrace() | |
267 | + errorCount++ | |
268 | + } | |
269 | + | |
270 | + if (errorCount > ERROR_LIMIT) | |
271 | + { | |
272 | + // エラーが連続でたくさん出たらループをストップ(ライブビューを停止)させる | |
273 | + isStart = false | |
274 | + } | |
275 | + } | |
276 | + | |
277 | + try | |
278 | + { | |
279 | + isr.close() | |
280 | + socket.close() | |
281 | + } | |
282 | + catch (e: Exception) | |
283 | + { | |
284 | + e.printStackTrace() | |
285 | + } | |
286 | + } | |
287 | + | |
288 | + | |
289 | + companion object | |
290 | + { | |
291 | + private const val DATA_HEADER_OFFSET = 18 | |
292 | + private const val BUFFER_SIZE = 2048 * 1280 | |
293 | + private const val ERROR_LIMIT = 30 | |
294 | + } | |
295 | +} |
@@ -19,7 +19,7 @@ import static net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor.FUJIX | ||
19 | 19 | import static net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor.FUJIX_LIVEVIEW_WAIT_DEFAULT_VALUE; |
20 | 20 | |
21 | 21 | |
22 | -public class FujiXLiveViewControl implements ILiveViewControl, IFujiXCommunication | |
22 | +public class FujiXLiveViewControlAlternate implements ILiveViewControl, IFujiXCommunication | |
23 | 23 | { |
24 | 24 | private final String TAG = toString(); |
25 | 25 | private final String ipAddress; |
@@ -30,9 +30,9 @@ public class FujiXLiveViewControl implements ILiveViewControl, IFujiXCommunicati | ||
30 | 30 | private static final int BUFFER_SIZE = 2048 * 1280; |
31 | 31 | private static final int ERROR_LIMIT = 30; |
32 | 32 | private boolean isStart = false; |
33 | - private boolean logcat = false; | |
33 | + private boolean logcat = true; | |
34 | 34 | |
35 | - public FujiXLiveViewControl(@NonNull Activity activity, String ip, int portNumber) | |
35 | + public FujiXLiveViewControlAlternate(@NonNull Activity activity, String ip, int portNumber) | |
36 | 36 | { |
37 | 37 | this.ipAddress = ip; |
38 | 38 | this.portNumber = portNumber; |
@@ -43,10 +43,13 @@ public class FujiXLiveViewControl implements ILiveViewControl, IFujiXCommunicati | ||
43 | 43 | SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); |
44 | 44 | String waitMsStr = preferences.getString(FUJIX_LIVEVIEW_WAIT, FUJIX_LIVEVIEW_WAIT_DEFAULT_VALUE); |
45 | 45 | logcat("waitMS : " + waitMsStr); |
46 | - int wait = Integer.parseInt(waitMsStr); | |
47 | - if ((wait >= 20)&&(wait <= 800)) | |
46 | + if (waitMsStr != null) | |
48 | 47 | { |
49 | - waitMs = wait; | |
48 | + int wait = Integer.parseInt(waitMsStr); | |
49 | + if ((wait >= 20) && (wait <= 800)) | |
50 | + { | |
51 | + waitMs = wait; | |
52 | + } | |
50 | 53 | } |
51 | 54 | } |
52 | 55 | catch (Exception e) |
@@ -63,6 +66,7 @@ public class FujiXLiveViewControl implements ILiveViewControl, IFujiXCommunicati | ||
63 | 66 | if (isStart) |
64 | 67 | { |
65 | 68 | // すでに受信スレッド動作中なので抜ける |
69 | + Log.v(TAG, " LiveView IS ALREADY STARTED"); | |
66 | 70 | return; |
67 | 71 | } |
68 | 72 | isStart = true; |
@@ -125,6 +129,10 @@ public class FujiXLiveViewControl implements ILiveViewControl, IFujiXCommunicati | ||
125 | 129 | boolean findJpeg = false; |
126 | 130 | int length_bytes; |
127 | 131 | int read_bytes = isr.read(byteArray, 0, BUFFER_SIZE); |
132 | + | |
133 | + // 先頭データ(48バイト分)をダンプ | |
134 | + dump_bytes("[lv]", byteArray, 48); | |
135 | + | |
128 | 136 | if (read_bytes > DATA_HEADER_OFFSET) |
129 | 137 | { |
130 | 138 | // メッセージボディの先頭にあるメッセージ長分は読み込む |
@@ -148,6 +156,7 @@ public class FujiXLiveViewControl implements ILiveViewControl, IFujiXCommunicati | ||
148 | 156 | { |
149 | 157 | // ウェイトを短めに入れてマーカーを拾うまで待つ |
150 | 158 | Thread.sleep(waitMs/4); |
159 | + logcat(" --- wait LiveView ---"); | |
151 | 160 | continue; |
152 | 161 | } |
153 | 162 | } |