# K 歌房场景化 Swift API (/zh-CN/api-reference/online-ktv/ios/ktv-scenario/api/ktv-api)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

本文提供在线 K 歌房场景定制化 Swift API。你可以在 GitHub 上查看源码文件 [KTVApi](https://github.com/AgoraIO-Community/KTVApi/blob/main/KTVAPI/iOS/Classes/KTVApi.swift) 和 [KTVApiImpl](https://github.com/AgoraIO-Community/KTVApi/blob/main/KTVAPI/iOS/Classes/KTVApiImpl.swift)。

:::warning[注意]
本文适用于 K 歌场景化 API v4.3.0。
:::

<a id="ktvapidelegate"></a>
## KTVApiDelegate [#ktvapidelegate]

该协议提供实现 K 歌场景的核心方法。

<a id="createKtvApi"></a>
<a id="createKTVApi"></a>
### createKtvApi [#createktvapi]

```swift
@objc optional func createKtvApi(config: KTVApiConfig)
```

初始化 KTV API 并进行初始化配置。

调用该方法可以初始化 KTV API 模块内部变量和缓存数据。

:::warning[注意]
- 如果你的业务场景是大合唱场景，请调用 [`createKTVGiantChorusApi`](#createKTVGiantChorusApi) 来创建并初始化大合唱场景的 KTV API 实例。
- 调用其他 KTV API 之前，你需要先调用本方法创建并初始化。
:::

#### 参数 [#参数]

- `config`：初始化配置，详见 [`KTVApiConfig`](#KTVApiConfig)。

<a id="createKTVGiantChorusApi"></a>
### createKTVGiantChorusApi [#createktvgiantchorusapi]

```swift
@objc optional func createKTVGiantChorusApi(config: GiantChorusConfiguration)
```

创建并初始化大合唱场景的 KTV API 实例。调用该方法可以初始化 KTV API 模块内部变量和缓存数据，并注册相应的回调监听。

:::warning[注意]
仅大合唱场景需要调用该方法来创建并初始化实例，其他任何场景下，请调用 [createKTVApi](#createKTVApi)。
:::

#### 参数 [#参数-1]

- `config`：初始化配置，详见 [`KTVGiantChorusApiConfig`](#GiantChorusConfiguration)。

<a id="cleancache"></a>
### cleanCache [#cleancache]

```swift
func cleanCache()
```

释放 KTV API 资源。

调用该方法可以清空 KTV API 模块内部变量和缓存数据，取消 `ktvApiEventHandler` 的事件监听，取消网络请求等。

<a id="addeventhandler"></a>
### addEventHandler [#addeventhandler]

```swift
func addEventHandler(ktvApiEventHandler: KTVApiEventHandlerDelegate)
```

注册 KTV API 事件。你可以多次调用该方法注册多个事件回调。

#### 参数 [#参数-2]

- `ktvApiEventHandler`：KTV API 的事件句柄，详见 [`KTVApiEventHandlerDelegate`](#KTVApiEventHandlerDelegate)。

<a id="removeeventhandler"></a>
### removeEventHandler [#removeeventhandler]

```swift
func removeEventHandler(ktvApiEventHandler: KTVApiEventHandlerDelegate)
```

取消注册 KTV API 事件。

#### 参数 [#参数-3]

- `ktvApiEventHandler`：KTV API 的事件句柄，详见 [`KTVApiEventHandlerDelegate`](#KTVApiEventHandlerDelegate)。

<a id="renewtoken"></a>
### renewToken [#renewtoken]

```swift
func renewToken(
    rtmToken: String,
    chorusChannelRtcToken: String
)
```

更新 Token。

当你收到 `onTokenPrivilegeWillExpire` 回调报告 Token 即将过期时，需要主动调用此方法更新 Token。

#### 参数 [#参数-4]

- `rtmToken`：用于音乐内容中心鉴权的 RTM Token，详见 [部署 RTM Token 服务器](/zh-CN/realtime-media/rtm/build/authentication-and-connection/token-generation)。
- `chorusChannelRtcToken`：加入合唱子频道的 Token。在合唱场景下，领唱需要加入两个频道，主频道用于发布人声和播放器的混流，合唱子频道用于发布麦克风采集的音频流。伴唱需要加入合唱子频道来同步领唱的人声。

<a id="renewinnerdatastreamid"></a>
### renewInnerDataStreamId [#renewinnerdatastreamid]

```swift
func renewInnerDataStreamId()
```

更新 KTV API 内部使用的数据流 ID。

如果你调用 `leaveChannel` 离开当前频道，之前创建的数据流会失效，你需要在调用 `joinChannel` 加入频道后，重新调用该方法更新数据流的 ID 。

由于每个频道中最多只能创建 5 个数据流，因此请勿在一个频道内多次调用该方法。

<a id="fetchmusiccharts"></a>
### fetchMusicCharts [#fetchmusiccharts]

```swift
func fetchMusicCharts(completion:@escaping MusicChartCallBacks)
```

获取歌曲榜单。

该方法用于异步操作，调用后会触发获取歌曲榜单的操作，并在操作完成后调用回调闭包以返回结果。

#### 参数 [#参数-5]

- `completion`：用于处理获取歌曲榜单后的回调。该闭包在函数执行完成后仍然可以被调用。回调闭包接受一个 `MusicChartCallBacks` 对象作为参数，用于获取歌曲榜单的结果。

<a id="searchmusic"></a>
### searchMusic[1/2] [#searchmusic12]

```swift
func searchMusic(musicChartId: Int,
                     page: Int,
                     pageSize: Int,
                     jsonOption: String,
                     completion:@escaping MusicResultCallBacks)
```

通过歌曲榜单的 ID 获取指定榜单的歌曲资源列表。

当你调用 `fetchMusicCharts` 获取歌曲榜单 ID 之后，可以通过此方法来检索对应的歌曲资源列表。

#### 参数 [#参数-6]

- `musicChartId`：歌曲榜单 ID，可通过 `fetchMusicCharts` 获取。

- `page`：当前页面编号，默认从 1 开始。

- `pageSize`：当前音乐资源列表的总页面数量，最大值为 50。

- `jsonOption`：扩展 JSON 字段，默认为 `Nil`。你可以通过该字段来筛选出你需要的音乐资源，目前支持筛选可打分的音乐资源及音乐资源的副歌片段：

  | **Key 值** | **Value 值** | **示例** |
  | --- | --- | --- |
  | `pitchType` | [ktv-api-ios-markdown-0-1-1 details](#table-slot-ktv-api-ios-markdown-0-1-1) | `{"pitchType": 1}` |
  | `needHighPart` | [ktv-api-ios-markdown-0-2-1 details](#table-slot-ktv-api-ios-markdown-0-2-1) | `{"needHighPart": true}` |

  <a id="table-slot-ktv-api-ios-markdown-0-1-1"></a>

  **ktv-api-ios-markdown-0-1-1 details**

  是否支持打分：

  - 1：支持打分的音乐资源。
  - 2：不支持打分的音乐资源。

  <a id="table-slot-ktv-api-ios-markdown-0-2-1"></a>

  **ktv-api-ios-markdown-0-2-1 details**

  是否需要副歌片段资源：

  - `true`：需要副歌片段资源。
  - `false`：不需要副歌片段资源。

- `completion`：获取指定榜单的歌曲列表回调。该闭包在函数执行完成后仍然可以被调用。回调闭包接受一个 `MusicResultCallBacks` 对象作为参数，用于获取歌曲列表。

<a id="searchmusic2"></a>
### searchMusic[2/2] [#searchmusic22]

```swift
func searchMusic(keyword: String,
                     page: Int, pageSize: Int,
                     jsonOption: String,
                     completion: @escaping MusicResultCallBacks)
```

通过关键词搜索歌曲。

#### 参数 [#参数-7]

- `keyword`：搜索关键词，支持歌曲名、歌手搜索。

- `page`：想要获取的音乐资源列表的目标页编号。

- `pageSize`：每页所展示的音乐资源的最大数量，最大值为 50。

- `jsonOption`：扩展 JSON 字段，默认为 `Nil`。你可以通过该字段来筛选出你需要的音乐资源，目前支持筛选可打分的音乐资源及音乐资源的副歌片段：

  | **Key 值** | **Value 值** | **示例** |
  | --- | --- | --- |
  | `pitchType` | [ktv-api-ios-markdown-1-1-1 details](#table-slot-ktv-api-ios-markdown-1-1-1) | `{"pitchType": 1}` |
  | `needHighPart` | [ktv-api-ios-markdown-1-2-1 details](#table-slot-ktv-api-ios-markdown-1-2-1) | `{"needHighPart": true}` |

  <a id="table-slot-ktv-api-ios-markdown-1-1-1"></a>

  **ktv-api-ios-markdown-1-1-1 details**

  是否支持打分：

  - 1：支持打分的音乐资源。
  - 2：不支持打分的音乐资源。

  <a id="table-slot-ktv-api-ios-markdown-1-2-1"></a>

  **ktv-api-ios-markdown-1-2-1 details**

  是否需要副歌片段资源：

  - `true`：需要副歌片段资源。
  - `false`：不需要副歌片段资源。

- `completion`：获取指定歌曲的回调。该闭包在函数执行完成后仍然可以被调用。回调闭包接受一个 `MusicResultCallBacks` 对象作为参数，用于获取歌曲资源。

<a id="loadmusic"></a>
### loadMusic[1/2] [#loadmusic12]

```swift
func loadMusic(songCode: Int, config: KTVSongConfiguration, onMusicLoadStateListener: IMusicLoadStateListener)
```

加载歌曲和歌词。

传入歌曲编号和加载配置，调用 `loadMusic` 加载歌曲和歌词。加载结果会通过 `IMusicLoadStateListener` 回调异步通知你。

#### 注意 [#注意]

目前一次仅支持加载一首歌曲，请在一首歌曲加载完成后再加载下一首。

#### 参数 [#参数-8]

- `songCode`: 歌曲编号，用于标识一个音乐资源。你可以通过 `searchMusic[1/2]` 或 `searchMusic[2/2]` 获取需要加载的歌曲编号，也可以通过 RESTful API 来获取[曲库所有歌曲列表](/zh-CN/api-reference/online-ktv/android/ktv-scenario/api/music-content-center#获取曲库所有歌曲列表)或[增量歌曲列表](/zh-CN/api-reference/online-ktv/android/ktv-scenario/api/music-content-center#获取增量歌曲列表)。
- `config`: 加载配置。详见 [`KTVSongConfiguration`](#KTVSongConfiguration)。
- `onMusicLoadStateListener`: 歌曲加载状态，详见 [`IMusicLoadStateListener`](#IMusicLoadStateListener)。

<a id="loadmusic2"></a>
### loadMusic[2/2] [#loadmusic22]

```swift
func loadMusic(config: KTVSongConfiguration, url: String)
```

加载歌曲和歌词。

传入歌曲的 URL 和加载配置，调用 `loadMusic` 加载歌曲和歌词。

#### 注意 [#注意-1]

目前一次仅支持加载一首歌曲，请在一首歌曲加载完成后再加载下一首。

#### 参数 [#参数-9]

- `url`：歌曲的 URL。

- `config`：加载配置。详见 [`KTVSongConfiguration`](#KTVSongConfiguration)。

<a id="removemusic"></a>
### removeMusic [#removemusic]

```swift
func removeMusic(songCode: Int)
```

移除加载的版权音乐。

你可以调用该方法来移除当前正在加载或已加载完成的歌曲。调用后，歌曲的加载进程会终止，歌曲缓存也会清除。

#### 参数 [#参数-10]

- `songCode`：歌曲编号，与你调用 `loadMusic` 时传入的歌曲编号一致。

<a id="switchsingerrole"></a>
### switchSingerRole [#switchsingerrole]

```swift
func switchSingerRole(newRole: KTVSingRole, onSwitchRoleState:@escaping ISwitchRoleStateListener)
```

切换 K 歌时的用户角色。

KTV API 初始化时默认用户角色为听众，如果需要开始独唱或加入合唱，需要调用 `switchSingerRole` 来切换至相应的角色。你可以参考[切换说明](/zh-CN/solutions/online-ktv/ktv-scenario/get-started/integrate-ktvapi#5-切换角色)来进行角色切换。

KTV API 内部会根据角色的切换来控制演唱过程中音乐播放器的播放、同步，以及订阅和发布音频流的行为。

#### 参数 [#参数-11]

- `newRole`: 切换后的用户角色，详见 [`KTVSingRole`](#KTVSingRole)。
- `onSwitchRoleState`：切换角色状态回调闭包，类型为 `ISwitchRoleStateListener`，用于处理切换角色的状态。

<a id="startsing"></a>
### startSing[1/2] [#startsing12]

```swift
func startSing(songCode: Int, startPos: Int)
```

播放歌曲。

如果你调用了 `loadMusic[1/2]` 加载歌曲，需要在收到 `onMusicLoadSuccess` 回调后再调用该方法来播放歌曲。

#### 参数 [#参数-12]

- `songCode`：歌曲编号，用于标识一个音乐资源。你可以通过 `searchMusic[1/2]` 或 `searchMusic[2/2]` 获取需要加载的歌曲编号，也可以通过 RESTful API 来获取[曲库所有歌曲列表](/zh-CN/api-reference/online-ktv/android/ktv-scenario/api/music-content-center#获取曲库所有歌曲列表)或[增量歌曲列表](/zh-CN/api-reference/online-ktv/android/ktv-scenario/api/music-content-center#获取增量歌曲列表)。
- `startPos`：起始播放位置，单位为毫秒。

<a id="startsing2"></a>
### startSing[2/2] [#startsing22]

```swift
fun startSing(url: String, startPos: Long)
```

播放歌曲。

你可以通过传入歌曲的 URL 来进行播放。

如果你调用了 `loadMusic[2/2]` 加载歌曲，需要在收到 `onMusicLoadSuccess` 回调后再调用该方法来播放歌曲。

#### 参数 [#参数-13]

- `url`：歌曲的 URL。
- `startPos`：起始播放位置，单位为毫秒。

<a id="resumesing"></a>
### resumeSing [#resumesing]

```swift
fun resumeSing()
```

恢复播放歌曲。

<a id="pausesing"></a>
### pauseSing [#pausesing]

```swift
fun pauseSing()
```

暂停播放歌曲。

<a id="seeksing"></a>
### seekSing [#seeksing]

```swift
func seekSing(time: Int)
```

跳转到指定时间播放歌曲。

#### 参数 [#参数-14]

- `time`: 跳转的时间点，单位为毫秒。

<a id="mutemic"></a>
### muteMic [#mutemic]

```swift
func muteMic(muteStatus: Bool)
```

设置麦克风的开关状态。

#### 参数 [#参数-15]

- `mute`：当前麦克风的开关状态：
  - `true`：关闭麦克风。
  - `false`：开启麦克风。

<a id="setlrcview"></a>
### setLrcView [#setlrcview]

```swift
func setLrcView(view: KTVLrcViewDelegate)
```

设置歌词控制视图。

歌词控制视图用于显示歌词和控制歌词滚动等操作。调用该方法后，可以将歌词控制视图和 KTV 模块进行绑定，从而实现歌词的同步滚动。

#### 参数 [#参数-16]

- `view`: 歌词控制视图，`KTVLrcViewDelegate` 对象。你需要继承 `KTVLrcViewDelegate` ，并实现 `KTVLrcViewDelegate` 下的接口。

<a id="setaudioplayoutdelay"></a>
### setAudioPlayoutDelay [#setaudioplayoutdelay]

```swift
func setAudioPlayoutDelay(audioPlayoutDelay: Int)
```

设置音频播放延迟时间。

在音频自采集的情况下，你需要调用该方法传入音频帧处理和播放开始前的时间差以便播放器的实时同步。

#### 参数 [#参数-17]

- `audioPlayoutDelay`：音频帧处理和播放开始前的时间差，单位为毫秒。

<a id="getmediaplayer"></a>
### getMediaPlayer [#getmediaplayer]

```swift
func getMediaPlayer() -> AgoraMusicPlayerProtocol?
```

获取播放器实例。

#### 返回值 [#返回值]

-  [`AgoraMusicPlayerProtocol`](/zh-CN/api-reference/rtc/ios/rtc-interface-class#class_imusicplayer) 实例。

<a id="getmusiccontentcenter"></a>
### getMusicContentCenter [#getmusiccontentcenter]

```swift
func getMusicContentCenter() -> AgoraMusicContentCenter?
```

获取音乐内容中心实例。

#### 返回值 [#返回值-1]

- [`AgoraMusicContentCenter`](/zh-CN/api-reference/rtc/ios/rtc-interface-class#class_imusiccontentcenter) 实例。

<a id="ktvlrcviewdelegate"></a>
## KTVLrcViewDelegate [#ktvlrcviewdelegate]

该协议提供歌词组件的相关回调。在调用 `setLrcView` 设置歌词控制视图时，你需要继承此协议并实现其下的方法。

<a id="onupdatepitch"></a>
### onUpdatePitch [#onupdatepitch]

```swift
func onUpdatePitch(pitch: Float)
```

人声音调更新回调。

由于目前 [`AgoraRtcEngineKit`](/zh-CN/api-reference/rtc/ios/rtc-interface-class#class_irtcengine) 不支持多代理，因此你需要实现该回调获取实时的人声音调来传递给 KTV API 内部，便于打分组件使用。

#### 参数 [#参数-18]

- `pitch`：音调值。

<a id="onupdateprogress"></a>
### onUpdateProgress [#onupdateprogress]

```swift
func onUpdateProgress(progress: Int)
```

当歌曲播放进度更新时，会触发该回调将歌曲的实时进度同步给歌词评分组件。该回调每 50 ms 触发一次。

#### 参数 [#参数-19]

- `progress`：当前歌曲的播放进度，单位为毫秒。

<a id="ondownloadlrcdata"></a>
### onDownloadLrcData [#ondownloadlrcdata]

```swift
func onDownloadLrcData(url: String)
```

当获取到歌词下载地址后，会触发调该回调报告歌词的下载地址。

#### 注意 [#注意-2]

请在这个回调内完成歌词下载。

#### 参数 [#参数-20]

- `url`：歌词的下载地址。

<a id="onhighparttime"></a>
### onHighPartTime [#onhighparttime]

```swift
func onHighPartTime(highStartTime: Int, highEndTime: Int)
```

当获取到副歌片段时，会触发该回调把副歌片段的起止时间同步给歌词组件用于显示对应的歌词。

#### 参数 [#参数-21]

- `highStartTime`：副歌片段的起始时间，单位为毫秒。
- `highEndTime`：副歌片段的结束时间，单位为毫秒。

<a id="IMusicLoadStateListener"></a>
## IMusicLoadStateListener [#imusicloadstatelistener]

该接口类提供歌曲加载状态的相关回调。

<a id="onmusicloadsuccess"></a>
### onMusicLoadSuccess [#onmusicloadsuccess]

```swift
func onMusicLoadSuccess(songCode: Int, lyricUrl: String)
```

歌曲加载成功回调。

当你调用 `loadMusic` 成功加载歌曲后，会触发该回调。

#### 参数 [#参数-22]

- `songCode`：歌曲编号，与你调用  `loadMusic` 时传入的歌曲编号一致。
- `lyricUrl`：歌词下载地址。

<a id="onmusicloadfail"></a>
### onMusicLoadFail [#onmusicloadfail]

```swift
func onMusicLoadFail(songCode: Int, reason: KTVLoadSongFailReason)
```

歌曲加载失败。

当你调用 `loadMusic` 加载歌曲，加载失败后会触发该回调报告失败的原因。

#### 参数 [#参数-23]

- `songCode`：歌曲编号，与你调用  `loadMusic` 时传入的歌曲编号一致。
- `reason`：歌曲加载失败的原因，详见 [`KTVLoadSongFailReason`](#KTVLoadSongFailReason)。

<a id="onmusicloadprogress"></a>
### onMusicLoadProgress [#onmusicloadprogress]

```swift
func onMusicLoadProgress(songCode: Int, percent: Int, status: AgoraMusicContentCenterPreloadStatus, msg: String?, lyricUrl: String?)
```

歌曲加载进度回调。

你可以通过该回调来获取当前歌曲的加载进度和状态。

#### 参数 [#参数-24]

- `songCode`：歌曲编号，与你调用  `loadMusic` 时传入的歌曲编号一致。
- `percent`：歌曲加载进度，取值范围为 [0,100]，100 表示加载完成。
- `status`：歌曲加载状态，详见 [`AgoraMusicContentCenterPreloadStatus`](/zh-CN/api-reference/rtc/ios/enum-preloadstate)。
- `msg`：本次请求返回的消息。`ok` 表示请求成功。
- `lyricUrl`：歌词下载地址。

<a id="KTVApiEventHandlerDelegate"></a>
## KTVApiEventHandlerDelegate [#ktvapieventhandlerdelegate]

该协议提供 K 歌场景的核心回调。

<a id="onmusicplayerstatechanged"></a>
### onMusicPlayerStateChanged [#onmusicplayerstatechanged]

```swift
func onMusicPlayerStateChanged(state: AgoraMediaPlayerState,
                               error: AgoraMediaPlayerError,
                               isLocal: Bool)
```

播放器状态改变回调。

#### 参数 [#参数-25]

- `state`：播放器的当前状态。详见 [`AgoraMediaPlayerState`](/zh-CN/api-reference/rtc/ios/enum-mediaplayerstate)。
- `error`：播放器的错误码。详见 [`AgoraMediaPlayerError`](/zh-CN/api-reference/rtc/ios/enum-mediaplayerreason)。
- `isLocal`: 是否为本地事件：
  - `true`: 代表是本地播放器的状态改变。可用于主唱和伴唱监听本地播放器状态。
  - `false`: 是远端播放器的状态改变。可用于伴唱和听众知晓主唱的播放器状态，从而方便后续进行多端播放同步。

举例来说，在合唱场景下，主唱、伴唱、听众收到的 `onMusicPlayerStateChanged` 回调有如下区别：

- 主唱：收到一个 `isLocal` 为 `true` 的回调，报告主唱播放器的状态改变。
- 伴唱：收到一个 `isLocal` 为 `true` 的回调，报告伴唱播放器的状态改变；同时，还收到一个 `isLocal` 为 `false` 的回调，报告主唱播放器的状态改变。
- 听众：收到一个 `isLocal` 为 `false` 的回调报告主唱端播放器的状态改变。

<a id="onsingerrolechanged"></a>
### onSingerRoleChanged [#onsingerrolechanged]

```swift
func onSingerRoleChanged(oldRole: KTVSingRole, newRole: KTVSingRole)
```

用户角色改变回调。

当你调用 `switchSingerRole` 成功切换用户角色后，会触发该回调报告切换前后的用户角色。

#### 参数 [#参数-26]

- `oldRole`：切换前的用户角色，详见 [`KTVSingRole`](#KTVSingRole)。
- `newRole`：切换后的用户角色，详见 [`KTVSingRole`](#KTVSingRole)。

<a id="ontokenprivilegewillexpire"></a>
### onTokenPrivilegeWillExpire [#ontokenprivilegewillexpire]

```swift
open fun onTokenPrivilegeWillExpire() {}
```

Token 即将过期回调。

当用于音乐内容中心鉴权的 RTM Token 或用于加入合唱频道（频道 2）鉴权的 Token 即将过期时，会触发该回调。

在收到该回调后，你需要调用 `renewToken` 来更新 Token。

<a id="onchoruschannelaudiovolumeindication"></a>
### onChorusChannelAudioVolumeIndication [#onchoruschannelaudiovolumeindication]

```swift
func onChorusChannelAudioVolumeIndication(
        speakers: [AgoraRtcAudioVolumeInfo],
        totalVolume: Int)
}
```

领唱的人声音量回调。

开始合唱后，该回调会每 50 ms 触发一次，报告领唱的人声音量信息。

#### 参数 [#参数-27]

- `speakers`：领唱的音量信息，详见 [`AgoraRtcAudioVolumeInfo`](/zh-CN/api-reference/rtc/ios/class-audiovolumeinfo) 数组。
- `totalVolume`：混音后的总音量，取值范围为 [0,255]。

<a id="enum"></a>
<a id="KTVSingRole"></a>
## Enum [#enum]
### KTVSingRole [#ktvsingrole]

```objc
public enum KTVSingRole: Int {
    case soloSinger = 0
    case coSinger
    case leadSinger
    case audience
}
```

K 歌用户角色类型：

- `SoloSinger`：独唱者。
- `CoSinger`：伴唱。
- `LeadSinger`：领唱。
- `Audience`：听众。

<a id="KTVLoadSongFailReason"></a>
### KTVLoadSongFailReason [#ktvloadsongfailreason]

```swift
public enum KTVLoadSongFailReason: Int {
    case noLyricUrl = 0
    case musicPreloadFail
    case cancelled
}
```

歌曲加载失败的原因：

- `noLyricUrl`：(0)  无歌词下载地址。
- `musicPreloadFail`：(1) 歌曲加载失败。请检查你的网络连接或检查 Token 是否过期。
- `cancelled`：(2) 歌曲加载因出现错误而终止。

<a id="ktvswitchrolefailreason"></a>
### KTVSwitchRoleFailReason [#ktvswitchrolefailreason]

```swift
public enum KTVSwitchRoleFailReason: Int {
    case none = 0
    case joinChannelFail
    case noPermission
}
```

用户角色切换结果：

- `none`：角色切换成功。
- `joinChannelFail`：加入频道失败。
- `noPermission`：不支持从当前角色切换为目标角色，请参考[切换说明](/zh-CN/solutions/online-ktv/ktv-scenario/get-started/integrate-ktvapi#5-切换角色)进行角色切换。

<a id="KTVLoadMusicMode"></a>
### KTVLoadMusicMode [#ktvloadmusicmode]

```swift
public enum KTVLoadMusicMode: Int {
    case loadMusicOnly
    case loadLrcOnly
    case loadMusicAndLrc
}
```

歌曲加载模式：

- `loadMusicOnly`：仅加载歌曲。用户在加入合唱成为伴唱时使用此模式。
- `loadLrcOnly`：仅加载歌词。用户角色为观众时使用此模式。
- `loadMusicAndLrc`：（默认）加载歌词和歌曲。用户角色为独唱者时使用此模式。

<a id="ktvloadsongstate"></a>
### KTVLoadSongState [#ktvloadsongstate]

```swift
public enum KTVLoadSongState: Int {
    case idle = -1
    case ok = 0
    case failed
    case inProgress
}
```

歌曲加载的状态：

- `idle`: 空闲状态，未加载歌曲。
- `ok`: 加载成功。
- `failed`: 加载失败。
- `inProgress`: 正在加载中。

<a id="KTVType"></a>
### KTVType [#ktvtype]

```swift
public enum KTVType: Int {
    case normal
    case singbattle
    case singRelay
}
```

K 歌的场景：

- `Normal`：独唱、合唱场景。
- `singBattle`：抢唱场景。
- `singRelay`：接唱场景。

<a id="loadMusicType"></a>
### loadMusicType [#loadmusictype]

```swift
@objc public enum loadMusicType: Int {
    case mcc
    case local
}
```

音乐资源类型：

- `mcc`：（默认）声网内容中心提供的版权音乐。
- `local`：本地音乐。

<a id="class"></a>
<a id="KTVApiConfig"></a>
## Class [#class]
### KTVApiConfig [#ktvapiconfig]

```swift
@objc open class KTVApiConfig: NSObject{
    var appId: String
    var rtmToken: String
    weak var engine: AgoraRtcEngineKit?
    var channelName: String
    var localUid: Int = 0
    var chorusChannelName: String
    var chorusChannelToken: String
    var type: KTVType = .normal
    var maxCacheSize: Int = 10
    var musicType: loadMusicType = .mcc
}
```

小合唱K 歌配置：

- `appId`：你的项目的 App ID。

- `rtmToken`：RTM Token，用于音乐内容中心鉴权。

:::info[信息]
你可以获取临时 RTM Token 用于测试，但在正式生产环境中，你需要自己部署一个 RTM Token 服务器来生成、更新 Token，详见 [部署 RTM Token 服务器](/zh-CN/realtime-media/rtm/build/authentication-and-connection/token-generation)。
:::

- `engine`：[`AgoraRtcEngineKit`](/zh-CN/api-reference/rtc/ios/rtc-interface-class#class_irtcengine) 对象。

- `channelName`：频道名。

- `localUid`：本地用户的 ID。频道内的每个用户 ID 都必须是唯一，需是 32 位无符号整数，建议取值范围为 [1,2³² - 1]。

- `chorusChannelName`: 合唱子频道的名称。在合唱场景下，领唱需要加入两个频道，主频道用户发布人声和播放器的混流，加入合唱子频道发布麦克风采集的音频流，伴唱需要加入合唱子频道来同步领唱的人声。在独唱场景下，该参数可以为空。

- `chorusChannelToken`：合唱场景下，根据合唱子频道的名称和用户 ID 生成的 Token，用于加入合唱子频道时进行鉴权。在独唱场景下，该参数可以为空。

- `type`：K 歌场景，详见 [`KTVType`](#KTVType)。

- `maxCacheSize`：可缓存的音乐资源数量，最多不能超过 50。

- `musicType`：音乐资源类型，详见 [`loadMusicType`](#loadMusicType)。

<a id="KTVSongConfiguration"></a>
### KTVSongConfiguration [#ktvsongconfiguration]

```swift
open class KTVSongConfiguration: NSObject {
    public var songIdentifier: String = ""
    public var mainSingerUid: Int = 0
    public var mode: KTVLoadMusicMode = .loadMusicAndLrc
    public var songCutter: Bool = false
}
```

歌曲加载设置：

- `songIdentifier`：歌曲的唯一标识。如果你使用的是自行维护的曲库，你需要传入该参数，并需确保唯一性。如果你使用的是声网提供的版权音乐，向 `songCode` 传参即可，此参数传空。
- `mainSingerUid`：独唱者的用户 ID。
- `mode`：歌曲加载的模式，详见 [`KTVLoadMusicMode`](#KTVLoadMusicMode)。
- `songCutter`：是否仅演唱歌曲的副歌片段：
  - `true`：仅演唱歌曲的副歌片段。
  - `false`：（默认）演唱完整歌曲。

  :::warning[注意]
  该参数仅在抢唱场景下生效。如果你需要抢唱歌曲的副歌片段，将该参数设为 `true`。
  :::

<a id="GiantChorusConfiguration"></a>
### GiantChorusConfiguration [#giantchorusconfiguration]

```swift
@objc open class GiantChorusConfiguration: NSObject{
    var appId: String
    var rtmToken: String
    weak var engine: AgoraRtcEngineKit?
    var channelName: String
    var localUid: Int = 0
    var chorusChannelName: String
    var chorusChannelToken: String
    var maxCacheSize: Int = 10
    var musicType: loadMusicType = .mcc
    var audienceChannelToken: String = ""
    var musicStreamUid: Int = 0
    var musicChannelToken: String = ""
    var routeSelectionConfig: GiantChorusRouteSelectionConfig = GiantChorusRouteSelectionConfig(type: .byDelay, streamNum: 6)
    var mccDomain: String?
}
```

大合唱K 歌配置：

- `appId`：你的项目的 App ID。

- `rtmToken`：RTM Token，用于音乐内容中心鉴权。

   :::info[信息]
   你可以获取临时 RTM Token 用于测试，但在正式生产环境中，你需要自己部署一个 RTM Token 服务器来生成、更新 Token，详见 [部署 RTM Token 服务器](/zh-CN/realtime-media/rtm/build/authentication-and-connection/token-generation)。
   :::

- `engine`：[`AgoraRtcEngineKit`](/zh-CN/api-reference/rtc/ios/rtc-interface-class#class_irtcengine) 对象。

- `channelName`：听众频道的频道名。

- `localUid`：本地用户的 ID。频道内的每个用户 ID 都必须是唯一，需是 32 位无符号整数，建议取值范围为 [1,2³² - 1]。

- `chorusChannelName`：演唱频道的频道名。领唱和伴唱需要加入该频道发布人声、音乐流。
- `chorusChannelToken`：加入演唱频道的 Token。
- `maxCacheSize`：可缓存的音乐资源数量，默认值为 10，不得超过 50。
- `musicType`：音乐资源类型，详见 [KTVMusicType](/zh-CN/api-reference/online-ktv/ios/ktv-scenario/api/ktv-api)。
- `audienceChannelToken`：加入听众频道的 Token。
- `musicStreamUid`：发布音乐流的用户 ID。领唱需要发布音乐流到频道中。
- `musicChannelToken`：基于发布音乐流的用户 ID 和频道名生成的 Token，用于发布音乐流至频道内时鉴权。
