适用于 Android 的 Amazon Chime SDK
注意:如果使用 SDK 源代码构建,
development
分支包含最新的更改,可能无法与公开可用的 Chime 媒体库一起构建,或者可能不如公开发布版本稳定。
使用 Amazon Chime 构建视频通话、音频通话和屏幕共享应用程序。
适用于 Android 的 Amazon Chime SDK 通过使用为 Amazon Chime 服务上的会议提供支持的相同基础设施服务,可以轻松地将协作音频通话、视频通话和屏幕共享查看功能添加到 Android 应用程序中。
这个适用于 Android 的 Amazon Chime SDK 通过连接到您在 AWS 账户中创建的会议会话资源来工作。该 SDK 包含在 Android 应用程序中构建自定义通话和协作体验所需的一切,包括以下方法:配置会议会话、列出和选择音频设备、切换视频设备、开始和停止屏幕共享查看、在发生媒体事件(如音量变化)时接收回调,以及管理会议功能(如音频静音和视频图块绑定)。
我们还有一个 Amazon Chime SDK 项目看板,您可以在那里找到社区请求及其状态。
要开始使用,请参阅以下资源:
并查看以下指南:
设置
注意:如果您只想运行演示应用程序,请跳到运行演示应用程序
适用于 Android 的移动 SDK 可以从 Maven Central 存储库下载,通过集成到您的 Android 项目的 Gradle 文件中,或者可以通过 .aar 文件直接嵌入。
为了设置,您项目的根文件夹将被称为 root
。
从 Maven 获取
要从 Maven 获取依赖项,请将依赖项添加到您的应用程序的(模块级)build.gradle
中。
更新 root/app
中的 build.gradle
,并在 dependencies
下添加以下内容:
dependencies {
implementation 'software.aws.chimesdk:amazon-chime-sdk-media:$MEDIA_VERSION'
implementation 'software.aws.chimesdk:amazon-chime-sdk:$SDK_VERSION'
}
版本号可以从最新的发布版本获取。
如果您不需要视频和内容共享功能,或软件视频编解码器支持,可以使用 amazon-chime-sdk-media-no-video-codecs
来减小大小。从 amazon-chime-sdk
的传递依赖中排除 amazon-chime-sdk-media
模块和/或 amazon-chime-sdk-machine-learning
模块的使用:
dependencies {
implementation 'software.aws.chimesdk:amazon-chime-sdk-media-no-video-codecs:$MEDIA_VERSION'
implementation ('software.aws.chimesdk:amazon-chime-sdk:$MEDIA_VERSION') {
exclude module: 'amazon-chime-sdk-media'
exclude module: 'amazon-chime-sdk-machine-learning'
}
}
项目现在可以构建 Arm 和 x86 目标,这在打包应用程序时可能有用。x86 目标将无法运行,也不打算在任何 x86 设备或模拟器上安装或运行。 重要:仅支持 Arm 设备。
如果您需要媒体二进制文件中的非功能性 x86 存根以打包您的应用程序,可以在您选择的媒体依赖项后附加 -x86-stub
。例如:
dependencies {
implementation 'software.aws.chimesdk:amazon-chime-sdk-media-no-video-codecs-x86-stub:$MEDIA_VERSION'
implementation ('software.aws.chimesdk:amazon-chime-sdk:$MEDIA_VERSION') {
exclude module: 'amazon-chime-sdk-media'
exclude module: 'amazon-chime-sdk-machine-learning'
}
}
手动下载 SDK 二进制文件
要在您自己的项目中包含 SDK 二进制文件,请按照以下步骤操作。
1. 下载二进制文件
从最新的发布版本下载 amazon-chime-sdk
和 amazon-chime-sdk-media
二进制文件。
如果您想使用更多机器学习功能,例如背景模糊/替换,还请从最新的发布版本下载 amazon-chime-sdk-machine-learning
二进制文件。否则,您可以忽略以下说明中所有关于 amazon-chime-sdk-machine-learning
的引用。
如果您不需要视频和内容共享功能,或软件视频编解码器支持,可以使用 amazon-chime-sdk-media-no-video-codecs
代替 amazon-chime-sdk-media
来排除软件视频编解码器支持并减小大小。如果是这样,您可以在以下说明中将所有对 amazon-chime-sdk-media
的引用视为 amazon-chime-sdk-media-no-video-codecs
。
项目现在可以构建 Arm 和 x86 目标,这在打包应用程序时可能有用。x86 目标将无法运行,也不打算在任何 x86 设备或模拟器上安装或运行。 重要:仅支持 Arm 设备。
如果您需要非功能性 x86 存根与完全功能的 arm 架构结合以打包您的应用程序,可以使用 amazon-chime-sdk-media-x86-stub
或 amazon-chime-sdk-media-no-video-codecs-x86-stub
媒体二进制文件,并在以下说明中将它们替换为 amazon-chime-sdk-media
引用。
注意:我们不支持混合使用不同发布版本的二进制文件。
解压缩它们并将 aar 文件复制到 root/app/libs
2. 更新 gradle 文件
在 root
中更新 build.gradle
,在 allprojects
的 repositories
下添加以下内容:
allprojects {
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
}
在 root/app
中更新 build.gradle
,并在 dependencies
下添加以下内容:
implementation(name: 'amazon-chime-sdk', ext: 'aar')
implementation(name: 'amazon-chime-sdk-media', ext: 'aar')
如果您使用 amazon-chime-sdk-machine-learning
库,那么也在 dependencies
下添加以下语句:
implementation(name: 'amazon-chime-sdk-machine-learning', ext: 'aar')
在 root/app
的 build.gradle
中的 compileOptions
下更新:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
运行演示应用程序
注意:这仅用于运行演示应用程序,并使用 SDK 作为代码而不是 aar 库。
要运行演示应用程序,请按照以下步骤操作。
注意:请确保您在支持 ARM 的设备(真实设备)或支持 arm 的模拟器上运行。我们目前不支持 x86,因此带有 x86 的模拟器将无法工作。
1. 部署无服务器演示
从 amazon-chime-sdk-js 部署无服务器演示,它将返回 https://xxxxx.xxxxx.xxx.com/Prod/
为移动演示应用程序提供 https://xxxxx.xxxxx.xxx.com/Prod/
。
2. 下载二进制文件
从最新的发布版本下载 amazon-chime-sdk-media
二进制文件。
下载 amazon-chime-sdk-machine-learning
二进制文件以获取机器学习功能。
解压缩并将 aar 文件复制到 amazon-chime-sdk-android/amazon-chime-sdk/libs
3. 更新演示应用程序
在 amazon-chime-sdk-android/app/src/main/res/values
路径下的 strings.xml
中更新 test_url
,使用步骤 1 中部署的无服务器演示的 URL。
注意:使用
https://xxxxx.xxxxx.xxx.com/Prod/
报告疑似漏洞
如果您在此项目中发现潜在的安全问题,我们请您通过我们的漏洞报告页面通知 AWS/Amazon 安全团队。请不要创建公开的 GitHub 问题。
使用方法
开始会话
用例 1. 开始会话。
您需要开始会议会话才能开始发送和接收音频。
使用默认配置开始会话:
meetingSession.audioVideo.start()
使用自定义配置开始会话:
meetingSession.audioVideo.start(audioVideoConfiguration)
audioVideoConfiguration
中可用的配置包括:
audioMode
audioDeviceCapabilities
audioStreamType
audioRecordingPresetOverride
enableAudioRedundancy
reconnectTimeoutMs
音频模式:默认音频格式是立体声/48KHz,即采样率为48KHz的立体声音频(Stereo48K)。其他支持的音频格式包括单声道/48KHz(Mono48K)或单声道/16KHz(Mono16K)。您可以在 AudioVideoConfiguration
中指定非默认音频模式,然后开始会议会话。
AudioDeviceCapabilities:默认的音频设备功能是同时启用音频输入和输出设备(InputAndOutput
),即麦克风和扬声器都处于启用状态。InputAndOutput
需要MODIFY_AUDIO_SETTINGS
和RECORD_AUDIO
权限。其他选项包括OutputOnly
(麦克风禁用,扬声器启用;需要MODIFY_AUDIO_SETTINGS
权限)和None
(麦克风和扬声器都禁用;不需要任何音频权限)。
AudioStreamType:默认值为VoiceCall
。可用选项有VoiceCall
和Music
,它们分别等同于AudioManager中的STREAM_VOICE_CALL
和STREAM_MUSIC
。此配置用于解决Oculus Quest 2上的音量问题。如果你不了解这个问题,可能不需要担心它。更多信息请参考Android文档:STREAM_VOICE_CALL,STREAM_MUSIC。
注意:尽管Android中有更多可用的流选项,但目前Amazon Chime SDK for Android仅支持STREAM_VOICE_CALL和STREAM_MUSIC。
AudioRecordingPresetOverride:默认值为None
。可用选项有None
、Generic
、Camcorder
、VoiceRecognition
和VoiceCommunication
。这些相当于此处提到的Android AudioRecorder配置中的选项。
EnableAudioRedundancy:默认值为true。启用时,SDK将在检测到数据包丢失时发送冗余音频数据,以帮助减少其对音频质量的影响。更多详情可以在冗余音频部分找到。
ReconnectTimeoutMs:默认值为180,000毫秒。使用此配置来控制由于网络状况不佳导致的会话重新连接超时。
用例2. 添加观察者以接收音频和视频会话生命周期事件。
注意:为避免错过任何事件,请在会话开始前添加观察者。你可以通过调用meetingSession.audioVideo.removeAudioVideoObserver(observer)来移除观察者。
val observer = object : AudioVideoObserver {
override fun onAudioSessionStartedConnecting(reconnecting: Boolean) {
if (reconnecting) {
// 例如,网络连接断开
}
}
override fun onAudioSessionStarted(reconnecting: Boolean) {
// 会议会话开始。
// 可以使用实时和设备API。
}
override fun onAudioSessionDropped(reconnecting: Boolean) {}
override fun onAudioSessionStopped(sessionStatus: MeetingSessionStatus) {
// 参见"停止会话"部分了解详情。
}
override fun onAudioSessionCancelledReconnect() {}
override fun onConnectionRecovered() {}
override fun onConnectionBecamePoor() {}
override fun onVideoSessionStartedConnecting() {}
override fun onVideoSessionStarted(sessionStatus: MeetingSessionStatus) {
// 视频会话开始。
// 可以使用视频API。
}
override fun onVideoSessionStopped(sessionStatus: MeetingSessionStatus) {}
}
meetingSession.audioVideo.addAudioVideoObserver(observer)
设备
用例3. 列出音频设备。
列出会议可用的音频设备。
val audioDevices = meetingSession.audioVideo.listAudioDevices()
// MediaDevice对象列表
audioDevices.forEach {
logger.info(TAG, "设备类型:${it.type},标签:${it.label}")
}
用例4. 通过传递MediaDevice
对象选择音频设备。
注意:你应该在会话开始后调用chooseAudioDevice,否则它将不会执行任何操作。你还应该使用listAudioDevices返回的设备之一来调用chooseAudioDevice。
// 过滤掉当前不支持选择的OTHER类型
val audioDevices = meetingSession.audioVideo.listAudioDevices().filter {
it.type != MediaDeviceType.OTHER)
}
val device = /* audioDevices中的一个项目 */
meetingSession.audioVideo.chooseAudioDevice(device)
用例5. 切换摄像头。
注意:如果你使用自定义摄像头捕获源,switchCamera()将不会执行任何操作。请参考自定义视频了解更多详情。
在设备的前置或后置摄像头之间切换(如果可用)。
meetingSession.audioVideo.switchCamera()
用例6. 添加观察者以接收更新的设备列表。
添加DeviceChangeObserver
以在新的音频设备连接或音频设备断开连接时接收回调。onAudioDeviceChanged
包含更新后的设备列表。
val observer = object: DeviceChangeObserver {
override fun onAudioDeviceChanged(freshAudioDeviceList: List<MediaDevice>) {
// 更新后的MediaDevice对象列表
freshAudioDeviceList.forEach {
logger.info(TAG, "设备类型:${it.type},标签:${it.label}")
}
}
}
meetingSession.audioVideo.addDeviceChangeObserver(observer)
用例7. 获取当前选择的音频设备。
注意:
getActiveAudioDevice
API需要API级别24或更高。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val activeAudioDevice = meetingSession.audioVideo.getActiveAudioDevice()
}
对于较低的API级别,开发者可以通过以下逻辑跟踪所选设备来实现相同的功能:
var activeAudioDevice: MediaDevice? = null
override fun onAudioDeviceChanged(freshAudioDeviceList: List<MediaDevice>) {
val device = /* freshAudioDeviceList中的一个项目 */
meetingSession.audioVideo.chooseAudioDevice(device)
activeAudioDevice = device // 更新当前设备
}
音频
用例8. 选择音频配置。
加入会议时,如果在开始音频会话时未明确指定,每个配置都会有一个默认值。
- 支持的AudioMode选项:Mono/16KHz、Mono/48KHz和Stereo/48KHz。默认为Stereo/48KHz。
- 支持的AudioDeviceCapabilities选项:Input and Output、Output Only和None。默认为Input and Output。
- 支持的AudioStreamType选项:VoiceCall和Music。默认为VoiceCall
- 支持的AudioRecordingPresetOverride选项:None、Generic、Camcorder、VoiceRecognition和VoiceCommunication。默认为None。
- 支持的enableAudioRedundancy选项:true和false。默认为true。
- 支持的reconnectTimeoutMs值:大于或等于0的整数。默认为180,000。
meetingSession.audioVideo.start() // 使用上述默认值启动音频视频会话
meetingSession.audioVideo.start(audioVideoConfiguration) // 使用指定的[AudioVideoConfiguration]启动音频视频会话
注意:到目前为止,你已经添加了观察者来接收设备和会话生命周期事件。在以下用例中,你将使用实时API方法来发送和接收音量指示器并控制静音状态。
用例9. 静音和取消静音音频输入。
val muted = meetingSession.audioVideo.realtimeLocalMute() // 如果静音成功返回true,失败返回false
val unmuted = meetingSession.audioVideo.realtimeLocalUnmute() // 如果取消静音成功返回true,失败返回false
用例10. 添加观察者以接收实时事件,如音量变化/信号变化/与会者静音状态。
你可以使用这个来构建实时指示器UI,并根据数组传递的变化进行更新。
注意:这些回调将只包含与上一次回调的差异。
val observer = object : RealtimeObserver {
override fun onVolumeChanged(volumeUpdates: Array<VolumeUpdate>) {
volumeUpdates.forEach { (attendeeInfo, volumeLevel) ->
logger.info(TAG, "${attendeeInfo.attendeeId}的音量变化:" +
$volumeLevel // Muted, NotSpeaking, Low, Medium, High
)
}
}
override fun onSignalStrengthChanged(signalUpdates: Array<SignalUpdate>) {
signalUpdates.forEach { (attendeeInfo, signalStrength) ->
logger.info(TAG, "${attendeeInfo.attendeeId}的信号强度变化:" +
$signalStrength // None, Low, High
)
}
}
override fun onAttendeesJoined(attendeeInfo: Array<AttendeeInfo>) {
attendeeInfo.forEach { logger.info(TAG, "${attendeeInfo.attendeeId}加入了会议") }
}
override fun onAttendeesLeft(attendeeInfo: Array<AttendeeInfo>) {
attendeeInfo.forEach { logger.info(TAG, "${attendeeInfo.attendeeId}离开了会议") }
}
override fun onAttendeesDropped(attendeeInfo: Array<AttendeeInfo>) {
attendeeInfo.forEach { logger.info(TAG, "${attendeeInfo.attendeeId}从会议中掉线") }
}
override fun onAttendeesMuted(attendeeInfo: Array<AttendeeInfo>) {
attendeeInfo.forEach { logger.info(TAG, "${attendeeInfo.attendeeId}已静音") }
}
override fun onAttendeesUnmuted(attendeeInfo: Array<AttendeeInfo>) {
attendeeInfo.forEach { logger.info(TAG, "${attendeeInfo.attendeeId}已取消静音") }
}
}
meetingSession.audioVideo.addRealtimeObserver(observer)
用例11. 检测活跃发言者和发言者的活跃分数。
你可以使用onActiveSpeakerDetected
事件来放大或强调最活跃发言者的视频窗格(如果有)。通过设置scoreCallbackIntervalMs
并实现onActiveSpeakerScoreChanged
,你可以定期接收活跃发言者的分数。
val observer = object : ActiveSpeakerObserver {
override fun onActiveSpeakerDetected(attendeeInfo: Array<AttendeeInfo>) {
if (attendeeInfo.isNotEmpty()) {
logger.info(TAG, "${attendeeInfo[0].attendeeId}是最活跃的发言者")
}
}
// 设置每1秒接收一次onActiveSpeakerScoreChanged事件
override val scoreCallbackIntervalMs: Int? get() = 1000
override fun onActiveSpeakerScoreChanged(scores: Map<AttendeeInfo, Double>) {
val scoreString = scores.map { entry -> "${entry.key.attendeeId}: ${entry.value}" }.joinToString(",")
logger.info(TAG, "活跃发言者的分数为: $scoreString")
}
}
// 基于SDK提供的策略计算活跃发言者,你也可以提供任何自定义算法
meetingSession.audioVideo.addActiveSpeakerObserver(DefaultActiveSpeakerPolicy(), observer)
视频
注意:你需要将视频绑定到
VideoRenderView
才能渲染它。可以使用
isLocalTile
属性识别本地视频图块。可以使用
isContent
属性识别内容视频图块。参见屏幕和内容共享。当同一远程参与者重新启动视频时,会使用新的图块ID创建图块。
你可以在使用Amazon Chime SDK在Android上构建会议应用程序中找到更多关于添加/删除/查看视频的详细信息。
用例12. 开始接收远程视频。
你可以调用startRemoteVideo
来开始接收远程视频,因为这默认不会发生。
meetingSession.audioVideo.startRemoteVideo()
用例13. 停止接收远程视频。
stopRemoteVideo
停止接收远程视频,并为现有的远程视频触发onVideoTileRemoved
。
meetingSession.audioVideo.stopRemoteVideo()
用例14. 查看远程视频。
val observer = object : VideoTileObserver {
override fun onVideoTileAdded(tileState: VideoTileState) {
// 忽略本地视频(参见查看本地视频)和内容视频(参见屏幕和内容共享)
if(tileState.isLocalTile || tileState.isContent) return
val videoRenderView = /* 你应用程序中用于显示视频的VideoRenderView对象 */
meetingSession.audioVideo.bindVideoView(videoRenderView, tileState.tileId)
}
override onVideoTileRemoved(tileState: VideoTileState) {
// 解绑视频视图以停止查看图块
audioVideo.unbindVideoView(tileState.tileId)
}
}
meetingSession.audioVideo.addVideoTileObserver(observer)
对于更高级的视频图块管理,请查看视频分页。
用例15. 开始共享你的视频。
// 使用内部相机捕获本地视频
meetingSession.audioVideo.startLocalVideo()
// 使用内部相机捕获并设置视频配置,例如maxBitRateKbps
// 如果未设置maxBitRateKbps,它将根据会议中的用户数和视频数自动调整
// 可以多次调用此方法以动态调整视频配置
val localVideoConfig = LocalVideoConfiguration(600)
meetingSession.audioVideo.startLocalVideo(localVideoConfig)
// 你可以切换相机来更改视频输入设备
meetingSession.audioVideo.switchCamera()
// 或者你可以为本地视频注入自定义视频源,参见自定义视频指南
用例16. 停止共享你的视频。
meetingSession.audioVideo.stopLocalVideo()
用例17. 查看本地视频。
val observer = object : VideoTileObserver {
override fun onVideoTileAdded(tileState: VideoTileState) {
// 在调用startLocalVideo后会调用onVideoTileAdded
val localVideoRenderView = /* 用于显示本地视频的VideoRenderView对象 */
if (tileState.isLocalTile) {
audioVideo.bindVideoView(localVideoRenderView, tileState.tileId)
}
}
override onVideoTileRemoved(tileState: VideoTileState) {
// 在调用stopLocalVideo后会调用onVideoTileRemoved
if (tileState.isLocalTile) {
logger.info(TAG, "本地视频已移除")
audioVideo.unbindVideoView(tileState.tileId)
}
}
}
meetingSession.audioVideo.addVideoTileObserver(observer)
屏幕和内容共享
注意:当你或其他参与者共享内容(例如,屏幕捕获或任何其他VideoSource对象)时,内容参与者(attendee-id#content)会加入会话并像普通参与者共享视频一样共享内容。
例如,你的参与者ID是"my-id"。当你调用
meetingSession.audioVideo.startContentShare
时,内容参与者"my-id#content"将加入会话并共享你的内容。
用例18. 开始共享你的屏幕或内容。
val observer = object : ContentShareObserver {
override fun onContentShareStarted() {
logger.info(TAG, "内容共享已开始")
}
override fun onContentShareStopped(status: ContentShareStatus) {
logger.info(TAG, "内容共享已停止,状态为${status.statusCode}")
}
}
meetingSession.audioVideo.addContentShareObserver(observer)
val contentShareSource = /* 一个ContentShareSource对象,可以使用DefaultScreenCaptureSource进行屏幕共享或任何带有自定义视频源的子类 */
// ContentShareSource对象不由SDK管理,开发者需要相应地启动、停止、释放
meetingSession.audioVideo.startContentShare(contentShareSource)
你可以为内容共享设置配置,例如maxBitRateKbps。实际达到的质量可能会根据系统和网络情况在通话过程中有所变化。
val contentShareConfig = LocalVideoConfiguration(200)
meetingSession.audioVideo.startContentShare(contentShareSource, contentShareConfig)
有关更多详细信息,请参见内容共享。
用例19. 停止共享你的屏幕或内容。
meetingSession.audioVideo.stopContentShare()
用例20. 查看参与者的内容或屏幕。
Chime SDK允许每次会议同时共享两个内容。远程内容共享会触发onVideoTileAdded
,而本地共享则不会。要预览渲染视频,请将VideoSink
添加到ContentShareSource
中的VideoSource
。
val observer = object : VideoTileObserver {
override fun onVideoTileAdded(tileState: VideoTileState) {
if (tileState.isContent) {
// tileState.attendeeId的格式为"attendee-id#content"
val attendeeId = tileState.attendeeId
// 从"attendee-id#content"中获取attendee ID
val baseAttendeeId = DefaultModality(attendeeId).base()
logger.info(TAG, "$baseAttendeeId 正在共享屏幕")
val contentVideoRenderView = /* 你应用程序中用于显示内容视频的VideoRenderView对象 */
meetingSession.audioVideo.bindVideoView(contentVideoRenderView, tileState.tileId)
}
}
override onVideoTileRemoved(tileState: VideoTileState) {
// 解绑视频视图以停止查看图块
meetingSession.audioVideo.unbindVideoView(tileId)
}
}
meetingSession.audioVideo.addVideoTileObserver(observer)
指标
用例21. 添加观察者以接收会议指标。
查看ObservableMetric
以获取更多可用指标,并监控音频、视频和内容共享质量。
val observer = object: MetricsObserver {
override fun onMetricsReceived(metrics: Map<ObservableMetric, Any>) {
metrics.forEach { (metricsName, metricsValue) ->
logger.info(TAG, "$metricsName : $metricsValue")
}
}
}
meetingSession.audioVideo.addMetricsObserver(observer)
数据消息
用例22. 添加观察者以接收数据消息。
启动会议会话后,你可以从多个主题接收实时消息。
注意:除非被限制,否则本地参与者发送的数据消息不会触发此回调。
val YOUR_ATTENDEE_ID = meetingSession.configuration.credentials.attendeeId
val observer = object: DataMessageObserver {
override fun onDataMessageReceived(dataMessage: DataMessage) {
// 后端返回的限制消息
if (!dataMessage.throttled) {
logger.info(TAG, "[${dataMessage.timestampMs}][{$dataMessage.senderAttendeeId}] : ${dataMessage.text()}")
}
}
// 你可以订阅多个主题。
const val DATA_MESSAGE_TOPIC = "chat"
meetingSession.audioVideo.addRealtimeDataMessageObserver(DATA_MESSAGE_TOPIC, observer)
用例23. 发送数据消息。
你可以向任何主题发送实时消息,订阅该主题的观察者将收到通知。
注意:主题需要是字母数字,可以包含连字符和下划线。数据不能超过2kb,生存时间是可选的,但必须是正整数。
const val DATA_MESSAGE_TOPIC = "chat"
const val DATA_MESSAGE_LIFETIME_MS = 1000
// 向订阅"chat"主题的任何订阅者发送"Hello Chime",生存时间为1秒
meetingSession.audioVideo.realtimeSendDataMessage(
DATA_MESSAGE_TOPIC,
"Hello Chime",
DATA_MESSAGE_LIFETIME_MS
)
停止会话
注意:确保移除所有你添加的观察者并释放资源,以避免任何内存泄漏。
用例24. 停止会话。
val observer = object: AudioVideoObserver {
override fun onAudioSessionStopped(sessionStatus: MeetingSessionStatus) {
// 这里是会议结束的地方。
// 你可以在这里进行一些清理工作。
}
override fun onVideoSessionStopped(sessionStatus: MeetingSessionStatus) {
// 这也会被调用。
}
}
meetingSession.audioVideo.addAudioVideoObserver(observer)
meetingSession.audioVideo.stop()
Amazon Voice Focus
Amazon Voice Focus可以减少会议中的背景噪音,提供更好的会议体验。有关更多详细信息,请参见Amazon Voice Focus。
用例25. 启用/禁用Amazon Voice Focus。
val enabled = meetingSession.audioVideo.realtimeSetVoiceFocusEnabled(true) // 成功启用Amazon Voice Focus
val disabled = meetingSession.audioVideo.realtimeSetVoiceFocusEnabled(false) // 成功禁用Amazon Voice Focus
自定义视频源
自定义视频源允许您控制视频,例如应用视频滤镜。有关更多详细信息,请参阅自定义视频。
背景模糊和替换
背景模糊/替换允许您对视频背景应用模糊效果或用图像替换背景。有关更多详细信息,请参阅背景滤镜。
冗余音频
从版本0.18.3开始,SDK在检测到丢包时会开始向我们的服务器发送冗余音频数据,以帮助减少丢包对音频质量的影响。冗余音频数据包仅针对包含活跃音频(即语音或音乐)的数据包发送。根据检测到的丢包量,这可能会使音频消耗的带宽增加到正常情况下的3倍。如果SDK在5分钟内未检测到任何丢包,它将自动停止发送冗余数据。
如果您需要禁用此功能,可以在开始会话之前通过AudioVideoConfiguration进行设置。
meetingSession.audioVideo.start(AudioVideoConfiguration(enableAudioRedundancy = false))
虽然有选项可以禁用该功能,但我们建议保持启用以提高音频质量。禁用它的一个可能原因是您的客户有非常严格的带宽限制。
常见问题
请参阅Amazon Chime SDK的一般常见问题。
调试
如何获取Amazon Chime SDK的日志进行调试?
应用程序可以通过在创建MeetingSession时传递Logger实例来获取Chime SDK的日志。Amazon Chime SDK有一些默认的日志记录器实现,您的应用程序可以使用,例如ConsoleLogger,它会将日志记录到控制台。ConsoleLogger
默认设置为INFO
级别。因此,要获取所有日志(包括媒体日志),请按以下方式创建日志记录器:
val logger = ConsoleLogger(LogLevel.VERBOSE)
远程参与者听不到我的音频,我该怎么办?
SDK底层使用OpenSL ES,在打开与麦克风设备的连接时需要设置录音预设。我们发现没有一个特定的预设值能在所有可能的Android设备上都能很好地工作。SDK使用默认预设VoiceCommunication
,这是我们在对我们拥有的设备进行一些测试后得出的结论。如果这个默认预设不起作用,导致远程方无法听到您的声音,请尝试通过在传递给start API的AudioVideoConfiguration
中指定audioRecordingPresetOverride
来使用不同的录音预设启动会话。
// 创建一个配置,其中预设被覆盖为Generic(例如)
val audioVideoConfig = AudioVideoConfiguration(audioRecordingPresetOverride = AudioRecordingPresetOverride.Generic)
// 启动音频视频
audioVideo.start(audioVideoConfig)
注意事项
使用背景替换需遵守额外的注意事项。您和您的最终用户对上传用于背景替换的所有内容(包括任何图像)负责,并且必须确保此类内容不违反法律,不侵犯或盗用任何第三方的权利,也不违反您与亚马逊之间协议的任何重要条款(包括文档、AWS服务条款或可接受使用政策)。
版权所有 Amazon.com, Inc. 或其附属公司。保留所有权利。