Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(*): split in multiple host api #74

Merged
merged 1 commit into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,37 +1,61 @@
package video.api.flutter.livestream

import android.app.Activity
import android.content.Context
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.view.TextureRegistry
import video.api.flutter.livestream.generated.CameraInfoHostApi
import video.api.flutter.livestream.generated.CameraProviderHostApi
import video.api.flutter.livestream.generated.CameraSettingsHostApi
import video.api.flutter.livestream.generated.LiveStreamHostApi
import video.api.flutter.livestream.manager.InstanceManager
import video.api.flutter.livestream.manager.PermissionsManager


/** ApiVideoLiveStreamPlugin */
class ApiVideoLiveStreamPlugin : FlutterPlugin, ActivityAware {
private var pluginBinding: FlutterPluginBinding? = null
private var activityBinding: ActivityPluginBinding? = null

private val instanceManager = InstanceManager()

private var permissionsManager: PermissionsManager? = null
private var liveStreamHostApiImpl: LiveStreamHostApiImpl? = null
private var cameraProviderHostApiImpl: CameraProviderHostApiImpl? = null
private var cameraInfoHostApi: CameraInfoHostApiImpl? = null
private var cameraSettingsHostApiImpl: CameraSettingsHostApiImpl? = null

private fun setUp(
permissionsManager: PermissionsManager,
binaryMessenger: BinaryMessenger,
activity: Activity,
context: Context,
textureRegistry: TextureRegistry
) {
LiveStreamHostApiImpl(
activity,
instanceManager.context = context

liveStreamHostApiImpl = LiveStreamHostApiImpl(
instanceManager,
permissionsManager,
textureRegistry,
binaryMessenger
).apply {
LiveStreamHostApi.setUp(binaryMessenger, this)
liveStreamHostApiImpl = this
}

cameraProviderHostApiImpl = CameraProviderHostApiImpl(context).apply {
CameraProviderHostApi.setUp(binaryMessenger, this)
}

cameraInfoHostApi = CameraInfoHostApiImpl(context).apply {
CameraInfoHostApi.setUp(binaryMessenger, this)
}

cameraSettingsHostApiImpl = CameraSettingsHostApiImpl(instanceManager).apply {
CameraSettingsHostApi.setUp(binaryMessenger, this)
}
}

Expand Down Expand Up @@ -62,21 +86,30 @@ class ApiVideoLiveStreamPlugin : FlutterPlugin, ActivityAware {
activity,
pluginBinding.textureRegistry
)

updateActivity(activity)
}

override fun onDetachedFromActivityForConfigChanges() {
permissionsManager?.let {
it.activity = null
activityBinding?.removeRequestPermissionsResultListener(it)
}

updateContext(pluginBinding!!.applicationContext)
updateActivity(null)
}

override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
activityBinding = binding
val activity = binding.activity

val permissionsManager = requireNotNull(permissionsManager)
permissionsManager.activity = binding.activity
permissionsManager.activity = activity
binding.addRequestPermissionsResultListener(permissionsManager)

updateContext(activity)
updateActivity(activity)
}

override fun onDetachedFromActivity() {
Expand All @@ -85,6 +118,19 @@ class ApiVideoLiveStreamPlugin : FlutterPlugin, ActivityAware {
activityBinding?.removeRequestPermissionsResultListener(it)
}

updateContext(pluginBinding!!.applicationContext)
updateActivity(null)
activityBinding = null
}

fun updateActivity(activity: Activity?) {

}

