Skip to content

Commit

Permalink
chore(deps): upgrading to StreamPack 3.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaultBee committed Sep 24, 2024
1 parent 1c42407 commit 6c3f143
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 105 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ buildscript {
versionName = "${properties['VERSION_NAME']}"

// StreamPack
streamPackVersion = "2.6.1"
streamPackVersion = "3.0.0"
}
}
plugins {
Expand Down
6 changes: 3 additions & 3 deletions livestream/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation "io.github.thibaultbee:streampack:$streamPackVersion"
implementation "io.github.thibaultbee:streampack-extension-rtmp:$streamPackVersion"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
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"

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
Expand Down
109 changes: 41 additions & 68 deletions livestream/src/main/java/video/api/livestream/ApiVideoLiveStream.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import android.Manifest
import android.content.Context
import android.util.Log
import androidx.annotation.RequiresPermission
import io.github.thibaultbee.streampack.error.StreamPackError
import io.github.thibaultbee.streampack.ext.rtmp.streamers.CameraRtmpLiveStreamer
import io.github.thibaultbee.streampack.listeners.OnConnectionListener
import io.github.thibaultbee.streampack.listeners.OnErrorListener
import io.github.thibaultbee.streampack.utils.*
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 kotlinx.coroutines.*
import video.api.livestream.enums.CameraFacingDirection
import video.api.livestream.interfaces.IConnectionListener
Expand Down Expand Up @@ -69,8 +71,6 @@ constructor(
private const val TAG = "ApiVideoLiveStream"
}

private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)

/**
* Sets/gets audio configuration once you have created the a [ApiVideoLiveStream] instance.
*/
Expand Down Expand Up @@ -136,33 +136,30 @@ constructor(
}
}

