This commit is contained in:
wangjiyu 2025-04-18 20:57:28 +08:00
parent f6d877403f
commit f3021f7588
2 changed files with 667 additions and 331 deletions

View File

@ -1,331 +1,336 @@
package com.example.mrtcdemo package com.example.mrtcdemo
import android.Manifest import android.Manifest
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.res.AssetManager import android.content.res.AssetManager
import android.graphics.Bitmap import android.graphics.Bitmap
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import cn.migu.tsg.MRTCEngine import cn.migu.tsg.MRTCEngine
import cn.migu.tsg.MRTCAdapter import cn.migu.tsg.MRTCAdapter
import cn.migu.tsg.MRTCVideoFrame import cn.migu.tsg.MRTCVideoFrame
import cn.migu.tsg.OnMRTCSDKListener import cn.migu.tsg.OnMRTCSDKListener
import cn.migu.tsg.RoomListener import cn.migu.tsg.RoomListener
import com.example.mrtcdemo.ui.theme.MRTCDemoTheme import com.example.mrtcdemo.ui.theme.MRTCDemoTheme
import kotlin.concurrent.thread
class MainActivity : ComponentActivity() {
// 权限请求回调 class MainActivity : ComponentActivity() {
private val permissionLauncher = registerForActivityResult( // 权限请求回调
ActivityResultContracts.RequestMultiplePermissions() private val permissionLauncher = registerForActivityResult(
) { permissions -> ActivityResultContracts.RequestMultiplePermissions()
if (permissions.all { it.value }) { ) { permissions ->
// 所有权限已授予开始加载SDK if (permissions.all { it.value }) {
} else { // 所有权限已授予开始加载SDK
// 处理权限被拒绝的情况 } else {
showToast("权限被拒绝,功能将受限") // 处理权限被拒绝的情况
} showToast("权限被拒绝,功能将受限")
} }
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge() super.onCreate(savedInstanceState)
enableEdgeToEdge()
// 请求必要权限
requestPermissions() // 请求必要权限
requestPermissions()
setContent {
MRTCDemoTheme { setContent {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> MRTCDemoTheme {
Greeting( Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
name = "Android", Greeting(
modifier = Modifier.padding(innerPadding) name = "Android",
) modifier = Modifier.padding(innerPadding)
} )
} }
} }
} }
}
private fun requestPermissions() {
permissionLauncher.launch( private fun requestPermissions() {
arrayOf( permissionLauncher.launch(
Manifest.permission.READ_EXTERNAL_STORAGE, arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO Manifest.permission.INTERNET,
) Manifest.permission.RECORD_AUDIO
) )
} )
}
var applicationId_ = "1357389261426393088"
var mAppSecrectKey_ = "gytr3qrrznsgac2lbdchfg0l4ltqx4x3nf4my0yt1dbx7riz1gnnsnhblrlc2j4o1lx4vdu495lifv8s7jyrmfxtq9lif9rusxnur5smdn5cjopstxp5dim7p52xrezp" var applicationId_ = "1357389261426393088"
var domain_ = "rtc.migu.cn" var mAppSecrectKey_ = "gytr3qrrznsgac2lbdchfg0l4ltqx4x3nf4my0yt1dbx7riz1gnnsnhblrlc2j4o1lx4vdu495lifv8s7jyrmfxtq9lif9rusxnur5smdn5cjopstxp5dim7p52xrezp"
var mPort_ = 34443 var domain_ = "rtc.migu.cn"
var srcUserId_ = "srcUser12" var mPort_ = 34443
var destUserId_ = "destUser12" var srcUserId_ = "srcUser12"
var destUserId_ = "destUser12"
var srcDisplayName_ = "srcDisplayName12"
var destDisplayName_ = "destDisplayName12" var srcDisplayName_ = "srcDisplayName12"
var srcRoomId_ = "srcRoom12" var destDisplayName_ = "destDisplayName12"
var destRoomId_ = srcRoomId_ var srcRoomId_ = "srcRoom12"
var srcChannelIndex_ = 46 var destRoomId_ = srcRoomId_
var destChannelIndex_ = 47 var srcChannelIndex_ = 46
var sampleRate_ = 16000 var destChannelIndex_ = 47
var channelNum_ = 1 var sampleRate_ = 16000
var isOnRoom_ = false var channelNum_ = 1
var isOnConsumer_ = false var isOnRoom_ = false
var isOnConsumer_ = false
private val audioListener_ = object : MRTCAdapter.MRTCAudioProcessListener {
override fun onReceiveRawAudioFrame(streamId: String, userId: String, frame: MRTCAdapter.MRTCAudioFrame) { private val audioListener_ = object : MRTCAdapter.MRTCAudioProcessListener {
// 在这里处理原始音频帧 override fun onReceiveRawAudioFrame(streamId: String, userId: String, frame: MRTCAdapter.MRTCAudioFrame) {
println("MRTCDEBUG ==================================") // 在这里处理原始音频帧
println("MRTCDEBUG streamId=$streamId, userId=$userId") println("MRTCDEBUG ==================================")
println("MRTCDEBUG frame, channel=${frame.channel}, length=${frame.length}, sampleRate=${frame.sampleRate}") println("MRTCDEBUG streamId=$streamId, userId=$userId")
println(frame.audioBuffer) println("MRTCDEBUG frame, channel=${frame.channel}, length=${frame.length}, sampleRate=${frame.sampleRate}")
} println(frame.audioBuffer.toString())
} }
private val sdkListener_ = object : OnMRTCSDKListener { }
override fun onRoom(type: Int, roomInfo: MRTCAdapter.MRTCRoomInfo) { private val sdkListener_ = object : OnMRTCSDKListener {
println("MRTCDEBUG 房间状态变化: type=$type, roomId=${roomInfo.roomId}") override fun onRoom(type: Int, roomInfo: MRTCAdapter.MRTCRoomInfo) {
println("MRTCDEBUG RTCContext::onRoom()") println("MRTCDEBUG 房间状态变化: type=$type, roomId=${roomInfo.roomId}")
isOnRoom_ = true println("MRTCDEBUG RTCContext::onRoom()")
} isOnRoom_ = true
}
override fun onRTMRoom(p0: Int, p1: Int) {
println("MRTCDEBUG onRTMRoom()") override fun onRTMRoom(p0: Int, p1: Int) {
} TODO("Not yet implemented")
}
override fun onProducer(p0: Int, p1: MRTCAdapter.MRTCProducerInfo?) {
println("MRTCDEBUG onProducer()") override fun onProducer(p0: Int, p1: MRTCAdapter.MRTCProducerInfo?) {
} TODO("Not yet implemented")
}
override fun onConsumer(msgId: Int, roomId: String?, peerId: String?, p3: Any?) {
println("MRTCDEBUG onConsumer, msgId:$msgId, roomId:$roomId, peerId:$peerId") override fun onConsumer(msgId: Int, roomId: String?, peerId: String?, p3: Any?) {
isOnConsumer_ = true println("MRTCDEBUG onConsumer, msgId:$msgId, roomId:$roomId, peerId:$peerId")
MRTCEngine.getDefault().registerSoundLevelListener(MRTCAdapter.MRTCAudioSourceType.TYPE_AUDIO_SOURCE_CUSTOM, isOnConsumer_ = true
roomId, peerId, srcChannelIndex_) MRTCEngine.getDefault().registerSoundLevelListener(MRTCAdapter.MRTCAudioSourceType.TYPE_AUDIO_SOURCE_CUSTOM,
var ret = MRTCEngine.getDefault().muteAudio(roomId, peerId, MRTCAdapter.MRTCAudioSourceType.TYPE_AUDIO_SOURCE_CUSTOM.type, roomId, peerId, srcChannelIndex_)
false, srcChannelIndex_) var ret = MRTCEngine.getDefault().muteAudio(roomId, peerId, MRTCAdapter.MRTCAudioSourceType.TYPE_AUDIO_SOURCE_CUSTOM.type,
if (ret != 0) { false, srcChannelIndex_)
println("MRTCDEBUG RTCContext::instance().muteAudio() failed, ret:$ret") if (ret != 0) {
return println("MRTCDEBUG RTCContext::instance().muteAudio() failed, ret:$ret")
} return
println("MRTCDEBUG init recv succ") }
println("MRTCDEBUG init recv succ")
}
}
override fun callBackMessage(code: Int, msg: String) {
println("MRTCDEBUG callBackMessage: [$code] $msg") override fun callBackMessage(code: Int, msg: String) {
} println("MRTCDEBUG callBackMessage: [$code] $msg")
}
override fun onCustomData(p0: MRTCAdapter.MRTCCustomData?) {
println("MRTCDEBUG onCustomData()") override fun onCustomData(p0: MRTCAdapter.MRTCCustomData?) {
} TODO("Not yet implemented")
}
override fun onDataProducer(p0: Int, p1: Int) {
println("MRTCDEBUG onDataProducer()") override fun onDataProducer(p0: Int, p1: Int) {
} TODO("Not yet implemented")
}
override fun onDataConsumer(p0: Int, p1: Int) {
println("MRTCDEBUG onDataConsumer()") override fun onDataConsumer(p0: Int, p1: Int) {
} TODO("Not yet implemented")
}
override fun onMessager(p0: String?, p1: String?, p2: String?, p3: String?) {
println("MRTCDEBUG onMessager()") override fun onMessager(p0: String?, p1: String?, p2: String?, p3: String?) {
} TODO("Not yet implemented")
}
override fun onRender(p0: String?, p1: String?, p2: Int, p3: Int, p4: MRTCVideoFrame?) {
println("MRTCDEBUG onRender()") override fun onRender(p0: String?, p1: String?, p2: Int, p3: Int, p4: MRTCVideoFrame?) {
} TODO("Not yet implemented")
}
override fun onScreenShot(p0: Bitmap?) {
println("MRTCDEBUG onScreenShot()") override fun onScreenShot(p0: Bitmap?) {
} TODO("Not yet implemented")
}
override fun onLocalAudioStats(p0: MRTCAdapter.MRTCLocalAudioStats?) {
println("MRTCDEBUG onLocalAudioStats()") override fun onLocalAudioStats(p0: MRTCAdapter.MRTCLocalAudioStats?) {
} TODO("Not yet implemented")
}
override fun onLocalVideoStats(p0: MRTCAdapter.MRTCLocalVideoStats?) {
println("MRTCDEBUG onLocalVideoStats()") override fun onLocalVideoStats(p0: MRTCAdapter.MRTCLocalVideoStats?) {
} TODO("Not yet implemented")
}
override fun onRemoteAudioStats(p0: MRTCAdapter.MRTCRemoteAudioStats?) {
println("MRTCDEBUG onRemoteAudioStats()") override fun onRemoteAudioStats(p0: MRTCAdapter.MRTCRemoteAudioStats?) {
} TODO("Not yet implemented")
}
override fun onRemoteVideoStats(p0: MRTCAdapter.MRTCRemoteVideoStats?) {
println("MRTCDEBUG onRemoteVideoStats()") override fun onRemoteVideoStats(p0: MRTCAdapter.MRTCRemoteVideoStats?) {
} TODO("Not yet implemented")
}
override fun onSoundLevelUpdate(p0: String?, p1: String?, p2: Int, p3: Int, p4: Int) {
println("MRTCDEBUG onSoundLevelUpdate()") override fun onSoundLevelUpdate(p0: String?, p1: String?, p2: Int, p3: Int, p4: Int) {
} TODO("Not yet implemented")
} }
}
private fun initMRTCEngine() : Boolean {
println("MRTCDEBUG initMRTCEngine=======================") private fun initMRTCEngine() : Boolean {
println("MRTCDEBUG initMRTCEngine=======================")
val config = MRTCAdapter.Config().apply {
applicationId = applicationId_ val config = MRTCAdapter.Config().apply {
mAppSecrectKey = mAppSecrectKey_ // 设置必要参数根据SDK文档补充
domain = domain_ applicationId = applicationId_
mPort = mPort_ mAppSecrectKey = mAppSecrectKey_
} domain = domain_
var roomListener = RoomListener() mPort = mPort_
roomListener.setOnDorySDKListener(sdkListener_) }
//MRTCEngine.setSDKLogDirectory("/Users/wangjiyu/StudioProjects/Log")
var ret1 = MRTCEngine.getDefault().init(config, this) RoomListener().setOnDorySDKListener(sdkListener_)
if (ret1 != 0) {
println("MRTCDEBUG RTCContext::instance().init() failed, ret:$ret1") val ret1 = MRTCEngine.getDefault().init(config, this)
return false if (ret1 != 0) {
} println("MRTCDEBUG RTCContext::instance().init() failed, ret:$ret1")
MRTCEngine.getDefault().setUserInfo(srcUserId_,srcDisplayName_,srcRoomId_) return false
var loginConfig = MRTCAdapter.LoginConfigParams().apply { }
mAppId = applicationId_
mAppSecrectKey = mAppSecrectKey_ MRTCEngine.getDefault().registerListener(MRTCAdapter.MRTCListenerType.TYPE_LISTENER_ROOM)
} MRTCEngine.getDefault().registerListener(MRTCAdapter.MRTCListenerType.TYPE_LISTENER_CONSUMER)
MRTCEngine.getDefault().registerListener(MRTCAdapter.MRTCListenerType.TYPE_LISTENER_ROOM) MRTCEngine.getDefault().registerReceivedMicAudioFrameListener(audioListener_)
MRTCEngine.getDefault().registerListener(MRTCAdapter.MRTCListenerType.TYPE_LISTENER_CONSUMER)
var ret2 = MRTCEngine.getDefault().joinRoom(loginConfig) MRTCEngine.getDefault().setUserInfo(srcUserId_,srcDisplayName_,srcRoomId_)
if (ret2 != 0) { val loginConfig = MRTCAdapter.LoginConfigParams().apply {
println("MRTCDEBUG RTCContext::instance().joinRoom() failed, ret:$ret2") mAppId = applicationId_
return false mAppSecrectKey = mAppSecrectKey_
} }
MRTCEngine.getDefault().registerReceivedMicAudioFrameListener(audioListener_) val ret2 = MRTCEngine.getDefault().joinRoom(loginConfig)
println("MRTCDEBUG init succ") if (ret2 != 0) {
return true println("MRTCDEBUG RTCContext::instance().joinRoom() failed, ret:$ret2")
} return false
}
private fun initSendMRTCEngine() : Boolean { println("MRTCDEBUG init succ")
while (!isOnRoom_) return true
{ }
println("MRTCDEBUG wait for OnRoom")
Thread.sleep(3000) private fun initSendMRTCEngine() : Boolean {
} while (!isOnRoom_)
{
println("MRTCDEBUG initSendMRTCEngine=======================") println("MRTCDEBUG wait for OnRoom")
val option = MRTCAdapter.MRTCAudioOption().apply { Thread.sleep(3000)
// 修改需要自定义的参数 }
sampleRate = sampleRate_
channel = 1 // 改为立体声 println("MRTCDEBUG initSendMRTCEngine=======================")
channelIndex = destChannelIndex_ val option = MRTCAdapter.MRTCAudioOption().apply {
echoCancellation = true // 开启回声消除 // 修改需要自定义的参数
} sampleRate = sampleRate_
var ret = MRTCEngine.getDefault().startCustomAudio(option) channel = 1 // 改为立体声
if (ret != 0) { channelIndex = destChannelIndex_
println("MRTCDEBUG startCustomAudio fail, ret:$ret") echoCancellation = true // 开启回声消除
return false }
} var ret = MRTCEngine.getDefault().startCustomAudio(option)
println("MRTCDEBUG init send succ") if (ret != 0) {
return true println("MRTCDEBUG startCustomAudio fail, ret:$ret")
return false
} }
println("MRTCDEBUG init send succ")
private fun initRecvMRTCEngine() : Boolean { return true
println("MRTCDEBUG initRecvMRTCEngine=======================")
while (!isOnConsumer_) }
{
println("MRTCDEBUG wait for OnConsumer") private fun initRecvMRTCEngine() : Boolean {
Thread.sleep(3000) println("MRTCDEBUG initRecvMRTCEngine=======================")
} while (!isOnConsumer_)
return true {
println("MRTCDEBUG wait for OnConsumer")
} Thread.sleep(3000)
}
private fun sendCustomAudioData(data :ByteArray, dataLength :Int) : Boolean { return true
while(!isOnRoom_) {
println("MRTCDEBUG wait for room and multi room before send") }
Thread.sleep(3000)
} private fun sendCustomAudioData(data :ByteArray, dataLength :Int) : Boolean {
if (data == null) { while(!isOnRoom_) {
println("MRTCDEBUG customData is null") println("MRTCDEBUG wait for room and multi room before send")
return false Thread.sleep(3000)
} }
println("MRTCDEBUG sendAudioData=======================") if (data == null) {
MRTCEngine.getDefault().sendCustomAudioData(data, sampleRate_, channelNum_, dataLength) println("MRTCDEBUG customData is null")
return true return false
}
} println("MRTCDEBUG sendAudioData=======================")
MRTCEngine.getDefault().sendCustomAudioData(data, sampleRate_, channelNum_, dataLength)
return true
private fun showToast(message: String) {
// 实现Toast显示 }
println("MRTCDEBUG showToast: $message")
private fun showToast(message: String) {
} // 实现Toast显示
println("MRTCDEBUG showToast: $message")
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
val context = LocalContext.current }
val isSDKReady = remember { mutableStateOf(false) }
var ret1 = initMRTCEngine() @Composable
if (!ret1) { fun Greeting(name: String, modifier: Modifier = Modifier) {
println("MRTCDEBUG init fail, ret:$ret1") val context = LocalContext.current
return val isSDKReady = remember { mutableStateOf(false) }
} var ret1 = initMRTCEngine()
var ret2 = initSendMRTCEngine() if (!ret1) {
if (!ret2) { println("MRTCDEBUG init fail, ret:$ret1")
println("MRTCDEBUG initSend fail, ret:$ret2") return
return }
} thread {
var ret3 = initRecvMRTCEngine() var ret2 = initSendMRTCEngine()
if (!ret3) { if (!ret2) {
println("MRTCDEBUG initRecv fail, ret:$ret3") println("MRTCDEBUG initSend fail, ret:$ret2")
return }
} thread {
var ret3 = initRecvMRTCEngine()
val data: ByteArray = "Hello".toByteArray(Charsets.UTF_8) if (!ret3) {
val dataLength: Int = data.size println("MRTCDEBUG initRecv fail, ret:$ret3")
for (i in 1..100) { }
println("MRTCDEBUG 第${i}次循环") }
// 执行您的业务逻辑
val data: ByteArray = "Hello".toByteArray(Charsets.UTF_8)
var ret4 = sendCustomAudioData(data, dataLength) val dataLength: Int = data.size
if (!ret4) { for (i in 1..100) {
println("MRTCDEBUG send fail, ret:$ret3") println("MRTCDEBUG 第${i}次循环")
return // 执行您的业务逻辑
}
Thread.sleep(3000) var ret4 = sendCustomAudioData(data, dataLength)
if (!ret4) {
} println("MRTCDEBUG send fail, ret:$ret4")
}
Thread.sleep(3000)
// 监听SDK状态 }
LaunchedEffect(Unit) { }
// 这里可以添加SDK状态监听逻辑
}
Text( // 监听SDK状态
text = if (isSDKReady.value) "Hello $name! (SDK Ready)" else "Loading SDK1...", LaunchedEffect(Unit) {
modifier = modifier // 这里可以添加SDK状态监听逻辑
) }
}
Text(
@Preview(showBackground = true) text = if (isSDKReady.value) "Hello $name! (SDK Ready)" else "Loading SDK1...",
@Composable modifier = modifier
fun GreetingPreview() { )
println("MRTCDEBUG GreetingPreview")
MRTCDemoTheme { }
Greeting("Android")
} @Preview(showBackground = true)
} @Composable
} fun GreetingPreview() {
println("MRTCDEBUG GreetingPreview")
MRTCDemoTheme {
Greeting("Android")
}
}
}

