Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
cba7f74
[Fix] Compose picture-in-picture. NMS-26673
Sep 18, 2025
6185358
[Android]Update .h file.
Nov 13, 2025
f8423f6
[Android]Remove byte-dance beauty.
Nov 13, 2025
65e7d29
[FEAT] MacOS & Windows Local Video Transcoding
Nov 13, 2025
4527dcd
[FIX] macos transcoding debug
Nov 13, 2025
c41e5a3
[FEAT] macos transcoding video
Nov 14, 2025
bb1e58f
[FEAT] 4.6.1 macOS FPS
Nov 14, 2025
e3f6d98
Update screen share feature for OC
Nov 14, 2025
f07369c
Update screen share feature for SwiftUI
Nov 13, 2025
d980161
Update screen share feature
Nov 13, 2025
9a6ef1e
Fix issues
Nov 14, 2025
a20701d
[FIX] windows
Nov 14, 2025
e952618
Merge branch 'dev/4.6.1' of github.com:Shengwang-Community/API-Exampl…
Nov 14, 2025
d9382a9
Update teamId for CI
Nov 14, 2025
e5595f2
Merge branch 'dev/4.6.1' of https://github.com/Shengwang-Community/AP…
Nov 14, 2025
6498add
Update mobile profile
Nov 14, 2025
a945881
[FIX] windows sdk
Nov 14, 2025
61e6798
Merge branch 'dev/4.6.1' of github.com:Shengwang-Community/API-Exampl…
Nov 14, 2025
c9a3704
Update plist
Nov 14, 2025
69a965a
Merge branch 'dev/4.6.1' of https://github.com/Shengwang-Community/AP…
Nov 14, 2025
a897f7d
Update plist
Nov 14, 2025
9c2e3b0
Update plist
Nov 14, 2025
85e3f74
Update config
Nov 14, 2025
9ba420a
[FIX] windows scripts
Nov 14, 2025
e9b4269
Merge branch 'dev/4.6.1' of github.com:Shengwang-Community/API-Exampl…
Nov 14, 2025
9090d5f
Update config
Nov 14, 2025
d525a61
Merge branch 'dev/4.6.1' of https://github.com/Shengwang-Community/AP…
Nov 14, 2025
fe9cf5c
Update config
Nov 14, 2025
81fab94
Update config
Nov 14, 2025
15a0cc5
Bug fix
Nov 17, 2025
2f739e3
Bugfix
Nov 17, 2025
630b60f
Xcode build archive
Nov 17, 2025
b7c666a
Modify config
Nov 17, 2025
293312a
Change code sign type
Nov 17, 2025
773ca28
Fix use the extension identifier by mistake
Nov 17, 2025
7f49ca0
Add debug information for ci script
Nov 17, 2025
9e6716c
Update script
Nov 17, 2025
8d6e518
Modify config
Nov 17, 2025
09ce5d0
Modify script
Nov 17, 2025
5e13560
Update CI script
Nov 17, 2025
4ff5915
Update script
Nov 17, 2025
a08099e
Update PIP
Nov 17, 2025
56fee53
[FEAT] remove byte beauty effect
Nov 17, 2025
f03d659
[FIX] remove swift ui about thirdpart beauty
Nov 17, 2025
277c1a2
update android rtc_sdk_version to 4.6.2.
Nov 24, 2025
9237453
NMS-28354 LiveStreaming: update default video scenario to APPLICATION…
Nov 24, 2025
20864e8
Update live stream video scenario to "live show"
Nov 24, 2025
7243cd3
Merge branch 'dev/4.6.2' of https://github.com/Shengwang-Community/AP…
Nov 24, 2025
b70af39
[FIX] macos && windows setVideoScenario
Nov 24, 2025
c05da99
fixs compose ScreenSharing
Nov 25, 2025
91ae73d
update .h file
Nov 25, 2025
b856cb4
update agora-beauty resources
Nov 27, 2025
4a6bf16
Fix PIP issues
Dec 5, 2025
cb4df10
Merge branch 'dev/4.6.2' of https://github.com/Shengwang-Community/AP…
Dec 5, 2025
f7aba63
feat:CSD-71936
Dec 11, 2025
cec47c9
update cpp file
Dec 25, 2025
49a008b
update assets
Dec 25, 2025
28e2c21
[FIX] windows transcoding text
Dec 25, 2025
f1ef848
[FIX] iOS video process
Dec 30, 2025
06559f5
[FIX] 4.6.2 podfile
Jan 15, 2026
4a84db8
[FEAT] windows SDK download url 4.6.2
Jan 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ci/build/modify_podfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ def modfiy(path, sdk_flag):
with open(path, 'r', encoding='utf-8') as file:
contents = []
for num, line in enumerate(file):
if "pod 'Agora" in line:
if "pod 'Shengwang" in line:
if sdk_flag:
line = '\t'+"pod 'sdk', :path => '../../sdk.podspec'" + "\n"
elif "pod 'sdk" in line:
Expand Down
2 changes: 1 addition & 1 deletion Android/APIExample-Audio/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ android.nonFinalResIds=false
# read enable simple filter section on README first before set this flag to TRUE
simpleFilter = false