private val internalConnectionListener = object : OnConnectionListener {
override fun onFailed(message: String) {
connectionListener.onConnectionFailed(message)
}

override fun onLost(message: String) {
connectionListener.onDisconnect()
private val internalListener = object : ICallbackStreamer.Listener {
override fun onOpenFailed(t: Throwable) {
connectionListener.onConnectionFailed(t.message ?: "Unknown error")
}

override fun onSuccess() {
connectionListener.onConnectionSuccess()
override fun onIsOpenChanged(isOpen: Boolean) {
if (isOpen) {
connectionListener.onConnectionSuccess()
} else {
connectionListener.onDisconnect()
}
}
}

private val errorListener = object : OnErrorListener {
override fun onError(error: StreamPackError) {
_isStreaming = false
Log.e(TAG, "An error happened", error)
override fun onError(throwable: Throwable) {
Log.e(TAG, "An error happened", throwable)
}
}

private val streamer = CameraRtmpLiveStreamer(
private val streamer = DefaultCameraCallbackStreamer(
context = context,
enableAudio = true,
initialOnErrorListener = errorListener,
initialOnConnectionListener = internalConnectionListener
)
enableMicrophone = true
).apply {
addListener(internalListener)
}

/**
* Get/set video bitrate during a streaming in bps.
Expand All @@ -174,14 +171,14 @@ constructor(
*
* @return video bitrate in bps
*/
get() = streamer.settings.video.bitrate
get() = streamer.videoEncoder?.bitrate ?: 0
/**
* Set video bitrate.
*
* @param value video bitrate in bps
*/
set(value) {
streamer.settings.video.bitrate = value
streamer.videoEncoder?.bitrate = value
}

/**
Expand Down Expand Up @@ -250,17 +247,16 @@ constructor(
*
* @return [Boolean.true] if audio is muted, [Boolean.false] if audio is not muted.
*/
get() = streamer.settings.audio.isMuted
get() = streamer.audioSource?.isMuted ?: true
/**
* Set mute value.
*
* @param value [Boolean.true] to mute audio, [Boolean.false] to unmute audio.
*/
set(value) {
streamer.settings.audio.isMuted = value
streamer.audioSource?.isMuted = value
}


/**
* Set/get the zoom ratio.
*/
Expand All @@ -270,14 +266,14 @@ constructor(
*
* @return the zoom ratio
*/
get() = streamer.settings.camera.zoom.zoomRatio
get() = streamer.videoSource.settings.zoom.zoomRatio
/**
* Set the zoom ratio.
*
* @param value the zoom ratio
*/
set(value) {
streamer.settings.camera.zoom.zoomRatio = value
streamer.videoSource.settings.zoom.zoomRatio = value
}

/**
Expand All @@ -297,22 +293,15 @@ constructor(
require(audioConfig != null) { "Audio config must be set" }
require(videoConfig != null) { "Video config must be set" }

scope.launch {
withContext(context = Dispatchers.IO) {
try {
streamer.connect(url.addTrailingSlashIfNeeded() + streamKey)
try {
streamer.startStream()
_isStreaming = true
} catch (e: Exception) {
streamer.disconnect()
connectionListener.onConnectionFailed("$e")
throw e
}
} catch (e: Exception) {
Log.e(TAG, "Failed to start stream", e)
}
}
val descriptor = UriMediaDescriptor(url.addTrailingSlashIfNeeded() + streamKey)
require(descriptor.type.sinkType == MediaSinkType.RTMP) { "URL must be RTMP" }

try {
streamer.startStream(url)
} catch (e: Exception) {
streamer.close()
connectionListener.onConnectionFailed("$e")
throw e
}
}

Expand All @@ -322,25 +311,10 @@ constructor(
* @see [startStreaming]
*/
fun stopStreaming() {
val isConnected = streamer.isConnected
scope.launch {
withContext(context = Dispatchers.IO) {
streamer.stopStream()
streamer.disconnect()
if (isConnected) {
connectionListener.onDisconnect()
}
_isStreaming = false
}
}
streamer.stopStream()
streamer.close()
}


/**
* Hack for private setter of [isStreaming].
*/
private var _isStreaming: Boolean = false

/**
* Check the streaming state.
*
Expand All @@ -349,7 +323,7 @@ constructor(
* @see [stopStreaming]
*/
val isStreaming: Boolean
get() = _isStreaming
get() = streamer.isStreaming

/**
* Starts camera preview of [cameraPosition].
Expand Down Expand Up @@ -391,6 +365,5 @@ constructor(
*/
fun release() {
streamer.release()
scope.cancel()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,65 @@ package video.api.livestream

import android.content.Context
import android.media.MediaFormat
import io.github.thibaultbee.streampack.streamers.helpers.AudioStreamerConfigurationHelper
import io.github.thibaultbee.streampack.streamers.helpers.CameraStreamerConfigurationHelper
import io.github.thibaultbee.streampack.streamers.helpers.VideoCameraStreamerConfigurationHelper
import io.github.thibaultbee.streampack.utils.backCameraList
import io.github.thibaultbee.streampack.utils.cameraList
import io.github.thibaultbee.streampack.utils.frontCameraList
import io.github.thibaultbee.streampack.core.internal.endpoints.composites.CompositeEndpoint
import io.github.thibaultbee.streampack.core.internal.endpoints.composites.muxers.flv.FlvMuxerInfo
import io.github.thibaultbee.streampack.core.streamers.infos.AudioStreamerConfigurationInfo
import io.github.thibaultbee.streampack.core.streamers.infos.CameraStreamerConfigurationInfo
import io.github.thibaultbee.streampack.core.streamers.infos.VideoCameraStreamerConfigurationInfo
import io.github.thibaultbee.streampack.core.utils.extensions.backCameras
import io.github.thibaultbee.streampack.core.utils.extensions.cameras
import io.github.thibaultbee.streampack.core.utils.extensions.frontCameras

object ConfigurationHelper {
private val helper = CameraStreamerConfigurationHelper.flvHelper
private val helper =
CameraStreamerConfigurationInfo(CompositeEndpoint.EndpointInfo(FlvMuxerInfo))
val audio = AudioConfigurationHelper(helper.audio)
val video = VideoStreamerConfigurationHelper(helper.video)
}

class AudioConfigurationHelper(private val audioHelper: AudioStreamerConfigurationHelper) {
class AudioConfigurationHelper(private val audioInfo: AudioStreamerConfigurationInfo) {
/**
* Get supported bitrate range.
*
* @return bitrate range
*/
fun getSupportedBitrates() =
audioHelper.getSupportedBitrates(MediaFormat.MIMETYPE_AUDIO_AAC)
audioInfo.getSupportedBitrates(MediaFormat.MIMETYPE_AUDIO_AAC)

/**
* Get maximum supported number of channel by encoder.
*
* @return maximum number of channel supported by the encoder
*/
fun getSupportedInputChannelRange() =
audioHelper.getSupportedInputChannelRange(MediaFormat.MIMETYPE_AUDIO_AAC)
audioInfo.getSupportedInputChannelRange(MediaFormat.MIMETYPE_AUDIO_AAC)

/**
* Get audio supported sample rates.
*
* @return sample rates list in Hz.
*/
fun getSupportedSampleRates() =
audioHelper.getSupportedSampleRates(MediaFormat.MIMETYPE_AUDIO_AAC)
audioInfo.getSupportedSampleRates(MediaFormat.MIMETYPE_AUDIO_AAC)
}

class VideoStreamerConfigurationHelper(private val videoHelper: VideoCameraStreamerConfigurationHelper) {
class VideoStreamerConfigurationHelper(private val videoInfo: VideoCameraStreamerConfigurationInfo) {

/**
* Get supported bitrate range.
*
* @return bitrate range
*/
fun getSupportedBitrates() =
videoHelper.getSupportedBitrates(MediaFormat.MIMETYPE_VIDEO_AVC)
videoInfo.getSupportedBitrates(MediaFormat.MIMETYPE_VIDEO_AVC)

/**
* Get encoder supported resolutions range.
*
* @return pair that contains supported width ([Pair.first]) and supported height ([Pair.second]).
*/
fun getSupportedResolutions() =
videoHelper.getSupportedResolutions(MediaFormat.MIMETYPE_VIDEO_AVC)
videoInfo.getSupportedResolutions(MediaFormat.MIMETYPE_VIDEO_AVC)

/**
* Get camera supported resolutions that are also supported by the encoder.
Expand All @@ -66,7 +69,7 @@ class VideoStreamerConfigurationHelper(private val videoHelper: VideoCameraStrea
* @return list of resolutions
*/
fun getCameraSupportedResolutions(context: Context) =
videoHelper.getSupportedResolutions(context, MediaFormat.MIMETYPE_VIDEO_AVC)
videoInfo.getSupportedResolutions(context, MediaFormat.MIMETYPE_VIDEO_AVC)


/**
Expand All @@ -79,29 +82,29 @@ class VideoStreamerConfigurationHelper(private val videoHelper: VideoCameraStrea
fun getSupportedFrameRates(
context: Context,
cameraId: String
) = videoHelper.getSupportedFramerates(context, MediaFormat.MIMETYPE_VIDEO_AVC, cameraId)
) = videoInfo.getSupportedFramerates(context, MediaFormat.MIMETYPE_VIDEO_AVC, cameraId)

/**
* Get cameras list
*
* @param context application context
* @return list of camera
*/
fun getCamerasList(context: Context) = context.cameraList
fun getCamerasList(context: Context) = context.cameras

/**
* Get back cameras list
*
* @param context application context
* @return list of back camera
*/
fun getBackCamerasList(context: Context) = context.backCameraList
fun getBackCamerasList(context: Context) = context.backCameras

/**
* Get front cameras list
*
* @param context application context
* @return list of front camera
*/
fun getFrontCamerasList(context: Context) = context.frontCameraList
fun getFrontCamerasList(context: Context) = context.frontCameras
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package video.api.livestream.enums

import android.content.Context
import io.github.thibaultbee.streampack.utils.backCameraList
import io.github.thibaultbee.streampack.utils.frontCameraList
import io.github.thibaultbee.streampack.utils.isBackCamera
import io.github.thibaultbee.streampack.utils.isFrontCamera
import io.github.thibaultbee.streampack.core.utils.extensions.backCameras
import io.github.thibaultbee.streampack.core.utils.extensions.frontCameras
import io.github.thibaultbee.streampack.core.utils.extensions.isBackCamera
import io.github.thibaultbee.streampack.core.utils.extensions.isFrontCamera

/**
* Represents camera facing direction.
Expand All @@ -28,9 +28,9 @@ enum class CameraFacingDirection {
*/
fun toCameraId(context: Context): String {
val cameraList = if (this == BACK) {
context.backCameraList
context.backCameras
} else {
context.frontCameraList
context.frontCameras
}
return cameraList[0]
}
Expand Down
Loading

0 comments on commit 6c3f143

Please sign in to comment.