直播流开始和停止
This commit is contained in:
@@ -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,
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.ckkj.defense_device.bean
|
||||
|
||||
data class VideoStreamRequest(
|
||||
val deviceNo: String
|
||||
)
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Any>
|
||||
|
||||
/**
|
||||
* 开始推流
|
||||
*/
|
||||
@POST("/app/stream/start")
|
||||
suspend fun videoStart(
|
||||
@Body request: VideoStreamRequest
|
||||
): GetCodeBean<VideoStreamInfo>
|
||||
|
||||
/**
|
||||
* 停止推流
|
||||
*/
|
||||
@POST("/app/stream/stop/{deviceNo}")
|
||||
suspend fun videoStop(
|
||||
@retrofit2.http.Path("deviceNo") deviceNo: String
|
||||
): GetCodeBean<Any>
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user