Compare commits

..

No commits in common. "master" and "main" have entirely different histories.
master ... main

8 changed files with 917 additions and 671 deletions

4
.gitignore vendored
View File

@ -13,7 +13,3 @@
.externalNativeBuild .externalNativeBuild
.cxx .cxx
local.properties local.properties
.idea
.idea/*
.gitignore
.idea/*

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

12
.idea/gradle.xml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

10
.idea/migrations.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

10
.idea/misc.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

549
.idea/other.xml Normal file
View File

@ -0,0 +1,549 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="direct_access_persist.xml">
<option name="deviceSelectionList">
<list>
<PersistentDeviceSelectionData>
<option name="api" value="27" />
<option name="brand" value="DOCOMO" />
<option name="codename" value="F01L" />
<option name="id" value="F01L" />
<option name="manufacturer" value="FUJITSU" />
<option name="name" value="F-01L" />
<option name="screenDensity" value="360" />
<option name="screenX" value="720" />
<option name="screenY" value="1280" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="OnePlus" />
<option name="codename" value="OP5552L1" />
<option name="id" value="OP5552L1" />
<option name="manufacturer" value="OnePlus" />
<option name="name" value="CPH2415" />
<option name="screenDensity" value="480" />
<option name="screenX" value="1080" />
<option name="screenY" value="2412" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="OPPO" />
<option name="codename" value="OP573DL1" />
<option name="id" value="OP573DL1" />
<option name="manufacturer" value="OPPO" />
<option name="name" value="CPH2557" />
<option name="screenDensity" value="480" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="28" />
<option name="brand" value="DOCOMO" />
<option name="codename" value="SH-01L" />
<option name="id" value="SH-01L" />
<option name="manufacturer" value="SHARP" />
<option name="name" value="AQUOS sense2 SH-01L" />
<option name="screenDensity" value="480" />
<option name="screenX" value="1080" />
<option name="screenY" value="2160" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="Lenovo" />
<option name="codename" value="TB370FU" />
<option name="id" value="TB370FU" />
<option name="manufacturer" value="Lenovo" />
<option name="name" value="Tab P12" />
<option name="screenDensity" value="340" />
<option name="screenX" value="1840" />
<option name="screenY" value="2944" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="a15" />
<option name="id" value="a15" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="A15" />
<option name="screenDensity" value="450" />
<option name="screenX" value="1080" />
<option name="screenY" value="2340" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="a35x" />
<option name="id" value="a35x" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="A35" />
<option name="screenDensity" value="450" />
<option name="screenX" value="1080" />
<option name="screenY" value="2340" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="31" />
<option name="brand" value="samsung" />
<option name="codename" value="a51" />
<option name="id" value="a51" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy A51" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="google" />
<option name="codename" value="akita" />
<option name="id" value="akita" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 8a" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="motorola" />
<option name="codename" value="arcfox" />
<option name="id" value="arcfox" />
<option name="manufacturer" value="Motorola" />
<option name="name" value="razr plus 2024" />
<option name="screenDensity" value="360" />
<option name="screenX" value="1080" />
<option name="screenY" value="1272" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="motorola" />
<option name="codename" value="austin" />
<option name="id" value="austin" />
<option name="manufacturer" value="Motorola" />
<option name="name" value="moto g 5G (2022)" />
<option name="screenDensity" value="280" />
<option name="screenX" value="720" />
<option name="screenY" value="1600" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="samsung" />
<option name="codename" value="b0q" />
<option name="id" value="b0q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy S22 Ultra" />
<option name="screenDensity" value="600" />
<option name="screenX" value="1440" />
<option name="screenY" value="3088" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="32" />
<option name="brand" value="google" />
<option name="codename" value="bluejay" />
<option name="id" value="bluejay" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 6a" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="google" />
<option name="codename" value="caiman" />
<option name="id" value="caiman" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 9 Pro" />
<option name="screenDensity" value="360" />
<option name="screenX" value="960" />
<option name="screenY" value="2142" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="google" />
<option name="codename" value="comet" />
<option name="id" value="comet" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 9 Pro Fold" />
<option name="screenDensity" value="390" />
<option name="screenX" value="2076" />
<option name="screenY" value="2152" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="29" />
<option name="brand" value="samsung" />
<option name="codename" value="crownqlteue" />
<option name="id" value="crownqlteue" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Note9" />
<option name="screenDensity" value="420" />
<option name="screenX" value="2220" />
<option name="screenY" value="1080" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="dm2q" />
<option name="id" value="dm2q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="S23 Plus" />
<option name="screenDensity" value="450" />
<option name="screenX" value="1080" />
<option name="screenY" value="2340" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="dm3q" />
<option name="id" value="dm3q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy S23 Ultra" />
<option name="screenDensity" value="600" />
<option name="screenX" value="1440" />
<option name="screenY" value="3088" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="e1q" />
<option name="id" value="e1q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy S24" />
<option name="screenDensity" value="480" />
<option name="screenX" value="1080" />
<option name="screenY" value="2340" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="e3q" />
<option name="id" value="e3q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy S24 Ultra" />
<option name="screenDensity" value="450" />
<option name="screenX" value="1440" />
<option name="screenY" value="3120" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="eos" />
<option name="id" value="eos" />
<option name="manufacturer" value="Google" />
<option name="name" value="Eos" />
<option name="screenDensity" value="320" />
<option name="screenX" value="384" />
<option name="screenY" value="384" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="felix" />
<option name="id" value="felix" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel Fold" />
<option name="screenDensity" value="420" />
<option name="screenX" value="2208" />
<option name="screenY" value="1840" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="google" />
<option name="codename" value="felix" />
<option name="id" value="felix" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel Fold" />
<option name="screenDensity" value="420" />
<option name="screenX" value="2208" />
<option name="screenY" value="1840" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="felix_camera" />
<option name="id" value="felix_camera" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel Fold (Camera-enabled)" />
<option name="screenDensity" value="420" />
<option name="screenX" value="2208" />
<option name="screenY" value="1840" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="motorola" />
<option name="codename" value="fogona" />
<option name="id" value="fogona" />
<option name="manufacturer" value="Motorola" />
<option name="name" value="moto g play - 2024" />
<option name="screenDensity" value="280" />
<option name="screenX" value="720" />
<option name="screenY" value="1600" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="g0q" />
<option name="id" value="g0q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="SM-S906U1" />
<option name="screenDensity" value="450" />
<option name="screenX" value="1080" />
<option name="screenY" value="2340" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="gta9pwifi" />
<option name="id" value="gta9pwifi" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="SM-X210" />
<option name="screenDensity" value="240" />
<option name="screenX" value="1200" />
<option name="screenY" value="1920" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="gts7xllite" />
<option name="id" value="gts7xllite" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="SM-T738U" />
<option name="screenDensity" value="340" />
<option name="screenX" value="1600" />
<option name="screenY" value="2560" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="samsung" />
<option name="codename" value="gts8uwifi" />
<option name="id" value="gts8uwifi" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Tab S8 Ultra" />
<option name="screenDensity" value="320" />
<option name="screenX" value="1848" />
<option name="screenY" value="2960" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="gts8wifi" />
<option name="id" value="gts8wifi" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Tab S8" />
<option name="screenDensity" value="274" />
<option name="screenX" value="1600" />
<option name="screenY" value="2560" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="gts9fe" />
<option name="id" value="gts9fe" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Tab S9 FE 5G" />
<option name="screenDensity" value="280" />
<option name="screenX" value="1440" />
<option name="screenY" value="2304" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="google" />
<option name="codename" value="husky" />
<option name="id" value="husky" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 8 Pro" />
<option name="screenDensity" value="390" />
<option name="screenX" value="1008" />
<option name="screenY" value="2244" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="30" />
<option name="brand" value="motorola" />
<option name="codename" value="java" />
<option name="id" value="java" />
<option name="manufacturer" value="Motorola" />
<option name="name" value="G20" />
<option name="screenDensity" value="280" />
<option name="screenX" value="720" />
<option name="screenY" value="1600" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="google" />
<option name="codename" value="komodo" />
<option name="id" value="komodo" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 9 Pro XL" />
<option name="screenDensity" value="360" />
<option name="screenX" value="1008" />
<option name="screenY" value="2244" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="lynx" />
<option name="id" value="lynx" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 7a" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="motorola" />
<option name="codename" value="maui" />
<option name="id" value="maui" />
<option name="manufacturer" value="Motorola" />
<option name="name" value="moto g play - 2023" />
<option name="screenDensity" value="280" />
<option name="screenX" value="720" />
<option name="screenY" value="1600" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="o1q" />
<option name="id" value="o1q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy S21" />
<option name="screenDensity" value="421" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="31" />
<option name="brand" value="google" />
<option name="codename" value="oriole" />
<option name="id" value="oriole" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 6" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="panther" />
<option name="id" value="panther" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 7" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="q5q" />
<option name="id" value="q5q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Z Fold5" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1812" />
<option name="screenY" value="2176" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="q6q" />
<option name="id" value="q6q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy Z Fold6" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1856" />
<option name="screenY" value="2160" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="30" />
<option name="brand" value="google" />
<option name="codename" value="r11" />
<option name="id" value="r11" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel Watch" />
<option name="screenDensity" value="320" />
<option name="screenX" value="384" />
<option name="screenY" value="384" />
<option name="type" value="WEAR_OS" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="r11q" />
<option name="id" value="r11q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="SM-S711U" />
<option name="screenDensity" value="450" />
<option name="screenX" value="1080" />
<option name="screenY" value="2340" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="30" />
<option name="brand" value="google" />
<option name="codename" value="redfin" />
<option name="id" value="redfin" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 5" />
<option name="screenDensity" value="440" />
<option name="screenX" value="1080" />
<option name="screenY" value="2340" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="google" />
<option name="codename" value="shiba" />
<option name="id" value="shiba" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 8" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="samsung" />
<option name="codename" value="t2q" />
<option name="id" value="t2q" />
<option name="manufacturer" value="Samsung" />
<option name="name" value="Galaxy S21 Plus" />
<option name="screenDensity" value="394" />
<option name="screenX" value="1080" />
<option name="screenY" value="2400" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="33" />
<option name="brand" value="google" />
<option name="codename" value="tangorpro" />
<option name="id" value="tangorpro" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel Tablet" />
<option name="screenDensity" value="320" />
<option name="screenX" value="1600" />
<option name="screenY" value="2560" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="34" />
<option name="brand" value="google" />
<option name="codename" value="tokay" />
<option name="id" value="tokay" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 9" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2424" />
</PersistentDeviceSelectionData>
<PersistentDeviceSelectionData>
<option name="api" value="35" />
<option name="brand" value="google" />
<option name="codename" value="tokay" />
<option name="id" value="tokay" />
<option name="manufacturer" value="Google" />
<option name="name" value="Pixel 9" />
<option name="screenDensity" value="420" />
<option name="screenX" value="1080" />
<option name="screenY" value="2424" />
</PersistentDeviceSelectionData>
</list>
</option>
</component>
</project>

View File

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

View File

@ -1,331 +0,0 @@
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")
}
}
}