import android.util.Log
import android.view.View
+import android.widget.ImageButton
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
import jp.osdn.gokigen.thetaview.IShowInformation
import jp.osdn.gokigen.thetaview.R
import jp.osdn.gokigen.thetaview.camera.ICameraStatusReceiver
import jp.osdn.gokigen.thetaview.camera.theta.connection.ThetaCameraConnection
import jp.osdn.gokigen.thetaview.camera.theta.liveview.ThetaLiveViewControl
+import jp.osdn.gokigen.thetaview.camera.theta.operation.ThetaMovieRecordingControl
+import jp.osdn.gokigen.thetaview.camera.theta.operation.ThetaOptionUpdateControl
import jp.osdn.gokigen.thetaview.camera.theta.operation.ThetaSingleShotControl
+import jp.osdn.gokigen.thetaview.camera.theta.status.ICaptureModeReceiver
import jp.osdn.gokigen.thetaview.camera.theta.status.ThetaCameraStatusWatcher
import jp.osdn.gokigen.thetaview.camera.theta.status.ThetaSessionHolder
import jp.osdn.gokigen.thetaview.liveview.ILiveView
import jp.osdn.gokigen.thetaview.scene.ICameraConnectionStatus
import jp.osdn.gokigen.thetaview.scene.IIndicator
-class ThetaControl(private val context: AppCompatActivity, private val showInformation : IShowInformation, statusReceiver : ICameraStatusReceiver) : ILiveViewController, ICameraControl, View.OnClickListener
+class ThetaControl(private val context: AppCompatActivity, private val showInformation : IShowInformation, statusReceiver : ICameraStatusReceiver) : ILiveViewController, ICameraControl, View.OnClickListener, ICaptureModeReceiver
{
private val sessionIdHolder = ThetaSessionHolder()
private val cameraConnection = ThetaCameraConnection(context, statusReceiver, sessionIdHolder, sessionIdHolder, this)
private val liveViewControl = ThetaLiveViewControl(liveViewListener)
private var indicator : IIndicator? = null
- private val statusWatcher = ThetaCameraStatusWatcher(sessionIdHolder)
+ private val statusWatcher = ThetaCameraStatusWatcher(sessionIdHolder, this)
private var isStatusWatch = false
fun setIndicator(indicator : IIndicator)
this.indicator = indicator
}
+ fun changeCaptureMode()
+ {
+ val options = if (statusWatcher.captureMode.contains("image"))
+ {
+ // image -> video
+ "\"captureMode\" : \"video\""
+ }
+ else
+ {
+ // video -> image
+ "\"captureMode\" : \"image\""
+ }
+ ThetaOptionUpdateControl(sessionIdHolder).setOptions(options, sessionIdHolder.isApiLevelV21())
+ }
+
+ override fun changedCaptureMode(captureMode : String)
+ {
+ try
+ {
+ val isImage = captureMode.contains("image")
+ context.runOnUiThread {
+ try
+ {
+ val view : ImageButton = context.findViewById(R.id.button_camera)
+ val iconId = if (isImage) { R.drawable.ic_baseline_videocam_24 } else { R.drawable.ic_baseline_camera_alt_24 }
+ view.setImageDrawable(ContextCompat.getDrawable(context, iconId))
+ view.invalidate()
+ }
+ catch (e : Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
override fun initialize()
{
// TODO("Not yet implemented")
}
when (v.id)
{
- R.id.button_camera -> { ThetaSingleShotControl(sessionIdHolder, showInformation, liveViewControl).singleShot(sessionIdHolder.isApiLevelV21()) }
+ R.id.button_camera -> {
+ if (statusWatcher.captureMode.contains("image")) {
+ // image
+ ThetaSingleShotControl(sessionIdHolder, showInformation, liveViewControl).singleShot(sessionIdHolder.isApiLevelV21())
+ }
+ else
+ {
+ // video
+ ThetaMovieRecordingControl(sessionIdHolder, showInformation, liveViewControl).movieControl(sessionIdHolder.isApiLevelV21())
+ }
+ }
else -> { }
}
}
--- /dev/null
+package jp.osdn.gokigen.thetaview.camera.theta.operation
+
+import android.util.Log
+import jp.osdn.gokigen.thetaview.IShowInformation
+import jp.osdn.gokigen.thetaview.camera.theta.status.IThetaSessionIdProvider
+import jp.osdn.gokigen.thetaview.liveview.ILiveViewController
+import jp.osdn.gokigen.thetaview.utils.communication.SimpleHttpClient
+
+class ThetaMovieRecordingControl(private val sessionIdProvider: IThetaSessionIdProvider, private val statusDrawer: IShowInformation, private val liveViewControl : ILiveViewController)
+{
+ private val httpClient = SimpleHttpClient()
+ private var isCapturing = false
+
+ fun movieControl(useOSCv2 : Boolean)
+ {
+ try
+ {
+ if (!(isCapturing))
+ {
+ startCapture(useOSCv2)
+ }
+ else
+ {
+ stopCapture(useOSCv2)
+ }
+ statusDrawer.invalidate()
+ isCapturing = !isCapturing
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ private fun startCapture(useOSCv2 : Boolean)
+ {
+ Log.v(TAG, "startCapture() (API v2.1 : $useOSCv2)")
+ try
+ {
+ val thread = Thread {
+ try
+ {
+ val shootUrl = "http://192.168.1.1/osc/commands/execute"
+ val postData = if (useOSCv2) "{\"name\":\"camera.startCapture\",\"parameters\":{\"timeout\":0}}" else "{\"name\":\"camera._startCapture\",\"parameters\":{\"sessionId\": \"" + sessionIdProvider.sessionId + "\"}}"
+
+ Log.v(TAG, " start Capture : $postData")
+ val result: String? = httpClient.httpPostWithHeader(shootUrl, postData, null, "application/json;charset=utf-8", timeoutMs)
+ if ((result != null)&&(result.isNotEmpty()))
+ {
+ Log.v(TAG, " startCapture() : $result")
+ }
+ else
+ {
+ Log.v(TAG, "startCapture() reply is null. $postData")
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ thread.start()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ private fun stopCapture(useOSCv2 : Boolean)
+ {
+ Log.v(TAG, "stopCapture() (API v2.1 : $useOSCv2)")
+ try
+ {
+ val thread = Thread {
+ try
+ {
+ val shootUrl = "http://192.168.1.1/osc/commands/execute"
+ val postData = if (useOSCv2) "{\"name\":\"camera.stopCapture\",\"parameters\":{\"timeout\":0}}" else "{\"name\":\"camera._stopCapture\",\"parameters\":{\"sessionId\": \"" + sessionIdProvider.sessionId + "\"}}"
+
+ Log.v(TAG, " stop Capture : $postData")
+
+ val result: String? = httpClient.httpPostWithHeader(shootUrl, postData, null, "application/json;charset=utf-8", timeoutMs)
+ if ((result != null)&&(result.isNotEmpty()))
+ {
+ Log.v(TAG, " stopCapture() : $result")
+ if (!useOSCv2)
+ {
+ // THETA V / THETA Z1 は、videoモードでライブビューができるので...
+ liveViewControl.stopLiveView()
+ waitMs() // ちょっと待つ...
+ liveViewControl.startLiveView()
+ }
+ }
+ else
+ {
+ Log.v(TAG, "stopCapture() reply is null. $postData")
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ thread.start()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private fun waitMs(waitMs: Int = 300)
+ {
+ try
+ {
+ Thread.sleep(waitMs.toLong())
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ companion object
+ {
+ private val TAG = ThetaMovieRecordingControl::class.java.simpleName
+ private const val timeoutMs = 6000
+ }
+}
\ No newline at end of file
--- /dev/null
+package jp.osdn.gokigen.thetaview.camera.theta.status
+
+interface ICaptureModeReceiver
+{
+ fun changedCaptureMode(captureMode : String)
+
+}
\ No newline at end of file
import jp.osdn.gokigen.thetaview.utils.communication.SimpleHttpClient
import org.json.JSONObject
-class ThetaCameraStatusWatcher(private val sessionIdProvider: IThetaSessionIdProvider, private val executeUrl : String = "http://192.168.1.1") : ICameraStatusWatcher, IThetaStatusHolder
+class ThetaCameraStatusWatcher(private val sessionIdProvider: IThetaSessionIdProvider, private val captureModeReceiver : ICaptureModeReceiver, private val executeUrl : String = "http://192.168.1.1") : ICameraStatusWatcher, IThetaStatusHolder
{
private val httpClient = SimpleHttpClient()
private var whileFetching = false
{
Log.v(TAG, " CapMode : $currentCaptureMode -> $captureMode")
currentCaptureMode = captureMode
+ captureModeReceiver.changedCaptureMode(captureMode)
setMessage(IIndicator.Area.AREA_2, Color.WHITE, "Capture Mode : $captureMode")
}
}
fun changeToConfiguration()
fun changeToDebugInformation()
fun exitApplication()
+ fun changeCaptureMode()
}
private fun camera()
{
Log.v(TAG, " - - - - - - - - - CAMERA - - - - - - - - -")
- sceneChanger.changeToDebugInformation()
+ sceneChanger.changeCaptureMode()
}
private fun configure()
changeFragment(logCatFragment)
}
+
+
override fun exitApplication()
{
val dialog = ConfirmationDialog.newInstance(activity)
)
}
+ override fun changeCaptureMode()
+ {
+ try
+ {
+ // CaptureModeの変更
+ thetaControl.changeCaptureMode()
+ }
+ catch (e : Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
private fun changeFragment(fragment: Fragment)
{
val transaction : FragmentTransaction = activity.supportFragmentManager.beginTransaction()
--- /dev/null
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z"/>
+</vector>
android:layout_marginRight="2dp"
android:layout_alignTop="@id/button_configure"
android:layout_alignParentBottom="true"
- android:src="@drawable/ic_baseline_change_circle_24"
+ android:src="@drawable/ic_baseline_videocam_24"
/>
<TextView
<PreferenceCategory
app:title="@string/pref_cat_application_settings">
-
+<!--
<SwitchPreferenceCompat
android:key="use_camera_x_preview"
android:title="@string/pref_use_camerax_preview"/>
-
+-->
<SwitchPreferenceCompat
android:key="save_local_location"
android:title="@string/save_local_location"/>