Developer Notes (3.0.11)
  • 17 Oct 2024
  • 3 Minutes à lire
  • Sombre
    Lumière
  • PDF

Developer Notes (3.0.11)

  • Sombre
    Lumière
  • PDF

The content is currently unavailable in French. You are viewing the default English version.
Résumé de l’article

Version 3.0.11 of the ScreenMeet SDK for Android introduces several new features.  They are discussed on this page.

API Changes

SessionEventListener

Several methods in SessionEventListener have updated their signatures. The return type has changed from Unit to Boolean, which determines whether the SDK should handle the event or if the client application has consumed it. This primarily affects UI-related events.

  • true: Indicates that the event has been handled by the developer and should not be further dispatched by the SDK.

  • false: Indicates that the event was not handled and the SDK should process it.

Developers can attach multiple SessionEventListener instances. An event is considered consumed if any of the listeners returns true.

Methods with Signature Changes

// Before
fun onFeatureRequest(feature: Feature, decisionHandler: (granted: Boolean) -> Unit)

// After
fun onFeatureRequest(feature: Feature, decisionHandler: (granted: Boolean) -> Unit): Boolean


// Before
fun onFeatureRequestRejected(entitlement: Entitlement)

// After
fun onFeatureRequestRejected(entitlement: Entitlement): Boolean


// Before
fun onScreenShareRequest(participant: Participant)

// After
fun onScreenShareRequest(participant: Participant): Boolean

New Method Added

fun onRemoteControlCommand(command: RemoteControlCommand): Boolean

Code Sample

Override Remote Control Events Added the ability to override Remote Control events using the SessionEventListener method onRemoteControlCommand:

private var areaNotClickableRemotely: Rect? = null

val rect = Rect()  
notClickableView.getGlobalVisibleRect(rect)  
areaNotClickableRemotely = rect

override fun onRemoteControlCommand(command: RemoteControlCommand): Boolean {  
	if (command is RemoteControlCommand.Mouse) {  
		// If the click occurs in a non-clickable area, return true.  
		// This indicates that the event has been handled and should not be 
		// further dispatched.        
		return areaNotClickableRemotely?.contains(command.x, command.y) == true  
	}  
	return false  
}

ScreenMeet.Configuration

A new method has been added:

fun preferredScreenCaptureFps(fps: Int): Configuration

Code Sample

Preferred Application Frame Capturing FPS Exposed an API to specify the preferred application frame capturing FPS. This can help tune video stream performance and reduce CPU usage. The default FPS is 24.

val configuration = Configuration(apiKey)  
configuration.preferredScreenCaptureFps(15)

Other Enhancements

  • Mouse Scroll Support for Remote Control Added support for mouse scroll events in Remote Control.

  • Synchronized Frame Rendering Introduced the ability to synchronize frame rendering between SurfaceView, TextureView, GLSurfaceView, and regular View. Previously, different Surface instances might overlap View elements during frame rendering. Setting a higher zIndex for the View than the Surface resolves this issue.

    view.z = 1f
  • Updated Sample App Updated the Sample App with an example demonstrating how to handle a mismatch between the local VideoTrack preview and the remote stream. The key point is that SurfaceViewRenderer should be resized to match the video's aspect ratio.

    binding.renderer.init(  
        eglBase,  
        object : RendererCommon.RendererEvents {  
            override fun onFrameResolutionChanged(  
                videoWidth: Int,  
                videoHeight: Int,  
                rotation: Int  
            ) {  
                binding.renderer.post {  
                    binding.renderer.layoutParams = fitFrame(  
                        videoWidth,  
                        videoHeight,  
                        binding.root.width,  
                        binding.root.height  
                    )  
                }  
            }  
      
            override fun onFirstFrameRendered() {  
    
            }  
        }  
    )
    
    private fun fitFrame(  
        videoWidth: Int,  
        videoHeight: Int,  
        containerWidth: Int,  
        containerHeight: Int  
    ): FrameLayout.LayoutParams {  
        val videoAspect = videoWidth.toFloat() / videoHeight  
        val containerAspect = containerWidth.toFloat() / containerHeight  
      
        val newWidth: Int  
        val newHeight: Int  
      
        if (videoAspect > containerAspect) {  
            newWidth = containerWidth  
            newHeight = (containerWidth / videoAspect).toInt()  
        } else {  
            newHeight = containerHeight  
            newWidth = (containerHeight * videoAspect).toInt()  
        }  
      
        val offsetX = (containerWidth - newWidth) / 2  
        val offsetY = (containerHeight - newHeight) / 2  
      
        return FrameLayout.LayoutParams(newWidth, newHeight).apply {  
            setMargins(offsetX, offsetY, 0, 0)  
        }  
    }
    
    

Thank you for using our SDK! If you have any questions or feedback, please reach out to our support team.


Cet article vous a-t-il été utile ?