diff --git a/.kotlin/errors/errors-1782888714708.log b/.kotlin/errors/errors-1782888714708.log new file mode 100644 index 0000000..87f3463 --- /dev/null +++ b/.kotlin/errors/errors-1782888714708.log @@ -0,0 +1,48 @@ +kotlin version: 2.2.10 +error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker3368904538941318214.tmp + +error message: Daemon compilation failed: Could not connect to Kotlin compile daemon +java.lang.RuntimeException: Could not connect to Kotlin compile daemon + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111) + at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74) + at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61) + at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61) + at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44) + at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41) + at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209) + at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) + at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) + at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) + at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166) + at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) + at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) + at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58) + at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176) + at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169) + at org.gradle.internal.Factories$1.create(Factories.java:30) + at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269) + at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42) + at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267) + at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) + at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) + at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) + at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) + at java.base/java.lang.Thread.run(Thread.java:1583) + + diff --git a/.kotlin/errors/errors-1782890222939.log b/.kotlin/errors/errors-1782890222939.log new file mode 100644 index 0000000..3f6b5b7 --- /dev/null +++ b/.kotlin/errors/errors-1782890222939.log @@ -0,0 +1,48 @@ +kotlin version: 2.2.10 +error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker2940944726750836786.tmp + +error message: Daemon compilation failed: Could not connect to Kotlin compile daemon +java.lang.RuntimeException: Could not connect to Kotlin compile daemon + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111) + at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74) + at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61) + at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61) + at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44) + at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41) + at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209) + at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) + at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) + at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) + at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166) + at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) + at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) + at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58) + at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176) + at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169) + at org.gradle.internal.Factories$1.create(Factories.java:30) + at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269) + at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42) + at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267) + at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) + at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) + at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) + at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) + at java.base/java.lang.Thread.run(Thread.java:1583) + + diff --git a/app/src/main/java/com/ckkj/defense_device/bean/VideoStartRequest.kt b/app/src/main/java/com/ckkj/defense_device/bean/VideoStartRequest.kt new file mode 100644 index 0000000..d15b325 --- /dev/null +++ b/app/src/main/java/com/ckkj/defense_device/bean/VideoStartRequest.kt @@ -0,0 +1,20 @@ +package com.ckkj.defense_device.bean + +data class VideoStreamInfo( + val deviceNo: String, + val streamId: String, + val app: String, + val online: Boolean, + val pushUrl: String, + val playToken: String, + val expireAt: String, + val playUrls:playUrls, + val expireSeconds: Int, +) +class playUrls( + val flv: String, + val hls: String, + val rtmp: String, + val rtsp: String, + val webrtc: String, +) diff --git a/app/src/main/java/com/ckkj/defense_device/bean/VideoStreamRequest.kt b/app/src/main/java/com/ckkj/defense_device/bean/VideoStreamRequest.kt new file mode 100644 index 0000000..c7d9506 --- /dev/null +++ b/app/src/main/java/com/ckkj/defense_device/bean/VideoStreamRequest.kt @@ -0,0 +1,5 @@ +package com.ckkj.defense_device.bean + +data class VideoStreamRequest( + val deviceNo: String +) \ No newline at end of file diff --git a/app/src/main/java/com/ckkj/defense_device/liveVideo/LiveVideoActivity.kt b/app/src/main/java/com/ckkj/defense_device/liveVideo/LiveVideoActivity.kt index 840021d..926c9fc 100644 --- a/app/src/main/java/com/ckkj/defense_device/liveVideo/LiveVideoActivity.kt +++ b/app/src/main/java/com/ckkj/defense_device/liveVideo/LiveVideoActivity.kt @@ -5,7 +5,6 @@ import android.content.res.Configuration import android.graphics.Color import android.os.Bundle import android.util.Log -import android.view.GestureDetector import android.view.MotionEvent import android.view.View import androidx.recyclerview.widget.LinearLayoutManager @@ -22,10 +21,13 @@ import com.gyf.immersionbar.ImmersionBar import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack import com.shuyu.gsyvideoplayer.utils.OrientationUtils +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import androidx.lifecycle.lifecycleScope import android.os.Handler import android.os.Looper +import com.ckkj.defense_device.bean.VideoStreamInfo +import com.ckkj.defense_device.bean.VideoStreamRequest import com.ckkj.defense_device.view.MyGSYVideoPlayerLive class LiveVideoActivity : BaseActivity() { @@ -47,6 +49,7 @@ class LiveVideoActivity : BaseActivity() { private var orientationUtils: OrientationUtils? = null private val ptzHandler = Handler(Looper.getMainLooper()) private var currentPtzDirection: String? = null + private var streamUrl: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -90,15 +93,41 @@ class LiveVideoActivity : BaseActivity() { } private fun initVideoPlayer() { - val videoUrl ="http://220.203.23.195:9090/live/test001.live.flv" - orientationUtils = OrientationUtils(this, binding.exoPlayContextId) orientationUtils?.isEnable = true + hidePlayerControls() + fetchStreamUrl() + } + + private fun fetchStreamUrl() { + val no = deviceNo ?: return + lifecycleScope.launch { + try { + val response = RetrofitNetwork.getNetworkService().videoStart(VideoStreamRequest(no)) + Log.d("直播流开始", "code=${response.code}, msg=${response.msg}") + if (response.code == 200 && response.data != null) { + //flv(http) 支持(IjkPlayer最好) + //hls(.m3u8) 支持(ExoPlayer/Ijk都支持) + //rtmp IjkPlayer支持,Exo默认不支持 + //rtsp IjkPlayer支持 + //webrtcGSYVideoPlayer 不支持 + streamUrl = response.data.playUrls.flv + Log.d("直播流开始", "获取地址:$streamUrl") + setupVideoPlayer(streamUrl!!) + } else { + Log.e("直播流开始", response.msg) + } + } catch (e: Exception) { + Log.e("直播流开始", "异常", e) + } + } + } + + private fun setupVideoPlayer(videoUrl: String) { GSYVideoOptionBuilder() .setUrl(videoUrl) .setCacheWithPlay(false) - .setCacheWithPlay(false) .setRotateViewAuto(true) .setLockLand(false) .setShowFullAnimation(true) @@ -113,13 +142,11 @@ class LiveVideoActivity : BaseActivity() { override fun onQuitFullscreen(url: String?, vararg objects: Any?) { super.onQuitFullscreen(url, *objects) - orientationUtils?.backToProtVideo() } }) .build(binding.exoPlayContextId) - hidePlayerControls() binding.exoPlayContextId.startPlayLogic() binding.exoPlayContextId.fullscreenButton.setOnClickListener { binding.exoPlayContextId.onPtzControlListener = @@ -140,7 +167,6 @@ class LiveVideoActivity : BaseActivity() { orientationUtils?.resolveByClick() binding.exoPlayContextId.startWindowFullscreen(this, true, true) } - } private fun hidePlayerControls() { binding.exoPlayContextId.backButton.visibility = View.GONE @@ -420,5 +446,18 @@ class LiveVideoActivity : BaseActivity() { ptzHandler.removeCallbacksAndMessages(null) orientationUtils?.releaseListener() binding.exoPlayContextId.release() + stopStream() + } + + private fun stopStream() { + val no = deviceNo ?: return + GlobalScope.launch { + try { + val response = RetrofitNetwork.getNetworkService().videoStop(no) + Log.d("直播流停止", "videoStop response: code=${response.code}, msg=${response.msg}") + } catch (e: Exception) { + Log.e("直播流停止", "停止推流异常", e) + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/ckkj/defense_device/utils/ApiService.kt b/app/src/main/java/com/ckkj/defense_device/utils/ApiService.kt index 92439e5..2c06c76 100644 --- a/app/src/main/java/com/ckkj/defense_device/utils/ApiService.kt +++ b/app/src/main/java/com/ckkj/defense_device/utils/ApiService.kt @@ -28,6 +28,8 @@ import com.ckkj.defense_device.bean.UpdateUserInfo import com.ckkj.defense_device.bean.UploadResponse import com.ckkj.defense_device.bean.UserInfoBean import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest +import com.ckkj.defense_device.bean.VideoStreamInfo +import com.ckkj.defense_device.bean.VideoStreamRequest import okhttp3.MultipartBody import retrofit2.http.Body import retrofit2.http.DELETE @@ -328,5 +330,22 @@ interface ApiService { @Query("duration") duration: String, ): GetCodeBean + /** + * 开始推流 + */ + @POST("/app/stream/start") + suspend fun videoStart( + @Body request: VideoStreamRequest + ): GetCodeBean + + /** + * 停止推流 + */ + @POST("/app/stream/stop/{deviceNo}") + suspend fun videoStop( + @retrofit2.http.Path("deviceNo") deviceNo: String + ): GetCodeBean + + } diff --git a/app/src/main/java/com/ckkj/defense_device/utils/RetrofitNetwork.kt b/app/src/main/java/com/ckkj/defense_device/utils/RetrofitNetwork.kt index 8040a42..b1c0081 100644 --- a/app/src/main/java/com/ckkj/defense_device/utils/RetrofitNetwork.kt +++ b/app/src/main/java/com/ckkj/defense_device/utils/RetrofitNetwork.kt @@ -12,8 +12,8 @@ import java.util.concurrent.TimeUnit object RetrofitNetwork { private const val DEFAULT_TIMEOUT = 30L - const val BASE_URL = "https://stem-boozy-margarine.ngrok-free.dev" - //const val BASE_URL = "http://service.reinkun.com:8001" + //const val BASE_URL = "https://stem-boozy-margarine.ngrok-free.dev" + const val BASE_URL = "http://service.reinkun.com:8001" private var retrofit: Retrofit? = null private val gson = Gson()