Skip to content

Commit 8c67f3e

Browse files
committed
Merge branch 'develop'
2 parents ebcdea7 + 6523eb6 commit 8c67f3e

File tree

25 files changed

+740
-88
lines changed

25 files changed

+740
-88
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ Video roadmap and changelog is available [here](https://github.com/GetStream/pro
115115

116116
### 0.4.0 milestone
117117

118+
- [X] Screensharing from mobile
118119
- [ ] Complete Livestreaming APIs and Tutorials for hosting & watching
119120
- [ ] Android SDK development.md cleanup (Daniel)
120121
- [ ] Upgrade to more recent versions of webrtc (Kanat)
@@ -131,7 +132,6 @@ Video roadmap and changelog is available [here](https://github.com/GetStream/pro
131132

132133
- [ ] Testing on more devices
133134
- [ ] Enable SFU switching
134-
- [ ] Screensharing from mobile
135135
- [ ] Camera controls
136136
- [ ] Tap to focus
137137
- [ ] 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

buildSrc/src/main/kotlin/io/getstream/video/android/Configuration.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ object Configuration {
66
const val minSdk = 24
77
const val majorVersion = 0
88
const val minorVersion = 3
9-
const val patchVersion = 2
9+
const val patchVersion = 3
1010
const val versionName = "$majorVersion.$minorVersion.$patchVersion"
11-
const val versionCode = 7
11+
const val versionCode = 8
1212
const val snapshotVersionName = "$majorVersion.$minorVersion.${patchVersion + 1}-SNAPSHOT"
1313
const val artifactGroup = "io.getstream"
1414
const val streamVideoCallGooglePlayVersion = "1.0.0"

docusaurus/docs/Android/02-tutorials/01-video-calling.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ If you're new to android, note that there are 2 `build.gradle` files, you want t
3131
```kotlin
3232
dependencies {
3333
// Stream Video Compose SDK
34-
implementation("io.getstream:stream-video-android-compose:0.3.2")
34+
implementation("io.getstream:stream-video-android-compose:0.3.3")
3535

3636
// Optionally add Jetpack Compose if Android studio didn't automatically include them
3737
implementation(platform("androidx.compose:compose-bom:2023.08.00"))

docusaurus/docs/Android/02-tutorials/02-audio-room.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ If you're new to android, note that there are 2 `build.gradle` files, you want t
3535
```groovy
3636
dependencies {
3737
// Stream Video Compose SDK
38-
implementation("io.getstream:stream-video-android-compose:0.3.2")
38+
implementation("io.getstream:stream-video-android-compose:0.3.3")
3939
4040
// Jetpack Compose (optional/ android studio typically adds them when you create a new project)
4141
implementation(platform("androidx.compose:compose-bom:2023.08.00"))

docusaurus/docs/Android/02-tutorials/03-livestream.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ If you're new to android, note that there are 2 `build.gradle` files, you want t
3535
```kotlin
3636
dependencies {
3737
// Stream Video Compose SDK
38-
implementation("io.getstream:stream-video-android-compose:0.3.2")
38+
implementation("io.getstream:stream-video-android-compose:0.3.3")
3939

4040
// Jetpack Compose (optional/ android studio typically adds them when you create a new project)
4141
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
title: Screen sharing
3+
description: Setup for screen sharing
4+
---
5+
6+
## Introduction
7+
8+
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)
28+
startMediaProjection.launch(mediaProjectionManager.createScreenCaptureIntent())
29+
```
30+
31+
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+
<string name="stream_video_screen_sharing_notification_title">You are screen sharing</string>
53+
<string name="stream_video_screen_sharing_notification_description"></string>
54+
<string name="stream_video_screen_sharing_notification_action_stop">Stop screen sharing</string>
55+
<string name="stream_video_screen_sharing_notification_channel_title">Screen-sharing</string>
56+
<string name="stream_video_screen_sharing_notification_channel_description">Required to be enabled for screen sharing</string>
57+
```

docusaurus/docs/Android/06-advanced/04-chat-with-video.mdx renamed to docusaurus/docs/Android/06-advanced/05-chat-with-video.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Let the project sync. It should have all the dependencies required for you to fi
3131
```groovy
3232
dependencies {
3333
// Stream Video Compose SDK
34-
implementation("io.getstream:stream-video-android-compose:0.3.2")
34+
implementation("io.getstream:stream-video-android-compose:0.3.3")
3535
3636
// Stream Chat
3737
implementation(libs.stream.chat.compose)
File renamed without changes.
File renamed without changes.

dogfooding/src/main/kotlin/io/getstream/video/android/ui/call/SettingsMenu.kt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616

1717
package io.getstream.video.android.ui.call
1818

19+
import android.app.Activity
20+
import android.media.projection.MediaProjectionManager
1921
import android.widget.Toast
22+
import androidx.activity.compose.rememberLauncherForActivityResult
23+
import androidx.activity.result.contract.ActivityResultContracts
2024
import androidx.compose.foundation.background
2125
import androidx.compose.foundation.clickable
2226
import androidx.compose.foundation.layout.Column
@@ -29,6 +33,8 @@ import androidx.compose.material.Card
2933
import androidx.compose.material.Icon
3034
import androidx.compose.material.Text
3135
import androidx.compose.runtime.Composable
36+
import androidx.compose.runtime.collectAsState
37+
import androidx.compose.runtime.getValue
3238
import androidx.compose.runtime.rememberCoroutineScope
3339
import androidx.compose.ui.Alignment
3440
import androidx.compose.ui.Modifier
@@ -54,6 +60,21 @@ internal fun SettingsMenu(
5460
val reactions =
5561
listOf(":fireworks:", ":hello:", ":raise-hand:", ":like:", ":hate:", ":smile:", ":heart:")
5662

63+
val screenSharePermissionResult = rememberLauncherForActivityResult(
64+
contract = ActivityResultContracts.StartActivityForResult(),
65+
onResult = {
66+
if (it.resultCode == Activity.RESULT_OK && it.data != null) {
67+
call.startScreenSharing(it.data!!)
68+
}
69+
onDismissed.invoke()
70+
},
71+
)
72+
73+
val isScreenSharing by call.screenShare.isEnabled.collectAsState()
74+
val screenShareButtonText = if (isScreenSharing) {
75+
"Stop screen-sharing"
76+
} else { "Start screen-sharing" }
77+
5778
Popup(
5879
alignment = Alignment.BottomStart,
5980
offset = IntOffset(30, -200),
@@ -92,6 +113,37 @@ internal fun SettingsMenu(
92113

93114
Spacer(modifier = Modifier.height(12.dp))
94115

116+
Row(
117+
modifier = Modifier.clickable {
118+
if (!isScreenSharing) {
119+
scope.launch {
120+
val mediaProjectionManager = context.getSystemService(
121+
MediaProjectionManager::class.java,
122+
)
123+
screenSharePermissionResult.launch(
124+
mediaProjectionManager.createScreenCaptureIntent(),
125+
)
126+
}
127+
} else {
128+
call.stopScreenSharing()
129+
}
130+
},
131+
) {
132+
Icon(
133+
painter = painterResource(id = R.drawable.stream_video_ic_screensharing),
134+
tint = VideoTheme.colors.textHighEmphasis,
135+
contentDescription = null,
136+
)
137+
138+
Text(
139+
modifier = Modifier.padding(start = 20.dp),
140+
text = screenShareButtonText,
141+
color = VideoTheme.colors.textHighEmphasis,
142+
)
143+
}
144+
145+
Spacer(modifier = Modifier.height(12.dp))
146+
95147
if (showDebugOptions) {
96148
Row(
97149
modifier = Modifier.clickable {

0 commit comments

Comments
 (0)