diff --git a/example/libs/sellycloudsdk-1.0.0.aar b/example/libs/sellycloudsdk-1.0.0.aar
index 1414a03..5869442 100644
Binary files a/example/libs/sellycloudsdk-1.0.0.aar and b/example/libs/sellycloudsdk-1.0.0.aar differ
diff --git a/example/src/main/java/com/demo/SellyCloudSDK/FeatureHubActivity.kt b/example/src/main/java/com/demo/SellyCloudSDK/FeatureHubActivity.kt
index 093e38d..fff849d 100644
--- a/example/src/main/java/com/demo/SellyCloudSDK/FeatureHubActivity.kt
+++ b/example/src/main/java/com/demo/SellyCloudSDK/FeatureHubActivity.kt
@@ -117,7 +117,14 @@ class FeatureHubActivity : AppCompatActivity() {
private fun setupActions() {
binding.btnHomeLivePush.setOnClickListener {
- showPushSettingsDialog { showPushProtocolSheet() }
+ showPushSettingsDialog {
+ val settings = settingsStore.read()
+ if (settings.useUrlMode) {
+ startActivity(LivePushActivity.createIntent(this, SellyLiveMode.RTMP))
+ } else {
+ showPushProtocolSheet()
+ }
+ }
}
binding.btnHomeLivePull.setOnClickListener {
showPlayConfigDialog()
@@ -341,6 +348,7 @@ class FeatureHubActivity : AppCompatActivity() {
val current = settingsStore.read()
dialogBinding.etStreamId.setText(generateRandomStreamId())
+ dialogBinding.etPushUrl.setText(current.pushUrl)
dialogBinding.etFps.setText(current.fps.toString())
dialogBinding.etMaxBitrate.setText(current.maxBitrateKbps.toString())
dialogBinding.etMinBitrate.setText(current.minBitrateKbps.toString())
@@ -354,16 +362,39 @@ class FeatureHubActivity : AppCompatActivity() {
}
)
+ fun updateModeVisibility(urlMode: Boolean) {
+ dialogBinding.groupUrlMode.visibility = if (urlMode) View.VISIBLE else View.GONE
+ dialogBinding.groupStreamIdMode.visibility = if (urlMode) View.GONE else View.VISIBLE
+ }
+
+ dialogBinding.rgPushMode.check(
+ if (current.useUrlMode) R.id.rbModeUrl else R.id.rbModeStreamId
+ )
+ updateModeVisibility(current.useUrlMode)
+
+ dialogBinding.rgPushMode.setOnCheckedChangeListener { _, checkedId ->
+ updateModeVisibility(checkedId == R.id.rbModeUrl)
+ }
+
dialogBinding.btnClose.setOnClickListener { dialog.dismiss() }
dialogBinding.btnApply.setOnClickListener {
+ val useUrlMode = dialogBinding.rgPushMode.checkedRadioButtonId == R.id.rbModeUrl
+ val pushUrl = dialogBinding.etPushUrl.text?.toString()?.trim().orEmpty()
val streamId = dialogBinding.etStreamId.text?.toString()?.trim().orEmpty()
val fps = dialogBinding.etFps.text?.toString()?.trim()?.toIntOrNull()
val maxKbps = dialogBinding.etMaxBitrate.text?.toString()?.trim()?.toIntOrNull()
val minKbps = dialogBinding.etMinBitrate.text?.toString()?.trim()?.toIntOrNull()
- if (streamId.isEmpty()) {
- Toast.makeText(this, "请输入 Stream ID", Toast.LENGTH_SHORT).show()
- return@setOnClickListener
+ if (useUrlMode) {
+ if (pushUrl.isEmpty()) {
+ Toast.makeText(this, "请输入推流地址", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+ } else {
+ if (streamId.isEmpty()) {
+ Toast.makeText(this, "请输入 Stream ID", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
}
if (fps == null || fps <= 0) {
Toast.makeText(this, "请输入正确的 FPS", Toast.LENGTH_SHORT).show()
@@ -392,7 +423,9 @@ class FeatureHubActivity : AppCompatActivity() {
fps = fps,
maxBitrateKbps = maxKbps,
minBitrateKbps = minKbps,
- xorKeyHex = xorKey
+ xorKeyHex = xorKey,
+ useUrlMode = useUrlMode,
+ pushUrl = pushUrl
)
settingsStore.write(updated)
dialog.dismiss()
diff --git a/example/src/main/java/com/demo/SellyCloudSDK/avdemo/AvDemoSettingsStore.kt b/example/src/main/java/com/demo/SellyCloudSDK/avdemo/AvDemoSettingsStore.kt
index c80e86e..fba3bc0 100644
--- a/example/src/main/java/com/demo/SellyCloudSDK/avdemo/AvDemoSettingsStore.kt
+++ b/example/src/main/java/com/demo/SellyCloudSDK/avdemo/AvDemoSettingsStore.kt
@@ -10,6 +10,8 @@ data class AvDemoSettings(
val maxBitrateKbps: Int,
val minBitrateKbps: Int,
val xorKeyHex: String = "",
+ val useUrlMode: Boolean = false,
+ val pushUrl: String = "",
) {
enum class Resolution { P360, P480, P540, P720 }
@@ -38,7 +40,9 @@ class AvDemoSettingsStore(context: Context) {
fps = prefs.getInt(KEY_FPS, DEFAULT_FPS),
maxBitrateKbps = prefs.getInt(KEY_MAX_KBPS, DEFAULT_MAX_KBPS),
minBitrateKbps = prefs.getInt(KEY_MIN_KBPS, DEFAULT_MIN_KBPS),
- xorKeyHex = prefs.getString(KEY_XOR_KEY_HEX, "").orEmpty()
+ xorKeyHex = prefs.getString(KEY_XOR_KEY_HEX, "").orEmpty(),
+ useUrlMode = prefs.getBoolean(KEY_USE_URL_MODE, false),
+ pushUrl = prefs.getString(KEY_PUSH_URL, "").orEmpty()
)
}
@@ -50,6 +54,8 @@ class AvDemoSettingsStore(context: Context) {
putInt(KEY_MAX_KBPS, settings.maxBitrateKbps)
putInt(KEY_MIN_KBPS, settings.minBitrateKbps)
putString(KEY_XOR_KEY_HEX, settings.xorKeyHex)
+ putBoolean(KEY_USE_URL_MODE, settings.useUrlMode)
+ putString(KEY_PUSH_URL, settings.pushUrl)
}
}
@@ -66,5 +72,7 @@ class AvDemoSettingsStore(context: Context) {
private const val DEFAULT_MAX_KBPS = 2000
private const val DEFAULT_MIN_KBPS = 500
private const val KEY_XOR_KEY_HEX = "xor_key_hex"
+ private const val KEY_USE_URL_MODE = "use_url_mode"
+ private const val KEY_PUSH_URL = "push_url"
}
}
diff --git a/example/src/main/java/com/demo/SellyCloudSDK/live/LivePushActivity.kt b/example/src/main/java/com/demo/SellyCloudSDK/live/LivePushActivity.kt
index 140fe8c..d833803 100644
--- a/example/src/main/java/com/demo/SellyCloudSDK/live/LivePushActivity.kt
+++ b/example/src/main/java/com/demo/SellyCloudSDK/live/LivePushActivity.kt
@@ -130,22 +130,31 @@ class LivePushActivity : AppCompatActivity() {
pusher.stopLive()
} else {
val settings = settingsStore.read()
- val env = envStore.read()
- val streamId = settings.streamId
- val authError = LiveAuthHelper.validateAuthConfig(env, streamId)
- if (authError != null) {
- Toast.makeText(this, authError, Toast.LENGTH_SHORT).show()
- return@setOnClickListener
- }
- val auth = LiveAuthHelper.buildAuthParams(
- env = env,
- channelId = streamId,
- type = LiveTokenSigner.TokenType.PUSH
- )
applyStreamConfig(settings)
- pusher.token = auth?.tokenResult?.token
pusher.setXorKey(settings.xorKeyHex)
- pusher.startLiveWithStreamId(streamId)
+ if (settings.useUrlMode) {
+ val pushUrl = settings.pushUrl
+ if (pushUrl.isEmpty()) {
+ Toast.makeText(this, "请先在设置中输入推流地址", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+ pusher.startLiveWithUrl(pushUrl)
+ } else {
+ val env = envStore.read()
+ val streamId = settings.streamId
+ val authError = LiveAuthHelper.validateAuthConfig(env, streamId)
+ if (authError != null) {
+ Toast.makeText(this, authError, Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+ val auth = LiveAuthHelper.buildAuthParams(
+ env = env,
+ channelId = streamId,
+ type = LiveTokenSigner.TokenType.PUSH
+ )
+ pusher.token = auth?.tokenResult?.token
+ pusher.startLiveWithStreamId(streamId)
+ }
}
}
diff --git a/example/src/main/res/layout/dialog_live_preset_settings.xml b/example/src/main/res/layout/dialog_live_preset_settings.xml
index fa75370..62da0f8 100644
--- a/example/src/main/res/layout/dialog_live_preset_settings.xml
+++ b/example/src/main/res/layout/dialog_live_preset_settings.xml
@@ -40,28 +40,112 @@
app:tint="@color/brand_primary" />
+
-
+ android:background="@drawable/bg_av_segment_container"
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
应用
Stream ID
关闭设置
+ 推流模式
+ StreamID
+ URL
+ 推流地址
播放配置
播放协议