-
Notifications
You must be signed in to change notification settings - Fork 746
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
Screen sharing over WebRTC #5911
Conversation
onurays
commented
May 3, 2022
•
edited
Loading
edited
- Start a video call between 2 or more devices
- Once the call is connected tap the menu icon (...)
- You should see the "Start sharing screen" option, select it
- A system permission dialog should appear, accept it
- Your screen will be streamed to other devices (in ~5 seconds)
- A sticky push notification should appear for Android 10 or later versions
- "Start sharing screen" button should turn to "Stop sharing screen"
private fun startScreenSharing(activityResult: ActivityResult) { | ||
val videoCapturer = ScreenCapturerAndroid(activityResult.data, object : MediaProjection.Callback() { | ||
override fun onStop() { | ||
Timber.v("User revoked the screen capturing permission") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're keeping this in production I would make this Timber.i
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Yes, we have to implement this dummy callback.
val factory = peerConnectionFactoryProvider.get() ?: return | ||
|
||
this.videoCapturer = videoCapturer | ||
|
||
val localMediaStream = factory.createLocalMediaStream(STREAM_ID) | ||
val videoSource = factory.createVideoSource(videoCapturer.isScreencast) | ||
|
||
// Start capturing screen | ||
val surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", rootEglBase!!.eglBaseContext) | ||
videoCapturer.initialize(surfaceTextureHelper, context, videoSource.capturerObserver) | ||
videoCapturer.startCapture(currentCaptureFormat.width, currentCaptureFormat.height, currentCaptureFormat.fps) | ||
|
||
// Remove local camera previews | ||
localSurfaceRenderers.forEach { it.get()?.let { localVideoTrack?.removeSink(it) } } | ||
|
||
// Show screen preview locally | ||
localVideoTrack = factory.createVideoTrack(VIDEO_TRACK_ID, videoSource).apply { setEnabled(true) } | ||
localMediaStream?.addTrack(localVideoTrack) | ||
localSurfaceRenderers.forEach { it.get()?.let { localVideoTrack?.addSink(it) } } | ||
|
||
// Remove camera stream | ||
peerConnection?.removeTrack(videoSender) | ||
|
||
screenSender = peerConnection?.addTrack(localVideoTrack, listOf(STREAM_ID)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each of these "regions" (as separated by the comments) can be made more readable by each being their own private function. This method can then read like a story without any comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. This class needs refactoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When testing on a real device (Nokia 7.2, Android 11), it seems the sharing is not working. I click on share screen then I see a dialog saying I will share all the content of my screen. And then I see a notification saying a screen sharing is running. But the sharing option stays with "Share my screen" and not "Stop sharing" like I would expect. And I don't see the share on Web. It seems like it does not transfer the video stream.
Also, could you please add a bit more of context and explanation in the PR description (for example how to test, to see what is expected).
@@ -147,6 +147,7 @@ class VectorCallViewModel @AssistedInject constructor( | |||
setState { copy(otherKnownCallInfo = null) } | |||
} | |||
} | |||
_viewEvents.post(VectorCallViewEvents.StopScreenSharingService) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I think the set of the isSharingScreen
to false in the state is missing. Maybe we should reuse an mutualize what is done in handleToggleScreenSharing()
when screen is shared:
if (isSharingScreen) {
call?.stopSharingScreen()
setState {
copy(isSharingScreen = false)
}
_viewEvents.post(VectorCallViewEvents.StopScreenSharingService)
}
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, although we finish the call activity as soon as the call ended.
private var callback: Callback? = null | ||
|
||
fun bind(callback: Callback) { | ||
this.callback = callback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to reset the callback to null
when unbound to the service in onServiceDisconnected
for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, done.
@@ -770,12 +775,49 @@ class WebRtcCall( | |||
return currentCaptureFormat | |||
} | |||
|
|||
fun startSharingScreen() { | |||
// TODO. Will be handled within the next PR. | |||
fun startSharingScreen(videoCapturer: VideoCapturer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tried to extract the screen sharing capabilities into a dedicated component to avoid adding new responsabilities to WebRtcCall
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it is easily possible. This class has many local fields. We will start implementing Element Call soon, so we probably won't invest in this class more.
Thank you for testing by turning off the camera :) I will fix this. |
I tested again with physical device (Android 11, Nokia 7.2), here is what I discovered:
|
Proximity sensor issue is a good catch and fixed. Second one seems the responsibility of web, because we stop sending streams. |
Thanks for fixing the proximity sensor issue, it is okay now. I discovered a new thing:
|
Matrix SDKIntegration Tests Results:
|