Android WebRTC+SRS/ZLM視頻通話(5):Android使用WebRTC從SRS/ZLMediaKit拉流
來自奔三人員的焦慮日志
接著上一章內(nèi)容,繼續(xù)來記錄Android是如何使用WebRTC從SRS/ZLMediaKit拉流播放。WebRTC是一種實(shí)現(xiàn)實(shí)時(shí)音視頻通信的技術(shù),而SRS(SRS Streaming Cluster)和ZLMediaKit則是兩種常用的流媒體服務(wù)。 Android 平臺(tái)上,可以使用 WebRTC 從 SRS/ZLMediaKit 中拉取流并進(jìn)行播放。
WebRTC推拉流的區(qū)別
推流:WebRTC 中的推流通常指將本地音視頻流發(fā)送到遠(yuǎn)端。推流涉及到本地設(shè)備上的音視頻采集、編碼、傳輸?shù)冗^程。
拉流:WebRTC 中的拉流通常指從遠(yuǎn)端獲取音視頻流并進(jìn)行播放。拉流涉及到 RTCPeerConnection 對(duì)象的建立和音視頻解碼等過程。拉流可以用于實(shí)現(xiàn)實(shí)時(shí)音視頻播放、音視頻錄制等場(chǎng)景。
總的來說,WebRTC 的推拉流都是通過 PeerConnection 對(duì)象進(jìn)行實(shí)現(xiàn),具體的實(shí)現(xiàn)細(xì)節(jié)會(huì)有一些不同。其中推流涉及到本地設(shè)備的音視頻采集和編碼等過程,而拉流則是接收遠(yuǎn)端的音視頻流進(jìn)行解碼和播放。
注意:這里暫不考慮NAT可穿透服務(wù)器,詳情可了解STUN/TURN 服務(wù)器的搭建和使用
別看一堆文字就頭大,實(shí)際上也就是兩行代碼的事,注意初始化時(shí)PeerConnection!!.addTransceiver方法的參數(shù)設(shè)置即可。去掉視頻、音頻采集等代碼,剩下的就是交換sdp的API地址變一下就好。
//拉流
if (!isPublish) {
peerConnection!!.addTransceiver(
MediaStreamTrack.MediaType.MEDIA_TYPE_AUDIO,
RtpTransceiver.RtpTransceiverInit(RtpTransceiver.RtpTransceiverDirection.RECV_ONLY)
)
peerConnection!!.addTransceiver(
MediaStreamTrack.MediaType.MEDIA_TYPE_VIDEO,
RtpTransceiver.RtpTransceiverInit(RtpTransceiver.RtpTransceiverDirection.RECV_ONLY)
)
}
//推流
else {
peerConnection!!.addTransceiver(
MediaStreamTrack.MediaType.MEDIA_TYPE_AUDIO,
RtpTransceiver.RtpTransceiverInit(RtpTransceiver.RtpTransceiverDirection.SEND_ONLY)
)
peerConnection!!.addTransceiver(
MediaStreamTrack.MediaType.MEDIA_TYPE_VIDEO,
RtpTransceiver.RtpTransceiverInit(RtpTransceiver.RtpTransceiverDirection.SEND_ONLY)
)
}
這里我已經(jīng)封裝成工具類,詳情看WebRTCUtil
頁面代碼
跟推流類似,我們新增一個(gè)預(yù)覽頁面、播放地址文本和一個(gè)開始拉流按鈕,具體看下面代碼:
//拉流地址
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier.weight(1f)
) {
Text(text = playUrl.value)
}
Box(
modifier = Modifier
.clickable {
doPlay()//開始播放
}
.width(80.dp)
.background(
Color.White,
RoundedCornerShape(5.dp)
)
.border(
1.dp,
Color(0xFF000000),
shape = RoundedCornerShape(5.dp)
)
.padding(5.dp),
contentAlignment = Alignment.Center
) {
Text(text = "拉流")
}
}
//拉流部分
Box(
modifier = Modifier
.fillMaxWidth()
.height(300.dp)
) {
surfaceViewRenderer2 = mSurfaceViewRenderer2(mEglBase, webRtcUtil2!!)
AndroidView({ surfaceViewRenderer2!! }) { videoView ->
CoroutineScope(Dispatchers.Main).launch {
//根據(jù)視頻大小縮放surfaceViewRenderer控件
var screenSize = "480-640"
var screenSizeD = 720 / 1280.0
val screenSizeS: Array<String> =
screenSize.split("-").toTypedArray()
screenSizeD =
screenSizeS[0].toInt() / (screenSizeS[1].toInt() * 1.0)
var finalScreenSizeD = screenSizeD
var vto = videoView.viewTreeObserver
vto.addOnPreDrawListener {
var width: Int = videoView.measuredWidth
var height: Int = (finalScreenSizeD * width).toInt()
//獲取到寬度和高度后,可用于計(jì)算
var layoutParams = videoView.layoutParams
layoutParams.height = height
videoView.layoutParams = layoutParams
true
}
}
}
}
@Composable
fun mSurfaceViewRenderer2(mEglBase: EglBase, webRtcUtil2: WebRTCUtil): SurfaceViewRenderer {
val context = LocalContext.current
val surfaceViewRenderer = remember {
SurfaceViewRenderer(context).apply {
id = R.id.surface_view_2
}
}
//Makes MapView follow the lifecycle of this composable
val lifecycleObserver = rememberMapLifecycleObserver(surfaceViewRenderer, mEglBase, webRtcUtil2)
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle) {
lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycle.removeObserver(lifecycleObserver)
}
}
return surfaceViewRenderer
}
private var webRtcUtil2: WebRTCUtil? = null
private var playUrl =
mutableStateOf("https://192.168.1.172/index/api/webrtc?app=live&stream=test&type=play")
private var surfaceViewRenderer2: SurfaceViewRenderer? = null
/**
* 開始播放
*/
private fun doPlay() {
if (webRtcUtil2 != null) {
webRtcUtil2!!.destroy()
}
webRtcUtil2 = WebRTCUtil(this@MainActivity)
webRtcUtil2!!.create(
mEglBase,
surfaceViewRenderer2,
isPublish = false,
isShowCamera = true,
playUrl = playUrl.value,
callBack = object : WebRTCUtil.WebRtcCallBack {
override fun onSuccess() {}
override fun onFail() {}
})
}
主要新增這幾個(gè),詳情可到Gitee拉取完整Demo
運(yùn)行效果
文章來源:http://www.zghlxwxcb.cn/news/detail-623085.html
第五章到這里就結(jié)束了,下節(jié)繼續(xù)記錄Android如何往SRS推拉流,占用您的垃圾時(shí)間了,實(shí)在對(duì)不住文章來源地址http://www.zghlxwxcb.cn/news/detail-623085.html
THE END
感謝查閱
玉念聿輝:編輯
到了這里,關(guān)于Android WebRTC+SRS/ZLM視頻通話(5):Android使用WebRTC從SRS/ZLMediaKit拉流的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!