View File

@ -0,0 +1,331 @@
package com.example.mrtcdemo
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.res.AssetManager
import android.graphics.Bitmap
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import cn.migu.tsg.MRTCEngine
import cn.migu.tsg.MRTCAdapter
import cn.migu.tsg.MRTCVideoFrame
import cn.migu.tsg.OnMRTCSDKListener
import cn.migu.tsg.RoomListener
import com.example.mrtcdemo.ui.theme.MRTCDemoTheme
class MainActivity : ComponentActivity() {
// 权限请求回调
private val permissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
if (permissions.all { it.value }) {
// 所有权限已授予开始加载SDK
} else {
// 处理权限被拒绝的情况
showToast("权限被拒绝,功能将受限")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
// 请求必要权限
requestPermissions()
setContent {
MRTCDemoTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
private fun requestPermissions() {
permissionLauncher.launch(
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.INTERNET,
Manifest.permission.RECORD_AUDIO
)
)
}
var applicationId_ = "1357389261426393088"
var mAppSecrectKey_ = "gytr3qrrznsgac2lbdchfg0l4ltqx4x3nf4my0yt1dbx7riz1gnnsnhblrlc2j4o1lx4vdu495lifv8s7jyrmfxtq9lif9rusxnur5smdn5cjopstxp5dim7p52xrezp"
var domain_ = "rtc.migu.cn"
var mPort_ = 34443
var srcUserId_ = "srcUser12"
var destUserId_ = "destUser12"
var srcDisplayName_ = "srcDisplayName12"
var destDisplayName_ = "destDisplayName12"
var srcRoomId_ = "srcRoom12"
var destRoomId_ = srcRoomId_
var srcChannelIndex_ = 46
var destChannelIndex_ = 47
var sampleRate_ = 16000
var channelNum_ = 1
var isOnRoom_ = false
var isOnConsumer_ = false
private val audioListener_ = object : MRTCAdapter.MRTCAudioProcessListener {
override fun onReceiveRawAudioFrame(streamId: String, userId: String, frame: MRTCAdapter.MRTCAudioFrame) {
// 在这里处理原始音频帧
println("MRTCDEBUG ==================================")
println("MRTCDEBUG streamId=$streamId, userId=$userId")
println("MRTCDEBUG frame, channel=${frame.channel}, length=${frame.length}, sampleRate=${frame.sampleRate}")
println(frame.audioBuffer)
}
}
private val sdkListener_ = object : OnMRTCSDKListener {
override fun onRoom(type: Int, roomInfo: MRTCAdapter.MRTCRoomInfo) {
println("MRTCDEBUG 房间状态变化: type=$type, roomId=${roomInfo.roomId}")
println("MRTCDEBUG RTCContext::onRoom()")
isOnRoom_ = true
}
override fun onRTMRoom(p0: Int, p1: Int) {
println("MRTCDEBUG onRTMRoom()")
}
override fun onProducer(p0: Int, p1: MRTCAdapter.MRTCProducerInfo?) {
println("MRTCDEBUG onProducer()")
}
override fun onConsumer(msgId: Int, roomId: String?, peerId: String?, p3: Any?) {
println("MRTCDEBUG onConsumer, msgId:$msgId, roomId:$roomId, peerId:$peerId")
isOnConsumer_ = true
MRTCEngine.getDefault().registerSoundLevelListener(MRTCAdapter.MRTCAudioSourceType.TYPE_AUDIO_SOURCE_CUSTOM,
roomId, peerId, srcChannelIndex_)
var ret = MRTCEngine.getDefault().muteAudio(roomId, peerId, MRTCAdapter.MRTCAudioSourceType.TYPE_AUDIO_SOURCE_CUSTOM.type,
false, srcChannelIndex_)
if (ret != 0) {
println("MRTCDEBUG RTCContext::instance().muteAudio() failed, ret:$ret")
return
}
println("MRTCDEBUG init recv succ")
}
override fun callBackMessage(code: Int, msg: String) {
println("MRTCDEBUG callBackMessage: [$code] $msg")
}
override fun onCustomData(p0: MRTCAdapter.MRTCCustomData?) {
println("MRTCDEBUG onCustomData()")
}
override fun onDataProducer(p0: Int, p1: Int) {
println("MRTCDEBUG onDataProducer()")
}
override fun onDataConsumer(p0: Int, p1: Int) {
println("MRTCDEBUG onDataConsumer()")
}
override fun onMessager(p0: String?, p1: String?, p2: String?, p3: String?) {
println("MRTCDEBUG onMessager()")
}
override fun onRender(p0: String?, p1: String?, p2: Int, p3: Int, p4: MRTCVideoFrame?) {
println("MRTCDEBUG onRender()")
}
override fun onScreenShot(p0: Bitmap?) {
println("MRTCDEBUG onScreenShot()")
}
override fun onLocalAudioStats(p0: MRTCAdapter.MRTCLocalAudioStats?) {
println("MRTCDEBUG onLocalAudioStats()")
}
override fun onLocalVideoStats(p0: MRTCAdapter.MRTCLocalVideoStats?) {
println("MRTCDEBUG onLocalVideoStats()")
}
override fun onRemoteAudioStats(p0: MRTCAdapter.MRTCRemoteAudioStats?) {
println("MRTCDEBUG onRemoteAudioStats()")
}
override fun onRemoteVideoStats(p0: MRTCAdapter.MRTCRemoteVideoStats?) {
println("MRTCDEBUG onRemoteVideoStats()")
}
override fun onSoundLevelUpdate(p0: String?, p1: String?, p2: Int, p3: Int, p4: Int) {
println("MRTCDEBUG onSoundLevelUpdate()")
}
}
private fun initMRTCEngine() : Boolean {
println("MRTCDEBUG initMRTCEngine=======================")
val config = MRTCAdapter.Config().apply {
applicationId = applicationId_
mAppSecrectKey = mAppSecrectKey_
domain = domain_
mPort = mPort_
}
var roomListener = RoomListener()
roomListener.setOnDorySDKListener(sdkListener_)
//MRTCEngine.setSDKLogDirectory("/Users/wangjiyu/StudioProjects/Log")
var ret1 = MRTCEngine.getDefault().init(config, this)
if (ret1 != 0) {
println("MRTCDEBUG RTCContext::instance().init() failed, ret:$ret1")
return false
}
MRTCEngine.getDefault().setUserInfo(srcUserId_,srcDisplayName_,srcRoomId_)
var loginConfig = MRTCAdapter.LoginConfigParams().apply {
mAppId = applicationId_
mAppSecrectKey = mAppSecrectKey_
}
MRTCEngine.getDefault().registerListener(MRTCAdapter.MRTCListenerType.TYPE_LISTENER_ROOM)
MRTCEngine.getDefault().registerListener(MRTCAdapter.MRTCListenerType.TYPE_LISTENER_CONSUMER)
var ret2 = MRTCEngine.getDefault().joinRoom(loginConfig)
if (ret2 != 0) {
println("MRTCDEBUG RTCContext::instance().joinRoom() failed, ret:$ret2")
return false
}
MRTCEngine.getDefault().registerReceivedMicAudioFrameListener(audioListener_)
println("MRTCDEBUG init succ")
return true
}
private fun initSendMRTCEngine() : Boolean {
while (!isOnRoom_)
{
println("MRTCDEBUG wait for OnRoom")
Thread.sleep(3000)
}
println("MRTCDEBUG initSendMRTCEngine=======================")
val option = MRTCAdapter.MRTCAudioOption().apply {
// 修改需要自定义的参数
sampleRate = sampleRate_
channel = 1 // 改为立体声
channelIndex = destChannelIndex_
echoCancellation = true // 开启回声消除
}
var ret = MRTCEngine.getDefault().startCustomAudio(option)
if (ret != 0) {
println("MRTCDEBUG startCustomAudio fail, ret:$ret")
return false
}
println("MRTCDEBUG init send succ")
return true
}
private fun initRecvMRTCEngine() : Boolean {
println("MRTCDEBUG initRecvMRTCEngine=======================")
while (!isOnConsumer_)
{
println("MRTCDEBUG wait for OnConsumer")
Thread.sleep(3000)
}
return true
}
private fun sendCustomAudioData(data :ByteArray, dataLength :Int) : Boolean {
while(!isOnRoom_) {
println("MRTCDEBUG wait for room and multi room before send")
Thread.sleep(3000)
}
if (data == null) {
println("MRTCDEBUG customData is null")
return false
}
println("MRTCDEBUG sendAudioData=======================")
MRTCEngine.getDefault().sendCustomAudioData(data, sampleRate_, channelNum_, dataLength)
return true
}
private fun showToast(message: String) {
// 实现Toast显示
println("MRTCDEBUG showToast: $message")
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
val context = LocalContext.current
val isSDKReady = remember { mutableStateOf(false) }
var ret1 = initMRTCEngine()
if (!ret1) {
println("MRTCDEBUG init fail, ret:$ret1")
return
}
var ret2 = initSendMRTCEngine()
if (!ret2) {
println("MRTCDEBUG initSend fail, ret:$ret2")
return
}
var ret3 = initRecvMRTCEngine()
if (!ret3) {
println("MRTCDEBUG initRecv fail, ret:$ret3")
return
}
val data: ByteArray = "Hello".toByteArray(Charsets.UTF_8)
val dataLength: Int = data.size
for (i in 1..100) {
println("MRTCDEBUG 第${i}次循环")
// 执行您的业务逻辑
var ret4 = sendCustomAudioData(data, dataLength)
if (!ret4) {
println("MRTCDEBUG send fail, ret:$ret3")
return
}
Thread.sleep(3000)
}
// 监听SDK状态
LaunchedEffect(Unit) {
// 这里可以添加SDK状态监听逻辑
}
Text(
text = if (isSDKReady.value) "Hello $name! (SDK Ready)" else "Loading SDK1...",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
println("MRTCDEBUG GreetingPreview")
MRTCDemoTheme {
Greeting("Android")
}
}
}