You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -115,6 +115,7 @@ Video roadmap and changelog is available [here](https://github.com/GetStream/pro
115
115
116
116
### 0.4.0 milestone
117
117
118
+
-[X] Screensharing from mobile
118
119
-[ ] Complete Livestreaming APIs and Tutorials for hosting & watching
119
120
-[ ] Android SDK development.md cleanup (Daniel)
120
121
-[ ] Upgrade to more recent versions of webrtc (Kanat)
@@ -131,7 +132,6 @@ Video roadmap and changelog is available [here](https://github.com/GetStream/pro
131
132
132
133
-[ ] Testing on more devices
133
134
-[ ] Enable SFU switching
134
-
-[ ] Screensharing from mobile
135
135
-[ ] Camera controls
136
136
-[ ] Tap to focus
137
137
-[ ] H264 workaround on Samsung 23 (see https://github.com/livekit/client-sdk-android/blob/main/livekit-android-sdk/src/main/java/io/livekit/android/webrtc/SimulcastVideoEncoderFactoryWrapper.kt#L34 and
The Stream Video Android SDK has support for screen sharing from an Android device. The SDK is using the [Android Media Projection API](https://developer.android.com/guide/topics/large-screens/media-projection) for the capture.
9
+
10
+
In order for a user to be able to share their screen, they must have the `screenshare` capability configured for the call they are in.
11
+
12
+
## How to start sharing your screen
13
+
14
+
You need to be in an active call (have a `Call` instance in Active call state) to start screen sharing.
15
+
16
+
You must ask the user for screen sharing permission before you can start sharing the screen. The permission is requested by using the [Media Projection API](https://developer.android.com/guide/topics/large-screens/media-projection). And then use the returned intent data from the permission result and call `Call.startScreenSharing(intentData)`.
17
+
18
+
An example implementation:
19
+
20
+
```kotlin
21
+
val startMediaProjection = registerForActivityResult(StartActivityForResult()) { result ->
22
+
if (it.resultCode ==Activity.RESULT_OK&& it.data !=null) {
23
+
call.startScreenSharing(it.data!!)
24
+
}
25
+
}
26
+
27
+
val mediaProjectionManager = context.getSystemService(MediaProjectionManager::class.java)
You can check if screen sharing is currently active by observing `call.screenShare.isEnabled`.
32
+
33
+
## Stopping screen sharing
34
+
35
+
Screen sharing can be stopped wit `Call.stopScreenSharing()`. It is automatically stopped if the call state goes into Inactive state.
36
+
37
+
The user can also disable screen sharing directly in the system settings (depending on the OEM there is usually a button in the notification bar for disabling screen sharing).
38
+
39
+
And the screen sharing can also be disabled through the screen sharing notification action button (described in next section).
40
+
41
+
## Screen sharing notification
42
+
43
+
A notification is always displayed to the user when the screen sharing is active. The notification itself can't be hidden and is required by the Android OS. The notification title and description can be customised.
44
+
45
+
Override string `stream_video_screen_sharing_notification_title` and `stream_video_screen_sharing_notification_description` to customise the notification text.
46
+
47
+
There is also a "Stop screen sharing" action button on the notification, the text of the button can be modified by overriding `stream_video_screen_sharing_notification_action_stop`.
48
+
49
+
All notifications in Android need to have a notification channel. The Stream Video Android SDK will automatically create a new channel for the screen sharing notification. You can customise the channel title and description (this is visible to the user in the system application settings). Override `stream_video_screen_sharing_notification_channel_title` and `stream_video_screen_sharing_notification_channel_description`.
50
+
51
+
```xml
52
+
<stringname="stream_video_screen_sharing_notification_title">You are screen sharing</string>
Copy file name to clipboardExpand all lines: stream-video-android-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/activecall/CallContent.kt
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -212,7 +212,7 @@ internal fun DefaultPictureInPictureContent(call: Call) {
212
212
val video = session?.participant?.video?.collectAsStateWithLifecycle()
213
213
val pictureInPictureAspectRatio:Float=16f/9f
214
214
215
-
if (session !=null) {
215
+
if (session !=null&&!session.participant.isLocal) {
Copy file name to clipboardExpand all lines: stream-video-android-compose/src/main/kotlin/io/getstream/video/android/compose/ui/components/call/renderer/ParticipantsGrid.kt
+2-1Lines changed: 2 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -69,7 +69,8 @@ public fun ParticipantsGrid(
69
69
val screenSharingSession = call.state.screenSharingSession.collectAsStateWithLifecycle()
70
70
val screenSharing = screenSharingSession.value
71
71
72
-
if (screenSharing ==null) {
72
+
// We do not display our own screen-sharing session
73
+
if (screenSharing ==null|| screenSharing.participant.isLocal) {
Copy file name to clipboardExpand all lines: stream-video-android-core/api/stream-video-android-core.api
+23-1Lines changed: 23 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -15,6 +15,7 @@ public final class io/getstream/video/android/core/Call {
15
15
public final fun getLocalMicrophoneAudioLevel ()Lkotlinx/coroutines/flow/StateFlow;
16
16
public final fun getMicrophone ()Lio/getstream/video/android/core/MicrophoneManager;
17
17
public final fun getMonitor ()Lio/getstream/video/android/core/CallHealthMonitor;
18
+
public final fun getScreenShare ()Lio/getstream/video/android/core/ScreenShareManager;
18
19
public final fun getSessionId ()Ljava/lang/String;
19
20
public final fun getSpeaker ()Lio/getstream/video/android/core/SpeakerManager;
20
21
public final fun getState ()Lio/getstream/video/android/core/CallState;
@@ -51,9 +52,11 @@ public final class io/getstream/video/android/core/Call {
51
52
public final fun setVisibility (Ljava/lang/String;Lstream/video/sfu/models/TrackType;Z)V
52
53
public final fun startHLS (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
53
54
public final fun startRecording (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
55
+
public final fun startScreenSharing (Landroid/content/Intent;)V
54
56
public final fun stopHLS (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
55
57
public final fun stopLive (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
56
58
public final fun stopRecording (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
59
+
public final fun stopScreenSharing ()V
57
60
public final fun subscribe (Lio/getstream/video/android/core/events/VideoEventListener;)Lio/getstream/video/android/core/EventSubscription;
58
61
public final fun subscribeFor ([Ljava/lang/Class;Lio/getstream/video/android/core/events/VideoEventListener;)Lio/getstream/video/android/core/EventSubscription;
59
62
public final fun switchSfu (ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
@@ -392,6 +395,8 @@ public final class io/getstream/video/android/core/MediaManagerImpl {
392
395
public final fun getContext ()Landroid/content/Context;
393
396
public final fun getEglBaseContext ()Lorg/webrtc/EglBase$Context;
394
397
public final fun getScope ()Lkotlinx/coroutines/CoroutineScope;
398
+
public final fun getScreenShareTrack ()Lorg/webrtc/VideoTrack;
399
+
public final fun getScreenShareVideoSource ()Lorg/webrtc/VideoSource;
395
400
public final fun getVideoSource ()Lorg/webrtc/VideoSource;
396
401
public final fun getVideoTrack ()Lorg/webrtc/VideoTrack;
397
402
}
@@ -663,6 +668,22 @@ public final class io/getstream/video/android/core/RingingState$TimeoutNoAnswer
663
668
public fun toString ()Ljava/lang/String;
664
669
}
665
670
671
+
public final class io/getstream/video/android/core/ScreenShareManager {
672
+
public static final field Companion Lio/getstream/video/android/core/ScreenShareManager$Companion;
673
+
public fun <init> (Lio/getstream/video/android/core/MediaManagerImpl;Lorg/webrtc/EglBase$Context;)V
674
+
public final fun disable (Z)V
675
+
public static synthetic fun disable$default (Lio/getstream/video/android/core/ScreenShareManager;ZILjava/lang/Object;)V
676
+
public final fun enable (Landroid/content/Intent;Z)V
677
+
public static synthetic fun enable$default (Lio/getstream/video/android/core/ScreenShareManager;Landroid/content/Intent;ZILjava/lang/Object;)V
678
+
public final fun getEglBaseContext ()Lorg/webrtc/EglBase$Context;
679
+
public final fun getMediaManager ()Lio/getstream/video/android/core/MediaManagerImpl;
680
+
public final fun getStatus ()Lkotlinx/coroutines/flow/StateFlow;
681
+
public final fun isEnabled ()Lkotlinx/coroutines/flow/StateFlow;
682
+
}
683
+
684
+
public final class io/getstream/video/android/core/ScreenShareManager$Companion {
685
+
}
686
+
666
687
public final class io/getstream/video/android/core/SpeakerManager {
667
688
public fun <init> (Lio/getstream/video/android/core/MediaManagerImpl;Lio/getstream/video/android/core/MicrophoneManager;Ljava/lang/Integer;)V
668
689
public synthetic fun <init> (Lio/getstream/video/android/core/MediaManagerImpl;Lio/getstream/video/android/core/MicrophoneManager;Ljava/lang/Integer;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
@@ -874,6 +895,7 @@ public final class io/getstream/video/android/core/call/RtcSession {
874
895
public final fun reconnect (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
875
896
public final fun setLocalTrack (Lstream/video/sfu/models/TrackType;Lio/getstream/video/android/core/model/MediaTrack;)V
876
897
public final fun setMuteState (ZLstream/video/sfu/models/TrackType;)V
898
+
public final fun setScreenShareTrack ()V
877
899
public final fun setSubscriber (Lio/getstream/video/android/core/call/connection/StreamPeerConnection;)V
878
900
public final fun setTrack (Ljava/lang/String;Lstream/video/sfu/models/TrackType;Lio/getstream/video/android/core/model/MediaTrack;)V
879
901
public final fun setTracks (Ljava/util/Map;)V
@@ -902,7 +924,7 @@ public final class io/getstream/video/android/core/call/connection/StreamPeerCon
902
924
public fun <init> (Lkotlinx/coroutines/CoroutineScope;Lio/getstream/video/android/core/model/StreamPeerType;Lorg/webrtc/MediaConstraints;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;I)V
903
925
public final fun addAudioTransceiver (Lorg/webrtc/MediaStreamTrack;Ljava/util/List;)V
904
926
public final fun addIceCandidate (Lio/getstream/video/android/core/model/IceCandidate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
905
-
public final fun addVideoTransceiver (Lorg/webrtc/MediaStreamTrack;Ljava/util/List;)V
927
+
public final fun addVideoTransceiver (Lorg/webrtc/MediaStreamTrack;Ljava/util/List;Z)V
906
928
public final fun createAnswer (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
907
929
public final fun createOffer (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
908
930
public final fun getAudioTransceiver ()Lorg/webrtc/RtpTransceiver;
0 commit comments