Skip to content

Commit da5e4be

Browse files
committed
add support for custom AMF object in RTMP clients
1 parent a484758 commit da5e4be

5 files changed

Lines changed: 39 additions & 10 deletions

File tree

library/src/main/java/com/pedro/library/util/streamclient/RtmpStreamClient.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,5 +178,4 @@ class RtmpStreamClient(
178178
fun setCustomAmfObject(amfObject: Map<String, Any>) {
179179
rtmpClient.setCustomAmfObject(amfObject)
180180
}
181-
182181
}

library/src/main/java/com/pedro/library/util/streamclient/UdpStreamClient.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ class UdpStreamClient(
4040
udpClient.setDelay(millis)
4141
}
4242

43-
4443
override fun setReTries(reTries: Int) {
4544
udpClient.setReTries(reTries)
4645
}

rtmp/src/main/java/com/pedro/rtmp/amf/v0/AmfObject.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ open class AmfObject(private val properties: LinkedHashMap<AmfString, AmfData> =
9292
val newValue: AmfData = when (data) {
9393
is String -> AmfString(data)
9494
is Int -> AmfNumber(data.toDouble())
95+
is Long -> AmfNumber(data.toDouble())
9596
is Double -> AmfNumber(data)
9697
is Float -> AmfNumber(data.toDouble())
9798
is Boolean -> AmfBoolean(data)

rtmp/src/main/java/com/pedro/rtmp/rtmp/CommandsManagerAmf0.kt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,17 @@ class CommandsManagerAmf0: CommandsManager() {
3939
val connect = CommandAmf0("connect", ++commandId, getCurrentTimestamp(), streamId,
4040
BasicHeader(ChunkType.TYPE_0, ChunkStreamId.OVER_CONNECTION.mark))
4141
val connectInfo = AmfObject()
42-
connectInfo.setProperty("app", appName + auth)
42+
43+
// Prefer custom app/tcUrl if provided, and always append auth to keep auth flow working
44+
val customApp = customAmfObject["app"]?.toString()
45+
val customTcUrl = customAmfObject["tcUrl"]?.toString()
46+
val finalApp = (customApp ?: appName) + auth
47+
val finalTcUrl = (customTcUrl ?: tcUrl) + auth
48+
49+
connectInfo.setProperty("app", finalApp)
4350
connectInfo.setProperty("flashVer", flashVersion)
44-
connectInfo.setProperty("tcUrl", tcUrl + auth)
51+
connectInfo.setProperty("tcUrl", finalTcUrl)
52+
4553
if (!videoDisabled) {
4654
if (videoCodec == VideoCodec.H265) {
4755
val list = mutableListOf<AmfData>()
@@ -56,8 +64,14 @@ class CommandsManagerAmf0: CommandsManager() {
5664
}
5765
}
5866
connectInfo.setProperty("objectEncoding", 0.0)
67+
68+
// Inject other custom AMF fields as-is; skip app/tcUrl since we've handled them with auth
5969
customAmfObject.forEach { (key, value) ->
60-
connectInfo.setProperty(key, value)
70+
when (key) {
71+
"app" -> connectInfo.setProperty("app", finalApp)
72+
"tcUrl" -> connectInfo.setProperty("tcUrl", finalTcUrl)
73+
else -> connectInfo.setProperty(key, value)
74+
}
6175
}
6276
connect.addData(connectInfo)
6377

rtmp/src/main/java/com/pedro/rtmp/rtmp/RtmpClient.kt

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,28 @@ class RtmpClient(private val connectChecker: ConnectChecker) {
252252

253253
tunneled = urlParser.scheme.startsWith("rtmpt")
254254
tlsEnabled = urlParser.scheme.endsWith("s")
255-
commandsManager.host = urlParser.host
256255
val defaultPort = if (tlsEnabled) 443 else if (tunneled) 80 else 1935
257-
commandsManager.port = urlParser.port ?: defaultPort
258-
commandsManager.appName = urlParser.getAppName()
259-
commandsManager.streamName = urlParser.getStreamName()
260-
commandsManager.tcUrl = urlParser.getTcUrl()
256+
257+
// Prefer values from customAmfObject; fallback to URL parsed values
258+
val co = commandsManager.customAmfObject
259+
commandsManager.host = (co["host"] as? String) ?: urlParser.host
260+
commandsManager.port = (co["port"] as? Int) ?: (urlParser.port ?: defaultPort)
261+
commandsManager.appName = (co["app"] as? String) ?: urlParser.getAppName()
262+
commandsManager.streamName = (co["streamName"] as? String) ?: urlParser.getStreamName()
263+
commandsManager.tcUrl = (co["tcUrl"] as? String) ?: urlParser.getTcUrl()
264+
265+
// Print connection summary for visibility
266+
runCatching {
267+
val used = mapOf(
268+
"host" to (co["host"] != null),
269+
"port" to (co["port"] != null),
270+
"app" to (co["app"] != null),
271+
"streamName" to (co["streamName"] != null),
272+
"tcUrl" to (co["tcUrl"] != null)
273+
)
274+
Log.i(TAG, "connect config => host=${commandsManager.host}, port=${commandsManager.port}, app=${commandsManager.appName}, stream=${commandsManager.streamName}, tcUrl=${commandsManager.tcUrl}, tls=$tlsEnabled, tunneled=$tunneled, fromCustom=$used")
275+
}
276+
261277
if (commandsManager.appName.isEmpty()) {
262278
isStreaming = false
263279
onMainThread {

0 commit comments

Comments
 (0)