diff --git a/.gitignore b/.gitignore index 10cfdbf..e3bdbed 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ .externalNativeBuild .cxx local.properties +/app/build diff --git a/.gitignore b/.gitignore index 10cfdbf..e3bdbed 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ .externalNativeBuild .cxx local.properties +/app/build diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt new file mode 100644 index 0000000..0afcb27 --- /dev/null +++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt @@ -0,0 +1,14 @@ +package com.casic.endoscope.extensions + +import android.content.Context +import android.os.Environment +import java.io.File + +//扩展函数 +fun Context.createVideoFileDir(): File { + val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "") + if (!videoDir.exists()) { + videoDir.mkdir() + } + return videoDir +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 10cfdbf..e3bdbed 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ .externalNativeBuild .cxx local.properties +/app/build diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt new file mode 100644 index 0000000..0afcb27 --- /dev/null +++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt @@ -0,0 +1,14 @@ +package com.casic.endoscope.extensions + +import android.content.Context +import android.os.Environment +import java.io.File + +//扩展函数 +fun Context.createVideoFileDir(): File { + val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "") + if (!videoDir.exists()) { + videoDir.mkdir() + } + return videoDir +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/endoscope/extensions/Long.kt b/app/src/main/java/com/casic/endoscope/extensions/Long.kt new file mode 100644 index 0000000..bd21ecf --- /dev/null +++ b/app/src/main/java/com/casic/endoscope/extensions/Long.kt @@ -0,0 +1,10 @@ +package com.casic.endoscope.extensions + +import com.pengxh.kt.lite.extensions.appendZero + +fun Long.toTime(): String { + val h = (this / 3600).toInt().appendZero() + val m = (this % 3600 / 60).toInt().appendZero() + val s = (this % 3600 % 60).toInt().appendZero() + return "$h:$m:$s" +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 10cfdbf..e3bdbed 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ .externalNativeBuild .cxx local.properties +/app/build diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt new file mode 100644 index 0000000..0afcb27 --- /dev/null +++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt @@ -0,0 +1,14 @@ +package com.casic.endoscope.extensions + +import android.content.Context +import android.os.Environment +import java.io.File + +//扩展函数 +fun Context.createVideoFileDir(): File { + val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "") + if (!videoDir.exists()) { + videoDir.mkdir() + } + return videoDir +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/endoscope/extensions/Long.kt b/app/src/main/java/com/casic/endoscope/extensions/Long.kt new file mode 100644 index 0000000..bd21ecf --- /dev/null +++ b/app/src/main/java/com/casic/endoscope/extensions/Long.kt @@ -0,0 +1,10 @@ +package com.casic.endoscope.extensions + +import com.pengxh.kt.lite.extensions.appendZero + +fun Long.toTime(): String { + val h = (this / 3600).toInt().appendZero() + val m = (this % 3600 / 60).toInt().appendZero() + val s = (this % 3600 % 60).toInt().appendZero() + return "$h:$m:$s" +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt index 1404f1c..b7e94e9 100644 --- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt +++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt @@ -7,29 +7,43 @@ import android.view.KeyEvent import android.view.MotionEvent import android.view.SurfaceHolder +import androidx.lifecycle.lifecycleScope import com.casic.endoscope.R import com.casic.endoscope.databinding.ActivityMainBinding +import com.casic.endoscope.extensions.createVideoFileDir import com.casic.endoscope.extensions.getChannel import com.casic.endoscope.extensions.initImmersionBar +import com.casic.endoscope.extensions.toTime import com.casic.endoscope.utils.ProjectConstant import com.casic.endoscope.utils.hk.MessageCodeHub import com.casic.endoscope.utils.hk.SDKGuider import com.hikvision.netsdk.HCNetSDK +import com.hikvision.netsdk.NET_DVR_JPEGPARA import com.hikvision.netsdk.NET_DVR_PREVIEWINFO import com.hikvision.netsdk.PTZCommand import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.createImageFileDir import com.pengxh.kt.lite.extensions.show +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale +import java.util.Timer +import java.util.TimerTask @SuppressLint("all") class MainActivity : KotlinBaseActivity(), SurfaceHolder.Callback { private val kTag = "MainActivity" private val hkSDK by lazy { HCNetSDK.getInstance() } + private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) } private val selectedSpeed = 7 private var clickTime = 0L private var previewHandle = -1 private var selectChannel = -1 - private var returnUserID = -1 + private var returnUserId = -1 private var aChannelNum = 0 private var startAChannel = 0 private var dChannelNum = 0 @@ -41,6 +55,9 @@ //焦距按钮是否已松开 private var isScaleButtonUp = true + private var timer: Timer? = null + private var timerTask: TimerTask? = null + private var seconds = 0L override fun initViewBinding(): ActivityMainBinding { return ActivityMainBinding.inflate(layoutInflater) @@ -51,6 +68,42 @@ } override fun initEvent() { + binding.imageButton.setOnClickListener { + if (isPreviewSuccess) { + lifecycleScope.launch(Dispatchers.IO) { + val strJpeg = NET_DVR_JPEGPARA() + strJpeg.wPicQuality = 1 + strJpeg.wPicSize = 2 + + val imagePath = "/${createImageFileDir()}/${timeFormat.format(Date())}.png" + hkSDK.NET_DVR_CaptureJPEGPicture( + returnUserId, selectChannel, strJpeg, imagePath + ) + + if (MessageCodeHub.getErrorCode() == 0) { + withContext(Dispatchers.Main) { + "画面抓取成功".show(this@MainActivity) + } + } + } + } + } + + binding.videoButton.setOnClickListener { + if (isPreviewSuccess) { + val videoPath = "/${createVideoFileDir()}/${timeFormat.format(Date())}.mp4" + hkSDK.NET_DVR_SaveRealData(returnUserId, videoPath) + binding.videoButton.text = "长按停止" + } + } + + binding.videoButton.setOnLongClickListener { + //停止视频抓取 + hkSDK.NET_DVR_StopSaveRealData(returnUserId) + binding.videoButton.text = "录像" + true + } + binding.toggleButton.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { val deviceItem = SDKGuider.sdkGuider.devManageGuider.DeviceItem() @@ -71,7 +124,7 @@ //配置设备通道 try { val deviceInfo = SDKGuider.sdkGuider.devManageGuider.devList[0] - returnUserID = deviceInfo.szUserId + returnUserId = deviceInfo.szUserId aChannelNum = deviceInfo.deviceInfoV40_jna.struDeviceV30.byChanNum.toInt() startAChannel = @@ -113,7 +166,7 @@ strutPlayInfo.bBlocked = 1 strutPlayInfo.hHwnd = binding.surfaceView.holder previewHandle = SDKGuider.sdkGuider.devPreviewGuider.RealPlay_V40_jni( - returnUserID, strutPlayInfo, null + returnUserId, strutPlayInfo, null ) if (previewHandle < 0) { Log.d(kTag, "initEvent: Err:${MessageCodeHub.getErrorCode()}") @@ -121,6 +174,17 @@ } isPreviewSuccess = true "预览开启成功".show(this) + //开始计时 + timer = Timer() + timerTask = object : TimerTask() { + override fun run() { + seconds++ + lifecycleScope.launch(Dispatchers.Main) { + binding.runningTimeView.text = seconds.toTime() + } + } + } + timer?.schedule(timerTask, 0, 1000) } catch (e: IndexOutOfBoundsException) { e.printStackTrace() "设备未正常连接,无法开启预览".show(this) @@ -130,9 +194,12 @@ if (!SDKGuider.sdkGuider.devPreviewGuider.RealPlay_Stop_jni(previewHandle)) { return@setOnCheckedChangeListener } - "预览关闭成功".show(this) previewHandle = -1 isPreviewSuccess = false + "预览关闭成功".show(this) + //停止计时 + timerTask?.cancel() + timer?.cancel() } } @@ -154,6 +221,7 @@ } true } + binding.topButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { @@ -172,6 +240,7 @@ } true } + binding.rightButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { @@ -190,6 +259,7 @@ } true } + binding.bottomButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> {