diff --git a/README.md b/README.md
index 4d1cedc..1bb3f80 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[![badge](https://img.shields.io/github/stars/apivideo/api.video-android-live-stream?style=social)](https://github.com/apivideo/api.video-android-live-stream)
[![badge](https://img.shields.io/discourse/topics?server=https%3A%2F%2Fcommunity.api.video)](https://community.api.video)
![](https://github.com/apivideo/.github/blob/main/assets/apivideo_banner.png)
-
Android RTMP live stream client
+Android RTMP and SRT live stream client
[api.video](https://api.video) is the video infrastructure for product builders. Lightning fast
video APIs for integrating, scaling, and managing on-demand & low latency live streaming features in
@@ -154,8 +154,8 @@ You can check device supported configurations by using the helper: `Helper`
We are using external library
-| Plugin | README |
-| ------ | ------ |
+| Plugin | README |
+|---------------------------------------------------------|------------------------------------------------------------------------------|
| [StreamPack](https://github.com/ThibaultBee/StreamPack) | [README.md](https://github.com/ThibaultBee/StreamPack/blob/master/README.md) |
## Sample application
diff --git a/example/src/main/java/video/api/livestream/example/ui/utils/Configuration.kt b/example/src/main/java/video/api/livestream/example/ui/utils/Configuration.kt
index 5accac4..9f72a7d 100644
--- a/example/src/main/java/video/api/livestream/example/ui/utils/Configuration.kt
+++ b/example/src/main/java/video/api/livestream/example/ui/utils/Configuration.kt
@@ -76,11 +76,11 @@ class Configuration(context: Context) {
class Endpoint(private val sharedPref: SharedPreferences, private val resources: Resources) {
var url: String = ""
get() = sharedPref.getString(
- resources.getString(R.string.rtmp_endpoint_url_key),
+ resources.getString(R.string.server_url_key),
field
)!!
var streamKey: String = ""
- get() = sharedPref.getString(resources.getString(R.string.rtmp_stream_key_key), field)!!
+ get() = sharedPref.getString(resources.getString(R.string.stream_key_key), field)!!
}
}
\ No newline at end of file
diff --git a/example/src/main/res/values/strings.xml b/example/src/main/res/values/strings.xml
index 451b16e..8234e2d 100644
--- a/example/src/main/res/values/strings.xml
+++ b/example/src/main/res/values/strings.xml
@@ -31,11 +31,11 @@
audio_enable_echo_canceler_key
audio_enable_noise_suppressor_key
Enable noise suppressor
- rtmp://broadcast.api.video/s/
- rtmp_address_key
- RTMP endpoint
- rtmp_stream_key_key
- Stream key
+ rtmp://broadcast.api.video/s/
+ server_url_key
+ RTMP or SRT server URL
+ stream_key_key
+ RTMP Stream key or SRT stream id
Permissions
Permissions not granted: leaving!
\ No newline at end of file
diff --git a/example/src/main/res/xml/preferences.xml b/example/src/main/res/xml/preferences.xml
index 6538188..9700112 100644
--- a/example/src/main/res/xml/preferences.xml
+++ b/example/src/main/res/xml/preferences.xml
@@ -62,15 +62,15 @@
\ No newline at end of file
diff --git a/livestream/build.gradle b/livestream/build.gradle
index fd3664c..c4b4aa8 100644
--- a/livestream/build.gradle
+++ b/livestream/build.gradle
@@ -59,6 +59,7 @@ dependencies {
implementation "io.github.thibaultbee.streampack:streampack-core:$streamPackVersion"
implementation "io.github.thibaultbee.streampack:streampack-ui:$streamPackVersion"
implementation "io.github.thibaultbee.streampack:streampack-extension-rtmp:$streamPackVersion"
+ implementation "io.github.thibaultbee.streampack:streampack-extension-srt:$streamPackVersion"
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
diff --git a/livestream/src/main/java/video/api/livestream/ApiVideoLiveStream.kt b/livestream/src/main/java/video/api/livestream/ApiVideoLiveStream.kt
index 346846e..40e2993 100644
--- a/livestream/src/main/java/video/api/livestream/ApiVideoLiveStream.kt
+++ b/livestream/src/main/java/video/api/livestream/ApiVideoLiveStream.kt
@@ -2,15 +2,17 @@ package video.api.livestream
import android.Manifest
import android.content.Context
+import android.net.Uri
import android.util.Log
import androidx.annotation.RequiresPermission
+import io.github.thibaultbee.streampack.core.data.mediadescriptor.MediaDescriptor
import io.github.thibaultbee.streampack.core.data.mediadescriptor.UriMediaDescriptor
import io.github.thibaultbee.streampack.core.internal.endpoints.MediaSinkType
import io.github.thibaultbee.streampack.core.streamers.callbacks.DefaultCameraCallbackStreamer
import io.github.thibaultbee.streampack.core.streamers.interfaces.ICallbackStreamer
-import io.github.thibaultbee.streampack.core.streamers.interfaces.startStream
import io.github.thibaultbee.streampack.core.utils.extensions.isBackCamera
import io.github.thibaultbee.streampack.core.utils.extensions.isFrontCamera
+import io.github.thibaultbee.streampack.ext.srt.data.mediadescriptor.SrtMediaDescriptor
import kotlinx.coroutines.*
import video.api.livestream.enums.CameraFacingDirection
import video.api.livestream.interfaces.IConnectionListener
@@ -287,31 +289,96 @@ constructor(
}
/**
- * Start a new RTMP stream.
+ * Start a new RTMP or SRT stream.
*
- * @param streamKey RTMP stream key. For security purpose, you must not expose it.
- * @param url RTMP Url. Default value (not set or null) is api.video RTMP broadcast url.
+ * Example of RTMP server url:
+ * ```
+ * rtmp://broadcast.api.video/s
+ * ```
+ *
+ * Example of SRT server url:
+ * ```
+ * srt://broadcast.api.video:6200
+ * ```
+ * Other query parameters will be ignored.
+ *
+ * @param streamKey The RTMP stream key or SRT stream id. For security purpose, you must not expose it.
+ * @param url The RTMP or SRT server Url. Default value (not set or null) is api.video RTMP broadcast url.
* @see [stopStreaming]
*/
fun startStreaming(
streamKey: String,
- url: String = context.getString(R.string.default_rtmp_url),
+ url: String = context.getString(R.string.default_server_url),
) {
require(!isStreaming) { "Stream is already running" }
require(streamKey.isNotEmpty()) { "Stream key must not be empty" }
require(url.isNotEmpty()) { "Url must not be empty" }
- require(audioConfig != null) { "Audio config must be set" }
- require(videoConfig != null) { "Video config must be set" }
+ requireNotNull(audioConfig) { "Audio config must be set" }
+ requireNotNull(videoConfig) { "Video config must be set" }
+
+ val descriptor = if (url.startsWith("srt://")) {
+ val uri = Uri.parse(url)
+ SrtMediaDescriptor(
+ host = requireNotNull(uri.host),
+ port = uri.port,
+ streamId = streamKey
+ )
+ } else {
+ UriMediaDescriptor(url.addTrailingSlashIfNeeded() + streamKey)
+ }
- val descriptor = UriMediaDescriptor(url.addTrailingSlashIfNeeded() + streamKey)
- require(descriptor.type.sinkType == MediaSinkType.RTMP) { "URL must be RTMP" }
+ startStreaming(descriptor)
+ }
+
+ /**
+ * Start a new RTMP or SRT stream.
+ *
+ * Example of RTMP url:
+ * ```
+ * rtmp://broadcast.api.video/s/{streamKey}
+ * ```
+ *
+ * Example of SRT url:
+ * ```
+ * srt://broadcast.api.video:6200?streamid={streamKey}
+ * ```
+ *
+ * Get the stream key from the api.video dashboard or through the API.
+ *
+ * @param url The RTMP or SRT server Url with stream key (RTMP) or stream id (SRT).
+ * @see [stopStreaming]
+ */
+ fun startStreaming(
+ url: String
+ ) {
+ require(!isStreaming) { "Stream is already running" }
+ require(url.isNotEmpty()) { "Url must not be empty" }
+ requireNotNull(audioConfig) { "Audio config must be set" }
+ requireNotNull(videoConfig) { "Video config must be set" }
+
+ startStreaming(UriMediaDescriptor(url))
+ }
+
+ /**
+ * Start a new RTMP or SRT stream.
+ *
+ * @param descriptor The media descriptor
+ * @see [stopStreaming]
+ */
+ private fun startStreaming(
+ descriptor: MediaDescriptor
+ ) {
+ require(!isStreaming) { "Stream is already running" }
+ requireNotNull(audioConfig) { "Audio config must be set" }
+ requireNotNull(videoConfig) { "Video config must be set" }
+
+ require((descriptor.type.sinkType == MediaSinkType.RTMP) || (descriptor.type.sinkType == MediaSinkType.SRT)) { "URL must be RTMP or SRT" }
try {
- streamer.startStream(url)
- } catch (e: Exception) {
- streamer.close()
- connectionListener.onConnectionFailed("$e")
- throw e
+ streamer.startStream(descriptor)
+ } catch (t: Throwable) {
+ connectionListener.onConnectionFailed("$t")
+ throw t
}
}
diff --git a/livestream/src/main/res/values/strings.xml b/livestream/src/main/res/values/strings.xml
index b8b32ec..58e4d27 100644
--- a/livestream/src/main/res/values/strings.xml
+++ b/livestream/src/main/res/values/strings.xml
@@ -1,4 +1,4 @@
- rtmp://broadcast.api.video/s/
+ rtmp://broadcast.api.video/s/
\ No newline at end of file