Component API Reference¶
This document provides detailed API reference for all major components in Gazer Mobile Stream Studio.
UsbCaptureManager¶
Manages USB device detection, connection, and permissions.
Class Definition¶
Public Interface¶
// Connection state observation
val connectionState: LiveData<ConnectionState>
val connectedDevice: LiveData<UsbDevice?>
// Device management
suspend fun requestPermission(device: UsbDevice): Boolean
suspend fun connectToDevice(device: UsbDevice): Result<Boolean>
fun disconnectDevice()
fun getCompatibleDevices(): List<UsbDevice>
// Device filtering
fun isCompatibleDevice(device: UsbDevice): Boolean
ConnectionState¶
sealed class ConnectionState {
object Disconnected : ConnectionState()
object Connecting : ConnectionState()
data class Connected(val device: UsbDevice) : ConnectionState()
data class Error(val message: String) : ConnectionState()
}
Usage Example¶
val usbManager = getSystemService(Context.USB_SERVICE) as UsbManager
val captureManager = UsbCaptureManager(this, usbManager)
// Observe connection state
captureManager.connectionState.observe(this) { state ->
when (state) {
is ConnectionState.Connected -> {
// Device connected, start video capture
}
is ConnectionState.Error -> {
// Handle connection error
}
}
}
// Connect to device
lifecycleScope.launch {
val devices = captureManager.getCompatibleDevices()
if (devices.isNotEmpty()) {
val result = captureManager.connectToDevice(devices.first())
// Handle connection result
}
}
UsbVideoCapture¶
Captures video frames from connected USB devices.
Class Definition¶
class UsbVideoCapture(
private val usbConnection: UsbDeviceConnection,
private val usbInterface: UsbInterface
)
Public Interface¶
// Video capture flow
val videoFrames: Flow<VideoFrame>
val captureState: StateFlow<CaptureState>
// Capture control
suspend fun startCapture(format: VideoFormat): Result<Boolean>
suspend fun stopCapture()
fun getSupportedFormats(): List<VideoFormat>
// Frame properties
val frameWidth: Int
val frameHeight: Int
val frameRate: Float
VideoFrame¶
data class VideoFrame(
val data: ByteArray,
val format: VideoFormat,
val width: Int,
val height: Int,
val timestamp: Long
)
VideoFormat¶
Usage Example¶
val videoCapture = UsbVideoCapture(connection, interface)
// Start capturing
lifecycleScope.launch {
val result = videoCapture.startCapture(VideoFormat.YUV420)
if (result.isSuccess) {
// Collect video frames
videoCapture.videoFrames.collect { frame ->
// Process video frame
processVideoFrame(frame)
}
}
}
VideoPreviewRenderer¶
Renders video frames to a SurfaceView for real-time preview.
Class Definition¶
Public Interface¶
// Rendering control
suspend fun startRendering(frameFlow: Flow<VideoFrame>)
fun stopRendering()
fun setAspectRatio(width: Int, height: Int)
// Rendering state
val isRendering: StateFlow<Boolean>
val renderingStats: Flow<RenderStats>
RenderStats¶
Usage Example¶
val surfaceView = findViewById<SurfaceView>(R.id.preview_surface)
val renderer = VideoPreviewRenderer(surfaceView)
// Start rendering video frames
lifecycleScope.launch {
renderer.startRendering(videoCapture.videoFrames)
}
// Monitor rendering performance
renderer.renderingStats.collect { stats ->
updateUI("FPS: ${stats.fps}, Dropped: ${stats.droppedFrames}")
}
CameraOverlayView¶
Manages camera overlay functionality with touch-based interaction.
Class Definition¶
class CameraOverlayView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr)
Public Interface¶
// Camera control
suspend fun startCamera(): Result<Boolean>
fun stopCamera()
val isCameraActive: StateFlow<Boolean>
// Overlay configuration
fun setPosition(position: OverlayPosition)
fun setSize(size: OverlaySize)
fun setVisibility(visible: Boolean)
// Touch interaction
var isDraggable: Boolean
var isResizable: Boolean
// Camera frames
val cameraFrames: Flow<Bitmap>
OverlayPosition¶
OverlaySize¶
enum class OverlaySize {
SMALL, // 15% of parent width
MEDIUM, // 25% of parent width
LARGE, // 35% of parent width
CUSTOM
}
Usage Example¶
val cameraOverlay = findViewById<CameraOverlayView>(R.id.camera_overlay)
// Configure overlay
cameraOverlay.setPosition(OverlayPosition.TOP_RIGHT)
cameraOverlay.setSize(OverlaySize.MEDIUM)
cameraOverlay.isDraggable = true
// Start camera
lifecycleScope.launch {
val result = cameraOverlay.startCamera()
if (result.isSuccess) {
// Camera overlay is now active
}
}
StreamCompositor¶
Combines USB video and camera overlay into a single video stream.
Class Definition¶
Public Interface¶
// Composition setup
fun setMainVideoSource(videoFlow: Flow<VideoFrame>)
fun setOverlaySource(overlayFlow: Flow<Bitmap>)
fun setOverlayConfiguration(config: OverlayConfig)
// Composite output
val compositeFrames: Flow<VideoFrame>
val compositionState: StateFlow<CompositionState>
// Composition control
suspend fun startComposition(): Result<Boolean>
fun stopComposition()
OverlayConfig¶
data class OverlayConfig(
val position: OverlayPosition,
val size: Size,
val opacity: Float = 1.0f,
val cornerRadius: Float = 0f
)
Usage Example¶
val compositor = StreamCompositor()
// Setup sources
compositor.setMainVideoSource(usbCapture.videoFrames)
compositor.setOverlaySource(cameraOverlay.cameraFrames)
// Configure overlay
val config = OverlayConfig(
position = OverlayPosition.TOP_RIGHT,
size = Size(320, 240),
opacity = 0.9f
)
compositor.setOverlayConfiguration(config)
// Start composition
lifecycleScope.launch {
compositor.startComposition()
compositor.compositeFrames.collect { frame ->
// Send to streaming
rtmpStreamer.encodeFrame(frame)
}
}
RtmpStreamer¶
Handles RTMP streaming and video encoding.
Class Definition¶
Public Interface¶
// Streaming configuration
data class StreamConfig(
val rtmpUrl: String,
val streamKey: String? = null,
val bitrate: Int,
val resolution: Resolution,
val fps: Int
)
// Streaming control
suspend fun startStreaming(config: StreamConfig): Result<Boolean>
suspend fun stopStreaming()
fun encodeFrame(frame: VideoFrame)
// Streaming state
val streamingState: StateFlow<StreamingState>
val streamingStats: Flow<StreamingStats>
StreamingState¶
sealed class StreamingState {
object Idle : StreamingState()
object Connecting : StreamingState()
object Streaming : StreamingState()
object Reconnecting : StreamingState()
data class Error(val message: String) : StreamingState()
}
StreamingStats¶
data class StreamingStats(
val bitrate: Int,
val fps: Float,
val droppedFrames: Int,
val connectionTime: Long
)
Usage Example¶
val rtmpStreamer = RtmpStreamer()
// Configure streaming
val config = StreamConfig(
rtmpUrl = "rtmp://live.twitch.tv/live/",
streamKey = "your_stream_key",
bitrate = 2500,
resolution = Resolution(1280, 720),
fps = 30
)
// Start streaming
lifecycleScope.launch {
val result = rtmpStreamer.startStreaming(config)
if (result.isSuccess) {
// Monitor streaming stats
rtmpStreamer.streamingStats.collect { stats ->
updateStreamingUI(stats)
}
}
}
MainActivity Integration¶
Example of how components work together in MainActivity:
Complete Setup¶
class MainActivity : AppCompatActivity() {
private lateinit var usbCaptureManager: UsbCaptureManager
private lateinit var videoRenderer: VideoPreviewRenderer
private lateinit var cameraOverlay: CameraOverlayView
private lateinit var streamCompositor: StreamCompositor
private lateinit var rtmpStreamer: RtmpStreamer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setupComponents()
observeStates()
}
private fun setupComponents() {
// Initialize all components
usbCaptureManager = UsbCaptureManager(this, usbManager)
videoRenderer = VideoPreviewRenderer(surfaceView)
cameraOverlay = findViewById(R.id.camera_overlay)
streamCompositor = StreamCompositor()
rtmpStreamer = RtmpStreamer()
// Connect components
lifecycleScope.launch {
// Setup video pipeline
usbCaptureManager.connectionState.collect { state ->
when (state) {
is ConnectionState.Connected -> {
setupVideoPipeline()
}
}
}
}
}
private suspend fun setupVideoPipeline() {
val videoCapture = UsbVideoCapture(connection, interface)
// Start video capture
videoCapture.startCapture(VideoFormat.YUV420)
// Setup preview
videoRenderer.startRendering(videoCapture.videoFrames)
// Setup composition
streamCompositor.setMainVideoSource(videoCapture.videoFrames)
streamCompositor.setOverlaySource(cameraOverlay.cameraFrames)
streamCompositor.startComposition()
// Setup streaming
streamCompositor.compositeFrames.collect { frame ->
rtmpStreamer.encodeFrame(frame)
}
}
}
This architecture provides a clean separation of concerns while maintaining efficient data flow and state management throughout the application.