fun updateContext(context: Context) {
instanceManager.context = context

cameraProviderHostApiImpl?.context = context
cameraInfoHostApi?.context = context
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package video.api.flutter.livestream

import android.content.Context
import android.hardware.camera2.CameraCharacteristics
import android.os.Build
import android.util.Range
import io.github.thibaultbee.streampack.utils.Zoom.Companion.DEFAULT_ZOOM_RATIO
import io.github.thibaultbee.streampack.utils.getCameraCharacteristics
import io.github.thibaultbee.streampack.utils.getScalerMaxZoom
import io.github.thibaultbee.streampack.utils.getZoomRatioRange
import io.github.thibaultbee.streampack.utils.isBackCamera
import io.github.thibaultbee.streampack.utils.isExternalCamera
import io.github.thibaultbee.streampack.utils.isFrontCamera
import video.api.flutter.livestream.generated.CameraInfoHostApi
import video.api.flutter.livestream.generated.NativeCameraLensDirection

class CameraInfoHostApiImpl(
var context: Context
) : CameraInfoHostApi {
override fun getSensorRotationDegrees(cameraId: String): Long {
val characteristics = context.getCameraCharacteristics(cameraId)
return (characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0).toLong()
}

override fun getLensDirection(cameraId: String): NativeCameraLensDirection {
return when {
context.isFrontCamera(cameraId) -> NativeCameraLensDirection.FRONT
context.isBackCamera(cameraId) -> NativeCameraLensDirection.BACK
context.isExternalCamera(cameraId) -> NativeCameraLensDirection.OTHER
else -> throw IllegalArgumentException("Invalid camera position for camera $cameraId")
}
}

private fun getZoomRange(cameraId: String): Range<Float> {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
context.getZoomRatioRange(cameraId)!!
} else {
Range(
DEFAULT_ZOOM_RATIO,
context.getScalerMaxZoom(cameraId)
)
}
}

override fun getMinZoomRatio(cameraId: String) = getZoomRange(cameraId).lower.toDouble()

override fun getMaxZoomRatio(cameraId: String) =
getZoomRange(cameraId).upper.toDouble()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package video.api.flutter.livestream

import android.content.Context
import io.github.thibaultbee.streampack.utils.cameraList
import video.api.flutter.livestream.generated.CameraProviderHostApi

class CameraProviderHostApiImpl(
var context: Context
) : CameraProviderHostApi {
override fun getAvailableCameraIds(): List<String> {
return context.cameraList
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package video.api.flutter.livestream

import io.github.thibaultbee.streampack.utils.CameraSettings
import video.api.flutter.livestream.generated.CameraSettingsHostApi
import video.api.flutter.livestream.manager.InstanceManager

class CameraSettingsHostApiImpl(
private val instanceManager: InstanceManager
) :
CameraSettingsHostApi {
private val settings: CameraSettings
get() = instanceManager.getInstance().settings.camera

override fun setZoomRatio(zoomRatio: Double) {
settings.zoom.zoomRatio = zoomRatio.toFloat()
}

override fun getZoomRatio(): Double {
return settings.zoom.zoomRatio.toDouble()
}
}
Original file line number Diff line number Diff line change
@@ -1,52 +1,48 @@
package video.api.flutter.livestream

import android.content.Context
import android.os.Handler
import android.os.Looper
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.view.TextureRegistry
import io.github.thibaultbee.streampack.utils.backCameraList
import io.github.thibaultbee.streampack.utils.externalCameraList
import io.github.thibaultbee.streampack.utils.frontCameraList
import io.github.thibaultbee.streampack.utils.isBackCamera
import io.github.thibaultbee.streampack.utils.isExternalCamera
import io.github.thibaultbee.streampack.utils.isFrontCamera
import video.api.flutter.livestream.generated.CameraPosition
import video.api.flutter.livestream.generated.LiveStreamFlutterApi
import video.api.flutter.livestream.generated.LiveStreamHostApi
import video.api.flutter.livestream.generated.NativeAudioConfig
import video.api.flutter.livestream.generated.NativeResolution
import video.api.flutter.livestream.generated.NativeVideoConfig
import video.api.flutter.livestream.manager.InstanceManager
import video.api.flutter.livestream.manager.LiveStreamViewManager
import video.api.flutter.livestream.manager.PermissionsManager
import video.api.flutter.livestream.utils.addTrailingSlashIfNeeded
import video.api.flutter.livestream.utils.toAudioConfig
import video.api.flutter.livestream.utils.toNativeResolution
import video.api.flutter.livestream.utils.toVideoConfig

fun LiveStreamHostApiImpl(
context: Context,
instanceManager: InstanceManager,
permissionsManager: PermissionsManager,
textureRegistry: TextureRegistry,
binaryMessenger: BinaryMessenger,
) = LiveStreamHostApiImpl(
context,
instanceManager,
permissionsManager,
textureRegistry,
LiveStreamFlutterApi(binaryMessenger)
)

class LiveStreamHostApiImpl(
private val context: Context,
private val instanceManager: InstanceManager,
private val permissionsManager: PermissionsManager,
private val textureRegistry: TextureRegistry,
private val liveStreamFlutterApi: LiveStreamFlutterApi,
) : LiveStreamHostApi {
private var flutterView: FlutterLiveStreamView? = null
private var flutterView: LiveStreamViewManager? = null
private val mainHandler = Handler(Looper.getMainLooper())

override fun create(): Long {
flutterView?.dispose()
flutterView = FlutterLiveStreamView(
context,
instanceManager.dispose()
flutterView = LiveStreamViewManager(
instanceManager.getInstance(),
textureRegistry,
permissionsManager,
{ executeOnMain { liveStreamFlutterApi.onIsConnectedChanged(true) {} } },
Expand Down Expand Up @@ -106,23 +102,12 @@ class LiveStreamHostApiImpl(
return flutterView!!.isStreaming
}

override fun getCameraPosition(): CameraPosition {
val camera = flutterView!!.camera
return when {
context.isFrontCamera(camera) -> CameraPosition.FRONT
context.isBackCamera(camera) -> CameraPosition.BACK
context.isExternalCamera(camera) -> CameraPosition.OTHER
else -> throw IllegalArgumentException("Invalid camera position for camera $camera")
}
override fun getCameraId(): String {
return flutterView!!.camera
}

override fun setCameraPosition(position: CameraPosition, callback: (Result<Unit>) -> Unit) {
val cameraList = when (position) {
CameraPosition.FRONT -> context.frontCameraList
CameraPosition.BACK -> context.backCameraList
CameraPosition.OTHER -> context.externalCameraList
}
flutterView!!.setCamera(cameraList.first(),
override fun setCameraId(cameraId: String, callback: (Result<Unit>) -> Unit) {
flutterView!!.setCamera(cameraId,
{ callback(Result.success(Unit)) },
{ callback(Result.failure(it)) })
}
Expand All @@ -139,18 +124,6 @@ class LiveStreamHostApiImpl(
return flutterView!!.videoConfig.resolution.toNativeResolution()
}

override fun setZoomRatio(zoomRatio: Double) {
flutterView!!.zoomRatio = zoomRatio.toFloat()
}

override fun getZoomRatio(): Double {
return flutterView!!.zoomRatio.toDouble()
}

override fun getMaxZoomRatio(): Double {
return flutterView!!.maxZoomRatio.toDouble()
}

private fun executeOnMain(block: () -> Unit) {
mainHandler.post {
block()
Expand Down
Loading
Loading