rtc_sdk_version = 4.6.0
rtc_sdk_version = 4.6.2
10 changes: 9 additions & 1 deletion Android/APIExample-Compose/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />

<application
android:allowBackup="true"
Expand All @@ -28,19 +32,23 @@
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.APIExampleCompose"
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize">
android:supportsPictureInPicture="true"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|screenSize|orientation|smallestScreenSize|screenLayout">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<!--
<activity
android:name=".samples.PictureInPictureActivity"
android:supportsPictureInPicture="true"
android:launchMode="singleTask"
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize"/>
-->

</application>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.agora.api.example.compose

import android.util.Log
import androidx.compose.runtime.Composable
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
Expand All @@ -9,6 +10,7 @@ import androidx.navigation.navArgument
import io.agora.api.example.compose.model.Component
import io.agora.api.example.compose.model.Components
import io.agora.api.example.compose.model.Example
import io.agora.api.example.compose.samples.cleanupPictureInPictureState
import io.agora.api.example.compose.ui.example.Example
import io.agora.api.example.compose.ui.home.Home
import io.agora.api.example.compose.ui.settings.Settings
Expand Down Expand Up @@ -48,7 +50,15 @@ fun NavGraph() {
val example = component.examples[exampleIndex]
Example(
example = example,
onBackClick = { navController.popBackStack() },
onBackClick = {
Log.d("PiPDebug", "NavGraph: onBackClick called for example: ${example.name}")
// Special handling for PictureInPicture example
if (example.name == R.string.example_pictureinpicture) {
Log.d("PiPDebug", "NavGraph: Cleaning up PictureInPicture state")
cleanupPictureInPictureState()
}
navController.popBackStack()
},
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import io.agora.api.example.compose.samples.MediaPlayer
import io.agora.api.example.compose.samples.MediaRecorder
import io.agora.api.example.compose.samples.OriginAudioData
import io.agora.api.example.compose.samples.OriginVideoData
import io.agora.api.example.compose.samples.PictureInPictureEntrance
import io.agora.api.example.compose.samples.PictureInPicture
import io.agora.api.example.compose.samples.PlayAudioFiles
import io.agora.api.example.compose.samples.PreCallTest
import io.agora.api.example.compose.samples.RTMPStreaming
Expand Down Expand Up @@ -54,7 +54,7 @@ val AdvanceExampleList = listOf(
Example(R.string.example_originvideodata) { OriginVideoData() },
Example(R.string.example_customvideosource) { CustomVideoSource() },
Example(R.string.example_customvideorender) { CustomVideoRender() },
Example(R.string.example_pictureinpicture) { PictureInPictureEntrance(it) },
Example(R.string.example_pictureinpicture) { PictureInPicture() },
Example(R.string.example_joinmultichannel) { JoinMultiChannel() },
Example(R.string.example_channelencryption) { ChannelEncryption() },
Example(R.string.example_playaudiofiles) { PlayAudioFiles() },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.agora.api.example.compose.samples

import android.util.Log
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
Expand Down Expand Up @@ -57,6 +58,17 @@ import io.agora.rtc2.video.VideoEncoderConfiguration
import io.agora.rtc2.video.VideoEncoderConfiguration.AdvanceOptions
import io.agora.rtc2.video.WatermarkOptions

private const val TAG = "LiveStreaming"

private fun getVideoScenarioName(scenario: Constants.VideoScenario): String {
return when (scenario) {
Constants.VideoScenario.APPLICATION_SCENARIO_GENERAL -> "General"
Constants.VideoScenario.APPLICATION_SCENARIO_MEETING -> "Meeting"
Constants.VideoScenario.APPLICATION_SCENARIO_1V1 -> "1V1"
Constants.VideoScenario.APPLICATION_SCENARIO_LIVESHOW -> "Live Show"
}
}

@Composable
fun LiveStreaming() {
val context = LocalContext.current
Expand All @@ -70,6 +82,9 @@ fun LiveStreaming() {
var localStats by remember { mutableStateOf(VideoStatsInfo()) }
var remoteStats by remember { mutableStateOf(VideoStatsInfo()) }
var clientRole by remember { mutableStateOf(Constants.CLIENT_ROLE_AUDIENCE) }
val settingsValues = remember { mutableStateMapOf<String, Any>().apply {
put("videoScenario", Constants.VideoScenario.APPLICATION_SCENARIO_LIVESHOW)
} }

val rtcEngine = remember {
RtcEngine.create(RtcEngineConfig().apply {
Expand Down Expand Up @@ -177,6 +192,10 @@ fun LiveStreaming() {
), 100, 15
)
)
// Set default video scenario
val defaultScenario = Constants.VideoScenario.APPLICATION_SCENARIO_LIVESHOW
val ret = setVideoScenario(defaultScenario)
Log.d(TAG, "onItemSelected: setVideoScenario " + getVideoScenarioName(defaultScenario) + " ret=" + ret)
}
}
DisposableEffect(lifecycleOwner) {
Expand All @@ -192,6 +211,11 @@ fun LiveStreaming() {
if (allGranted) {
// Permission is granted
Toast.makeText(context, R.string.permission_granted, Toast.LENGTH_LONG).show()
// Set video scenario before joining channel
val scenario = settingsValues["videoScenario"] as? Constants.VideoScenario
?: Constants.VideoScenario.APPLICATION_SCENARIO_LIVESHOW
val ret = rtcEngine.setVideoScenario(scenario)
Log.d(TAG, "onItemSelected: setVideoScenario " + getVideoScenarioName(scenario) + " ret=" + ret)
val mediaOptions = ChannelMediaOptions()
mediaOptions.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING
mediaOptions.clientRoleType = clientRole
Expand All @@ -214,6 +238,7 @@ fun LiveStreaming() {
localStats = localStats,
remoteStats = remoteStats,
localLarge = localLarge,
settingsValues = settingsValues,
onSwitch = {
localLarge = !localLarge
},
Expand Down Expand Up @@ -248,12 +273,12 @@ private fun LiveStreamingView(
localLarge: Boolean = true,
localStats: VideoStatsInfo = VideoStatsInfo(),
remoteStats: VideoStatsInfo = VideoStatsInfo(),
settingsValues: MutableMap<String, Any> = mutableMapOf(),
onSwitch: () -> Unit = {},
onJoinClick: (String) -> Unit,
onLeaveClick: () -> Unit
) {
var openSettingSheet by rememberSaveable { mutableStateOf(false) }
val settingsValues = remember { mutableStateMapOf<String, Any>() }

Box {
Column {
Expand Down Expand Up @@ -349,9 +374,17 @@ private fun LiveStreamingView(
rtcEngine = rtcEngine,
role = clientRole,
remoteUid = remoteUid,
isJoined = isJoined,
values = settingsValues,
onValueChanged = { key, value ->
settingsValues[key] = value
// Update video scenario immediately if not joined
if (key == "videoScenario" && !isJoined) {
val scenario = value as? Constants.VideoScenario
?: Constants.VideoScenario.APPLICATION_SCENARIO_LIVESHOW
val ret = rtcEngine?.setVideoScenario(scenario) ?: -1
Log.d(TAG, "onItemSelected: setVideoScenario " + getVideoScenarioName(scenario) + " ret=" + ret)
}
}
)
}
Expand Down Expand Up @@ -387,15 +420,34 @@ private fun LiveStreamingSettingView(
rtcEngine: RtcEngine? = null,
role: Int = Constants.CLIENT_ROLE_AUDIENCE,
remoteUid: Int = 0,
isJoined: Boolean = false,
values: Map<String, Any> = emptyMap(),
onValueChanged: (String, Any) -> Unit = { _, _ -> }
) {
val context = LocalContext.current
val videoScenario = values["videoScenario"] as? Constants.VideoScenario
?: Constants.VideoScenario.APPLICATION_SCENARIO_LIVESHOW

Column(
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {
// Video Scenario selection - must be set before joining channel
DropdownMenuRaw(
title = stringResource(id = R.string.video_scenario),
options = listOf(
stringResource(id = R.string.video_scenario_general) to Constants.VideoScenario.APPLICATION_SCENARIO_GENERAL,
stringResource(id = R.string.video_scenario_meeting) to Constants.VideoScenario.APPLICATION_SCENARIO_MEETING,
stringResource(id = R.string.video_scenario_1v1) to Constants.VideoScenario.APPLICATION_SCENARIO_1V1,
stringResource(id = R.string.video_scenario_liveshow) to Constants.VideoScenario.APPLICATION_SCENARIO_LIVESHOW,
),
selectedValue = videoScenario,
enable = !isJoined,
onSelected = { _, option ->
onValueChanged("videoScenario", option.second)
}
)
Divider(modifier = Modifier.padding(horizontal = 16.dp))
if (role == Constants.CLIENT_ROLE_AUDIENCE) {
SwitchRaw(
title = stringResource(id = R.string.open_low_latency_live),
Expand Down
Loading