# Content Share
Builders using the Amazon Chime SDK for Android can share a second video stream such as screen capture in a meeting without disrupting their applications existing audio/video stream.
## Prerequisites
* You have read the [API overview](https://github.com/aws/amazon-chime-sdk-android/blob/master/guides/api_overview.md) and have a basic understanding of the components covered in that document.
* You have completed [Getting Started](https://github.com/aws/amazon-chime-sdk-android/blob/master/guides/getting_started.md) and have running application which uses the Amazon Chime SDK.
* You have read the [Custom Video Sources, Processors, and Sinks](https://github.com/aws/amazon-chime-sdk-android/blob/master/guides/custom_video.md) and have a basic understanding of APIs such as [VideoSource](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video/-video-source/index.html).
## Sharing content with remote participants
Content share APIs are accessible from [AudioVideoFacade](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo/-audio-video-facade.html). Builders will need to create a [ContentShareSource](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.contentshare/-content-share-source/index.html) which currently contains just the [VideoSource](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video/-video-source/index.html) desired to share in the meeting. A bundled screen capture source using [MediaProjection](https://developer.android.com/reference/android/media/projection/MediaProjection) is provided in [DefaultScreenCaptureSource](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video.capture/-default-screen-capture-source/index.html), but developers can also share any video source which implements [VideoSource](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video/-video-source/index.html).
### Constructing the provided screen capture source implementation
In [DefaultScreenCaptureSource](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video.capture/-default-screen-capture-source/index.html), the video frames are provided via the [MediaProjection](https://developer.android.com/reference/android/media/projection/MediaProjection) APIs, so an application will need to complete the following prerequisites before the implementation is ready for use:
1. *(Android Q and above only)* Starting in Android Q, a foreground service is required before acquiring a `MediaProjection` through [MediaProjectionManger.getMediaProjection](https://developer.android.com/reference/android/media/projection/MediaProjectionManager). Applications will need to create a Service, defined in your `AndroidManifest.xml` and start it as foreground before starting the screen capture source. This will look like the following:
```xml
```
2. To construct a [DefaultScreenCaptureSource](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video.capture/-default-screen-capture-source/index.html), request screen capture permissions from the user and use the result in the constructor parameters:
```kotlin
// Call this function when screen capture is desired
fun requestScreenCapturePermission() {
mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
// Show prompt for screen capture permission
startActivityForResult(
mediaProjectionManager.createScreenCaptureIntent(),
SCREEN_CAPTURE_REQUEST_CODE
)
}
// Handle the result of permission prompt activity started
// in requestScreenCapturePermission
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
// ...
if (SCREEN_CAPTURE_REQUEST_CODE == requestCode && resultCode == Activity.RESULT_OK && data != null) {
// (Android Q and above) Start the service created in step 1
startService(Intent(this, ScreenCaptureService::class.java))
// Initialize a DefaultScreenCaptureSource instance using given result
val screenCaptureSource = DefaultScreenCaptureSource(
this,
logger,
// Use the same EglCoreFactory instance as passed into DefaultMeetingSession
DefaultSurfaceTextureCaptureSourceFactory(
logger,
eglCoreFactory),
resultCode,
data
)
screenCaptureSource.start()
}
// ... Complete any other initialization
}
```
See [Custom Video Sources, Processors, and Sinks](https://github.com/aws/amazon-chime-sdk-android/blob/master/guides/custom_video.md) for more information on the usage of [EglCoreFactory](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video.gl/-egl-core-factory/index.html). The capture source will not work if the factory is not shared between the capture and the meeting session due to use of GPU based video frames.
### Using a custom video source
Refer to the [Implementing a custom video source and transmitting](https://github.com/aws/amazon-chime-sdk-android/blob/master/guides/custom_video.md#implementing-a-custom-video-source-and-transmitting) section of the custom video guide to build a video source to share. Content share supports sharing any source which implements [VideoSource](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video/-video-source/index.html).
### Passing a video source into the facade
Once the video source is ready, wrap it with [ContentShareSource](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.contentshare/-content-share-source/index.html) to share the video.
```kotlin
// Construct the content share source
val contentShareSource = ContentShareSource()
contentShareSource.videoSource = screenCaptureSource // Or a custom source
// Start sharing the content share source to remote participants
audioVideo.startContentShare(contentShareSource)
// ...
// Stop sharing the source
audioVideo.stopContentShare()
```
Additionally, you can set configuration for content share, e.g. maxBitRateKbps. Actual quality achieved may vary throughout the call depending on what system and network can provide.
```kotlin
val contentShareConfig = LocalVideoConfiguration(200)
meetingSession.audioVideo.startContentShare(contentShareSource, contentShareConfig)
```
Note that the content share APIs do not manage the source and only provide a sink to transmit captured frames to remote participants, builders will be responsible to take care of its lifecycle including stopping and releasing the capture sources internal resources.
### Receiving content share events
Applications can receive content share events by implementing methods from [ContentShareObserver](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.contentshare/-content-share-observer/index.html) and subscribe with [addContentShareObserver](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.contentshare/-content-share-controller/add-content-share-observer.html).
## Viewing the content
Content shares are treated as regular audio-video attendees. The attendee ID of a content share is the same as the original attendee, but with a suffix of **#content**. Applications using the Amazon Chime SDK receive real-time attendee presence and video tile updates callbacks for content attendee using the exact same mechanisms as normal video.
To view the content share:
1. Create an observer of [VideoTileObserver](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video/-video-tile-observer/index.html) that implements [onVideoTileAdded](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video/-video-tile-observer/on-video-tile-added.html) to receive callbacks when the video tile is added.
1. Subscribe the observer with [addVideoTileObserver](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video/-video-tile-controller-facade/add-video-tile-observer.html) via audio video facade.
1. In the `onVideoTileAdded`, bind the video tile to a [VideoRenderView](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video/-video-render-view.html).
```kotlin
override fun onVideoTileAdded(tileState: VideoTileState) {
// ...
if (tileState.isContent) {
audioVideo.bindVideoView(view.video_surface, tileState.tileId)
}
}
```
Builders can use the [VideoTileState.isContent](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.audiovideo.video/-video-tile-state/is-content.html) to check if the video tile is a content share, and any add special logic you need to handle the content share.
You can also use the [DefaultModality](https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.utils/-default-modality/index.html) class to determine that an attendee ID is a content share:
```kotlin
if (DefaultModality(attendeeId).hasModality(ModalityType.Content)) {
// ...special handling for content share...
}
```