空间音效
声网为电子竞技、在线会议等场景提供空间音效功能,让用户拥有沉浸式的音频体验。
- 通过更新用户的空间位置,用户可以实时感受到其他用户距离、方位、朝向的变化。
- 通过更新媒体播放器的空间位置,用户可以为背景音、伴奏等媒体资源增添空间感。
- 通过设置参数,体验声音模糊、空气衰减等效果。
空间音效功能当前处于实验阶段,请联系 sales@shengwang.cn 开通空间音效功能,如果需要技术支持,请联系技术支持。
技术原理
用户的空间音效
声网为用户提供本地直角坐标系计算方案设置空间音效:
使用 AgoraLocalSpatialAudioKit
类实现空间音效,通过 SDK 计算本地用户与远端用户的相对位置。你需要分别调用 updateSelfPosition
和 updateRemotePosition
更新本地和远端用户的空间坐标,本地用户才能听到远端用户的空间音效。
媒体播放器的空间音效
声网为媒体播放器提供本地直角坐标系计算方案设置空间音效:
通过 SDK 计算本地用户和媒体播放器的相对位置。你需要在 AgoraLocalSpatialAudioKit
类中分别调用 updateSelfPosition
和 updatePlayerPositionInfo
更新本地用户和媒体播放器的空间坐标,本地用户才能听到媒体播放器的空间音效。
前提条件
在进行操作之前,请确保你已经在项目中实现了基本的实时音视频功能。详见实现音视频互动。
实现方法
用户的空间音效
该方案通过 AgoraLocalSpatialAudioKit
类实现空间音效,API 调用时序与操作步骤如下:
-
在调用其他声网 API 前,调用
sharedEngineWithAppId
并填入你的 App ID,初始化AgoraRtcEngineKit
对象。 -
在调用
AgoraLocalSpatialAudioKit
类的其他 API 前,调用sharedLocalSpatialAudioWithConfig
初始化AgoraLocalSpatialAudioKit
对象。 -
调用
setAudioProfile
设置profile
(音频编码属性)为AgoraAudioProfileDefault
、scenario
(音频应用场景)为AgoraAudioScenarioGameStreaming
。 -
调用带
mediaOptions
参数的joinChannelByToken
加入频道(使用 RTC Token)。你需要在AgoraRtcChannelMediaOptions
中设置channelProfile
(频道场景)为AgoraChannelProfileLiveBroadcasting
(直播场景)、clientRoleType
(用户角色)为AgoraClientRoleBroadcaster
(主播)。 -
声网默认订阅所有远端用户的音频流,你需要调用
AgoraRtcEngineKit
的muteAllRemoteAudioStreams(true)
取消订阅所有远端用户,否则你在步骤 6 中设置的音频接收范围会无效。 -
调用下列方法,设置音频接收范围:
- 调用
setMaxAudioRecvCount
设置音频接收范围内最多可接收的音频流数。 - 调用
setAudioRecvRange
设置音频接收范围(米)。 - 调用
setDistanceUnit
设置游戏引擎单位距离的长度(米)。
- 调用
-
先后调用
updateSelfPosition
和updateRemotePosition
更新本地和远端用户的空间位置,体验空间音效。 -
如果无需体验空间音效,则调用
clearRemotePositions
删除所有远端用户的空间位置信息。删除后,本地用户会听不到所有远端用户。 -
调用
AgoraLocalSpatialAudioKit
的destroy
销毁AgoraLocalSpatialAudioKit
对象。注意必须在调用
AgoraRtcEngineKit
的destroy
前销毁AgoraLocalSpatialAudioKit
对象。 -
调用
AgoraRtcEngineKit
的leaveChannel
和destroy
离开频道并销毁AgoraRtcEngineKit
对象。
媒体播放器的空间音效
该方案通过 AgoraLocalSpatialAudioKit
类中的 updateSelfPosition
和 updatePlayerPositionInfo
实现空间音效。以 AgoraLocalSpatialAudioKit
类为例,操作步骤如下:
-
在调用其他声网 API 前,调用
sharedEngineWithAppId
并填入你的 App ID,初始化AgoraRtcEngineKit
对象。 -
在调用
AgoraLocalSpatialAudioKit
类的其他 API 前,调用sharedLocalSpatialAudioWithConfig
初始化AgoraLocalSpatialAudioKit
对象。 -
调用
setAudioProfile
设置profile
(音频编码属性)为AgoraAudioProfileDefault
、scenario
(音频应用场景)为AgoraAudioScenarioGameStreaming
。 -
调用带
mediaOptions
参数的joinChannelByToken
加入频道(使用 RTC Token)。你需要在AgoraRtcChannelMediaOptions
中设置channelProfile
(频道场景)为AgoraChannelProfileLiveBroadcasting
(直播场景)、clientRoleType
(用户角色)为AgoraClientRoleBroadcaster
(主播)。 -
声网默认订阅所有远端用户的音频流,你需要调用
AgoraRtcEngineKit
的muteAllRemoteAudioStreams(true)
取消订阅所有远端用户,否则你在步骤 6 中设置的音频接收范围会无效。 -
调用下列方法,设置音频接收范围:
- 调用
setMaxAudioRecvCount
设置音频接收范围内最多可接收的音频流数。 - 调用
setAudioRecvRange
设置音频接收范围(米)。 - 调用
setDistanceUnit
设置游戏引擎单位距离的长度(米)。
- 调用
-
先后调用
updateSelfPosition
和updatePlayerPositionInfo
更新本地用户和媒体播放器的空间位置,体验空间音效。 -
调用
AgoraLocalSpatialAudioKit
的destroy
销毁AgoraLocalSpatialAudioKit
对象。注意必须在调用
AgoraRtcEngineKit
的destroy
前销毁AgoraLocalSpatialAudioKit
对象。 -
调用
AgoraRtcEngineKit
的destroy
销毁AgoraRtcEngineKit
对象。
示例代码
本节展示使用本地直角坐标系计算方案实现媒体播放器空间音效的示例代码:
class SpatialAudioMain: BaseViewController {
var agoraKit: AgoraRtcEngineKit!
var mediaPlayer: AgoraRtcMediaPlayerProtocol!
var localSpatial: AgoraLocalSpatialAudioKit!
override func viewDidLoad() {
// 初始化 AgoraRtcEngineKit
agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: KeyCenter.AppId, delegate: self)
// 设置频道场景为直播场景
agoraKit.setChannelProfile(.liveBroadcasting)
// 设置用户角色为主播
agoraKit.setClientRole(.broadcaster)
// 设置音频编码属性和应用场景
agoraKit.setAudioProfile(.default, scenario: .gameStreaming)
guard let filePath = Bundle.main.path(forResource: "audiomixing", ofType: "mp3") else {return}
// 创建媒体播放器
mediaPlayer = agoraKit.createMediaPlayer(with: self)
// 打开媒体资源
mediaPlayer.open(filePath, startPos: 0)
// 初始化 AgoraLocalSpatialAudioKit
let localSpatialConfig = AgoraLocalSpatialAudioConfig()
localSpatialConfig.rtcEngine = agoraKit
localSpatial = AgoraLocalSpatialAudioKit.sharedLocalSpatialAudio(with: localSpatialConfig)
// 设置音频接收范围
localSpatial.setAudioRecvRange(50)
// 设置游戏引擎单位距离的长度
localSpatial.setDistanceUnit(1)
// 更新本地用户的空间位置
let pos = [NSNumber(0.0), NSNumber(0), NSNumber(0.0)]
let forward = [NSNumber(1.0), NSNumber(0.0), NSNumber(0.0)]
let right = [NSNumber(0.0), NSNumber(1.0), NSNumber(0.0)]
let up = [NSNumber(0.0), NSNumber(0.0), NSNumber(1.0)]
self.localSpatial.updateSelfPosition(pos, axisForward: forward, axisRight: right, axisUp: up)
}
override func willMove(toParent parent: UIViewController?) {
if parent == nil {
// 销毁 AgoraLocalSpatialAudioKit
AgoraLocalSpatialAudioKit.destroy()
// 销毁 AgoraRtcEngineKit
AgoraRtcEngineKit.destroy()
}
}
// 更新媒体播放器的空间位置
func updateRemoteUserSpatialAudioPositon() {
let maxR = UIScreen.main.bounds.height / 2.0
let maxSpatailDistance = 30.0
let spatialDistance = currentDistance * maxSpatailDistance / maxR
let posForward = spatialDistance * cos(currentAngle);
let posRight = spatialDistance * sin(currentAngle);
let position = [NSNumber(value: posForward), NSNumber(value: posRight), NSNumber(0.0)]
let forward = [NSNumber(1.0), NSNumber(0.0), NSNumber(0.0)]
let positionInfo = AgoraRemoteVoicePositionInfo()
positionInfo.position = position
positionInfo.forward = forward
localSpatial.updatePlayerPositionInfo(Int(mediaPlayer.getMediaPlayerId()), positionInfo: positionInfo)
}
}
相关文档
示例项目
声网在 GitHub 上提供一个开源的示例项目 SpatialAudio,你可以前往下载,或查看其中的源代码。