Skip to content
Open
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
Expand Up @@ -64,6 +64,11 @@ interface IVideoInput : ISnapshotable {
*/
val sourceFlow: StateFlow<IVideoSource?>

/**
* The video source configuration
*/
val sourceConfigFlow: StateFlow<VideoSourceConfig?>

/**
* Mute the video stream.
* The video stream will be replaced by a black screen.
Expand Down Expand Up @@ -131,6 +136,9 @@ internal class VideoInput(
*/
override val sourceFlow: StateFlow<IVideoSource?> = sourceInternalFlow.asStateFlow()

/**
* The video source configuration
*/
private val source: IVideoSourceInternal?
get() = sourceInternalFlow.value

Expand All @@ -140,7 +148,7 @@ internal class VideoInput(
/**
* The video source configuration.
*/
val sourceConfigFlow = _sourceConfigFlow.asStateFlow()
override val sourceConfigFlow = _sourceConfigFlow.asStateFlow()

private val sourceConfig: VideoSourceConfig?
get() = sourceConfigFlow.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import io.github.thibaultbee.streampack.core.elements.sources.video.camera.Camer
import io.github.thibaultbee.streampack.core.elements.sources.video.camera.ICameraSource
import io.github.thibaultbee.streampack.core.elements.sources.video.camera.extensions.getCameraCharacteristics
import io.github.thibaultbee.streampack.core.elements.utils.ConflatedJob
import io.github.thibaultbee.streampack.core.elements.utils.extensions.rotateFromNaturalOrientation
import io.github.thibaultbee.streampack.core.elements.utils.OrientationUtils
import io.github.thibaultbee.streampack.core.elements.utils.extensions.runningHistoryNotNull
import io.github.thibaultbee.streampack.core.interfaces.IWithVideoSource
Expand All @@ -52,6 +53,8 @@ import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
Expand Down Expand Up @@ -114,6 +117,18 @@ class PreviewView @JvmOverloads constructor(
/**
* The [PreviewListener] to listen to specific view events.
*/
/**
* If true, it uses the video source configuration resolution for the preview.
* Default is true.
*/
var matchVideoConfig: Boolean = true
set(value) {
if (field != value) {
field = value
attachToStreamerIfReady(false)
}
}

var listener: PreviewListener? = null

private var zoomListener: CameraSettings.Zoom.OnZoomChangedListener? = null
Expand All @@ -130,6 +145,7 @@ class PreviewView @JvmOverloads constructor(
CoroutineScope(defaultDispatcher + SupervisorJob() + CoroutineName("preview"))
private var startPreviewJob = ConflatedJob()
private var sourceJob = ConflatedJob()
private var sourceConfigJob = ConflatedJob()

private var streamer: IWithVideoSource? = null
private val streamerMutex = Mutex()
Expand Down Expand Up @@ -190,6 +206,17 @@ class PreviewView @JvmOverloads constructor(
}
}
}

sourceConfigJob += defaultScope.launch {
streamer.videoInput.sourceConfigFlow
.map { it?.resolution }
.distinctUntilChanged()
.collect {
if (matchVideoConfig) {
attachToStreamerIfReady(true)
}
}
}
}

/**
Expand Down Expand Up @@ -266,6 +293,7 @@ class PreviewView @JvmOverloads constructor(
collectSource(newStreamer)
} else {
sourceJob.cancel()
sourceConfigJob.cancel()
}
}
}
Expand All @@ -274,7 +302,15 @@ class PreviewView @JvmOverloads constructor(
private fun attachToStreamerIfReady(shouldFailSilently: Boolean) {
if (streamer != null && isAttachedToWindow) {
try {
startPreview(size)
val config = streamer?.videoInput?.sourceConfigFlow?.value
Logger.e(TAG, "Resolution = ${config?.resolution}")
startPreview(
if (matchVideoConfig) {
config?.resolution ?: size
} else {
size
}
)
} catch (t: Throwable) {
if (shouldFailSilently) {
// Swallow the exception and fail silently if the method is invoked by View
Expand Down
1 change: 1 addition & 0 deletions ui/ui/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
<attr name="enableTapToFocus" format="boolean" />
<attr name="scaleMode" />
<attr name="position" />
<attr name="matchVideoConfig" format="boolean" />
</declare-styleable>
</resources>
Loading