# 歌词打分组件 Objective-C API (/zh-CN/api-reference/online-ktv/ios/auikaraoke/api/lyrics-api)

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

本文提供在线 K 歌房歌词打分组件相关 API。

:::warning[注意]
本文仅适用于歌词打分组件 v1.1.6。
:::

<a id="karaokeview"></a>
## KaraokeView [#karaokeview]

歌词打分组件的基础接口类，实现歌词同步、演唱评分的主要功能。请确保在主线程中调用该类下的 API。

<a id="init"></a>
### init [#init]

```swift
public convenience init(frame: CGRect, loggers: [ILogger] = [FileLogger(), ConsoleLogger()])
```

初始化 `KaraokeView` 。

在调用 `KaraokeView` 接口类下的其他 API 前，你需要先调用此方法进行初始化。

**参数**

- `frame`：`KaraokeView` 视图的位置和大小。
- `loggers`：日志记录器。SDK 使用 `ILogger` 对象的数组来记录日志。 `ILogger` 数组默认包含一个 `FileLogger` 对象和一个 `ConsoleLogger` 对象。

**返回值**

- 一个 `KaraokeView` 实例。

<a id="parselyricdata"></a>
### parseLyricData [#parselyricdata]

```objective-c
public static func parseLyricData(data: Data) -> LyricModel?
```

解析歌词文件数据。

**参数**

- `data`：需要解析的歌词文件对象。

**返回值**

- 方法调用成功时返回一个对应的歌词数据模型对象，包含歌词文本等信息。
- 方法调用失败时返回 `nil`。

<a id="setlyricdata"></a>
### setLyricData [#setlyricdata]

```swift
public func setLyricData(data: LyricModel?)
```

设置歌词数据模型。

该方法用于设置歌词数据模型，在调用该方法前，你需要先调用 `parseLyricData` 方法解析歌词数据并获取相应的歌词数据模型对象以便于歌词显示。

请在主线程调用该方法。

**参数**

- `data`：[`LyricModel`](#LyricModel) 对象，表示歌词数据模型，包含歌曲的基本信息、歌词信息等。如果为 `nil`，表示当前歌曲为纯音乐，没有对应的歌词信息。

<a id="reset"></a>
### reset [#reset]

```swift
public func reset()
```

重置歌词及打分设置。

当一首歌曲播放完毕后或是播放过程中切到另外一首歌曲时，需要调用该方法来重置歌词、打分设置。

<a id="setprogress"></a>
### setProgress [#setprogress]

```swift
public func setProgress(progress: Int)
```

把歌曲当前的播放进度同步给歌词、打分组件。

在实现歌词和歌曲播放同步时，你需要调用该方法来将歌曲当前的播放进度设置给 `KaraokeView` 以便 `KaraokeView` 根据当前歌曲的播放位置显示对相应的歌词。

调用该方法前你需要先通过内置媒体播放器的 [`getPosition`](/zh-CN/api-reference/rtc/ios/play/mediaplayer/mediaplayer-info#getposition) 方法获取歌曲当前的播放进度。声网建议你每 20 毫秒调用一次该方法来把歌曲的播放进度同步给歌词打分组件。

**参数**

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

<a id="setpitch"></a>
### setPitch[1/2] [#setpitch12]

```swift
public func setPitch(pitch: Double)
```

把获取的实时人声音调同步给打分组件。

当你通过 `AgoraRtcEngineDelegate` 下的 [`reportAudioVolumeIndicationOfSpeakers`](/zh-CN/api-reference/rtc/ios/audio/audio-basic#callback_irtcengineeventhandler_onaudiovolumeindication) 获取本地用户的人声音调后，你需要调用该方法把获取到的实时人声音调同步给打分组件用于演唱评分。

**参数**

- `pitch`：用户的实时人声音调。

<a id="setpitch"></a>
### setPitch[2/2] [#setpitch22]

```swift
 public func setPitch(pitch: Double, progress: Int)
```

把获取的实时人声音调和当前歌曲的播放进度同步给打分组件。

当你通过 `AgoraRtcEngineDelegate` 下的 [`reportAudioVolumeIndicationOfSpeakers`](/zh-CN/api-reference/rtc/ios/audio/audio-basic#callback_irtcengineeventhandler_onaudiovolumeindication) 获取本地用户的人声音调、通过内置媒体播放器的 [`getPosition`](/zh-CN/api-reference/rtc/ios/play/mediaplayer/mediaplayer-info#getposition) 方法获取歌曲当前的播放进度后，你需要调用该方法把获取到的实时人声音调和歌曲的播放进度同步给打分组件。

:::info[信息]
声网推荐 K 歌角色为观众的用户调用该方法。
:::

**参数**

- `pitch`：获取到的实时人声音调。
- `progress`：歌曲当前的播放进度，单位为毫秒。

<a id="setscorelevel"></a>
### setScoreLevel [#setscorelevel]

```swift
public func setScoreLevel(level: Int)
```

设置得分的难易程度。

你可以通过该方法来设置演唱者得分的难易程度。

**参数**

- `level`：难度等级，取值范围为 [0, 100]，默认值为 10。值越小表示难度等级越低，演唱者越容易得分。
  <a id="table"></a>
你可以参考下表来设置不同难度：

| 难度     | 推荐取值 |
| :------- | :------- |
| 低难度   | 3        |
| 中低难度 | 10       |
| 中等难度 | 17       |
| 中高难度 | 25       |
| 高难度   | 35       |

<a id="setscorecompensationoffset"></a>
### setScoreCompensationOffset [#setscorecompensationoffset]

```swift
public func setScoreCompensationOffset(offset: Int)
```

调整演唱评分分数结果。

如果你的业务场景对演唱分数有特殊要求，你可以调用此方法来调整演唱评分的分数结果。

**参数**

- `offset`：额外增加或减少的分数，取值范围为 [-100, 100]，默认值为 0。

声网不建议你同时使用 `setScoreLevel` 和 `setScoreCompensationOffset` 来调整打分机制。

<a id="setscorealgorithm"></a>
### setScoreAlgorithm [#setscorealgorithm]

```swift
public func setScoreAlgorithm(algorithm: IScoreAlgorithm)
```

设置 `IScoreAlgorithm` 对象。

如果你不想使用打分组件默认的打分算法，你可以通过该方法来自定义打分算法。你自定义的打分算法应遵循 `IScoreAlgorithm` 协议。

**参数**

- `algorithm`：实现了 `IScoreAlgorithm` 协议的对象。

<a id="karaokedelegate"></a>
## KaraokeDelegate [#karaokedelegate]

`KaraokeView` 的核心事件回调。

<a id="onkaraokeview"></a>
### onKaraokeView[1/2] [#onkaraokeview12]

```swift
optional func onKaraokeView(view: KaraokeView, didDragTo position: Int)
```

歌词拖动结束的回调。

如果你设置允许歌词拖动（将 `LyricsView` 类下的 `draggable` 设为 `true`），当歌词拖动结束后会触发此回调。你可以通过该回调获取歌词拖动后对应的播放位置。

**参数**

- `view`：KaraokeView 实例。
- `position`：歌词拖动后对应的歌曲播放位置，单位为毫秒。

<a id="onkaraokeview2"></a>
### onKaraokeView[2/2] [#onkaraokeview22]

```swift
optional func onKaraokeView(view: KaraokeView,
                            didFinishLineWith model: LyricLineModel,
                            score: Int,
                            cumulativeScore: Int,
                            lineIndex: Int,
                            lineCount: Int)
```

一行歌词播放完毕回调。

当一行歌词播放完毕后，会触发该回调报告当前行的歌词的得分、累计得分等信息。

**参数**

- `view`：`KaraokeView` 实例。
- `model`：当前歌词行的信息，详见 `LyricLineModel`。
- `score`：当前歌曲行的得分，取值范围 [0, 100]。
- `cumulativeScore`：当前累计得分。
- `lineIndex`：歌词行数的索引号，最小值为 0。
- `lineCount`：歌词的总行数。

<a id="iscorealgorithm"></a>
## IScoreAlgorithm [#iscorealgorithm]

该协议中提供演唱打分相关的 API。

<a id="getlinescore"></a>
### getLineScore [#getlinescore]

```swift
func getLineScore(with toneScores: [ToneScoreModel]) -> Int
```

获取当前歌词行的演唱得分。

当用户唱完一句歌词后，你可以调用该方法来自定义该行歌词的分数计算。

**参数**

- `toneScores`：当前歌词行中每一个字得分的集合，详见 [`ToneScoreModel`](#ToneScoreModel)。

<a id="ilogger"></a>
## ILogger [#ilogger]

该协议提供日志相关的 API。

:::info[信息]
默认情况下，储存歌词打分组件日志的沙盒路径为 `AppData/Documents/Logs`。
:::

<a id="onlog"></a>
### onLog [#onlog]

```swift
onLog(content: String, tag: String?, time: String, level: LoggerLevel)
```

`KaraokeView` 的日志回调。

你可以通过该回调来了解日志的相关内容，可用于排查问题。

:::info[信息]
此回调将会在子线程被调用。
:::

**参数**

- `content`：要记录的日志内容。
- `tag`：日志标签（可选参数），用于进一步分类或标识日志。
- `time`：日志记录的时间。
- `level`：日志的级别，详见 [`LoggerLevel`](#LoggerLevel)。

<a id="lyricsfiledownloaderdelegate"></a>
## LyricsFileDownloaderDelegate [#lyricsfiledownloaderdelegate]

该协议提供歌词下载的相关回调。

<a id="onlyricsfiledownloadprogress"></a>
### onLyricsFileDownloadProgress [#onlyricsfiledownloadprogress]

```swift
func onLyricsFileDownloadProgress(requestId: Int, progress: Float)
```

歌词文件下载进度回调。当你调用 `download` 开始下载歌词文件后，会触发该回调报告当前的下载进度。

**参数**

- `requestId`：本次请求的唯一标识。
- `progress`：歌词文件的下载进度：
  - `[0,1)`：下载中。
  - `1`：下载完成。

<a id="onlyricsfiledownloadcompleted"></a>
### onLyricsFileDownloadCompleted [#onlyricsfiledownloadcompleted]

```swift
func onLyricsFileDownloadCompleted(requestId: Int, fileData: Data?, error: DownloadError?)
```

歌词文件下载完成回调。

当你调用 `download` 开始下载歌词，歌词下载完成后会触发此回调报告歌词下载完成或下载失败的原因。

**参数**

- `requestId`：本次请求的唯一标识。
- `fileData`：歌词文件的二进制数据。如果返回 `nil`，表示歌词文件下载失败。
- `error`：下载出错的原因，详见 [`DownloadError`](#downloaderror)。`nil` 表示没有错误。

<a id="class"></a>
<a id="downloaderror"></a>
## Class [#class]
### DownloadError [#downloaderror]

```swift
public class DownloadError: NSError {
    public let msg: String
    public let domainType: DownloadErrorDomainType
    public var originalError: NSError?
}
```

歌词文件下载出错的原因。

**属性**：

- `msg`：错误信息。
- `domainType`：出错的原因，详见 [`DownloadErrorDomainType`](#downloaderrordomaintype)。
- `originalError`：内部原因。

<a id="lyricsview"></a>
### LyricsView [#lyricsview]

```swift
public class LyricsView: UIView {
    public var noLyricTipsText: String = "无歌词"
    public var noLyricTipsColor: UIColor = .orange
    public var noLyricTipsFont: UIFont = .systemFont(ofSize: 17)
    public var waitingViewHidden: Bool = false
    public var inactiveLineTextColor: UIColor = .white
    public var activeLineUpcomingTextColor: UIColor = .white
    public var activeLinePlayedTextColor: UIColor = .colorWithHex(hexStr: "#FF8AB4")
    public var inactiveLineFontSize = UIFont(name: "PingFangSC-Semibold", size: 15)!
    public var activeLineUpcomingFontSize = UIFont(name: "PingFangSC-Semibold", size: 18)!
    public var maxWidth: CGFloat = UIScreen.main.bounds.width - 30
    public var lyricLineSpacing: CGFloat = 10
    public let firstToneHintViewStyle: FirstToneHintViewStyle = .init()
    public var draggable: Bool = false
}
```

歌词组件界面设置。

**属性**：

- `noLyricTipsText`：无歌词时显示的提示文字。

- `noLyricTipsColor`：无歌词时显示的提示文字的颜色。

- `noLyricTipsFont`：无歌词时显示的提示文字的大小。

- `waitingViewHidden`：在播放歌曲前奏时是否显示等待圆点。

- `inactiveLineTextColor`：未在当前播放的歌词的颜色。

- `activeLineUpcomingTextColor`：当前歌词行中，即将播放的歌词的颜色。

- `activeLinePlayedTextColor`：当前歌词行中，已播放的歌词的颜色。

- `inactiveLineFontSize`：未在当前播放的歌词文字大小。

- `activeLineUpcomingFontSize`：即将播放的歌词文字大小。

- `maxWidth`：歌词视图的最大宽度（pt）。

- `lyricLineSpacing`：歌词行间距。

- `FirstToneHintViewStyle`：等待圆点的风格，详见 [`FirstToneHintViewStyle`](#FirstToneHintViewStyle)。

- `draggable`：是否允许歌词拖动：

  - `true`：允许歌词拖动。

  - `false`：（默认）不允许歌词拖动。

<a id="scoringview"></a>
### ScoringView [#scoringview]

```swift
public class ScoringView: UIView {
    public var viewHeight: CGFloat = 120
    public var topSpaces: CGFloat = 0
    public var defaultPitchCursorX: CGFloat = 100
    public var standardPitchStickViewHeight: CGFloat = 3
    public var movingSpeedFactor: CGFloat = 120
    public var standardPitchStickViewColor: UIColor = .gray
    public var standardPitchStickViewHighlightColor: UIColor = .colorWithHex(hexStr: "#FF8AB4")
    public var localPitchCursorOffsetX: CGFloat = -3
    public var localPitchCursorImage: UIImage? = nil
    public var particleEffectHidden: Bool = false
    public var emitterImages: [UIImage]?
    public var hitScoreThreshold: Float = 0.7
}
```

打分组件界面设置。

**属性**：

- `viewHeight`：打分视图的高度。

- `topSpaces`：打分视图和 `KaraokeView` 顶部的距离。

- `defaultPitchCursorX`：游标出现的起始位置。

- `standardPitchStickViewHeight`：标准音高线的高度。

- `movingSpeedFactor`：标准音高线的移动速度。

- `standardPitchStickViewColor`：标准音高线默认的颜色。

- `standardPitchStickViewHighlightColor`：击中标准音高线时的颜色。

- `localPitchCursorOffsetX`：游标在 X 轴上的偏移量，游标的中心到竖线的 `centerX` 的距离。

  - 0：游标中心点和竖线中心点重合。
  - < 0：游标向左偏移。
 - &gt; 0：游标向右偏移。

- `localPitchCursorImage`：自定义音高显示器样式。

- `particleEffectHidden`：是否隐藏粒子动画效果：

  - `true`：隐藏粒子动画效果。
  - `false`：（默认）不隐藏粒子动画效果。

- `emitterImages`：自定义粒子动画样式。

- `hitScoreThreshold`：动画效果阈值，取值范围为为 (0, 1]。例如，如果你将该值设为 0.1，则一行歌词得分超过 10 分，就会触发音高线着色和粒子动画效果。

<a id="lyricsfiledownloader"></a>
### LyricsFileDownloader [#lyricsfiledownloader]

```swift
public class LyricsFileDownloader: NSObject {
    @objc public var maxFileNum: UInt8 = 50
    @objc public var maxFileAge: UInt = 8 * 60 * 60
    @objc public weak var delegate: LyricsFileDownloaderDelegate?
    @objc public var delegateQueue = DispatchQueue.main

  	public override init()
    @objc public func download(urlString: String) -> Int
    @objc public func cancelDownload(requestId: Int)
    @objc public func cleanAll()
}
```

歌词文件下载及管理。

**属性：**

- `maxFileNum`：可缓存的歌词文件最大数量，默认值为 50。如果超过你所设置的值，歌词打分组件会自动清除最早缓存的歌词文件。
- `maxFileAge`：歌词文件的有效期，默认为 8 小时。如歌词文件过期，你需要重新下载才可以继续使用。
- `delegate`：`LyricsFileDownloaderDelegate` 对象，详见 [`LyricsFileDownloaderDelegate`](#lyricsfiledownloaderdelegate)。
- `delegateQueue`：代理方法执行的队列，默认为主队列。

**方法：**

<a id="init"></a>
#### init [#init-1]

初始化歌词下载器。

**返回值：** 一个 `LyricsFileDownloader` 实例。

<a id="download"></a>
#### download [#download]

下载歌词文件。

**参数：**

- `urlString`：需要下载的歌词文件的 URL。如果你需要下载声网版权音乐的歌词，你需要先调用 [`getLyricWithSongCode`](/zh-CN/api-reference/rtc/ios/play/drm) 获取指定歌曲的歌词下载地址，然后通过由此触发的 [`onLyricResult`](/zh-CN/api-reference/rtc/ios/play/drm#callback_imusiccontentcentereventhandler_onlyricresult) 回调来获取歌词的 `url`。

**返回值：**

- 方法调用成功时返回一个 `requestId`，为本次请求的唯一标识。
- < 0：方法调用失败。如 `-1` 表示参数无效。

<a id="canceldownload"></a>
#### cancelDownload [#canceldownload]

取消下载歌词文件。

**参数：**

- `requestId`：请求的唯一标识，当你成功调用 `download` 方法后会返回一个 `requestId`，将其传入此参数来取消该次歌词下载。

<a id="cleaall"></a>
#### cleanAll [#cleanall]

清除所有已缓存的歌词文件。

<a id="LyricToneModel"></a>
### LyricToneModel [#lyrictonemodel]

```swift
public class LyricToneModel: NSObject {
    @objc public let beginTime: Int
    @objc public let duration: Int
    @objc public var word: String
    @objc public let pitch: Double
}
```

一行歌词中，每一个词的音高数据。

**属性**：

- `beginTime`：歌词开始的时间，单位为毫秒。
- `duration`：歌词的总时长，单位为毫秒。
- `word`：歌词内容。
- `pitch`：该词的音高。

<a id="ToneScoreModel"></a>
### ToneScoreModel [#tonescoremodel]

```swift
public class ToneScoreModel: NSObject {
    @objc public let tone: LyricToneModel
    @objc public var score: Float
    var scores = [Float]()
}
```

歌词中每一个字的得分信息。

**属性**：

- `tone`：每一个字对应的音高信息，详见 [`LyricToneModel`](#LyricToneModel)。
- `score`：每一个字的得分，取值范围 [0, 100]。

<a id="LyricModel"></a>
### LyricModel [#lyricmodel]

```swift
public class LyricModel: NSObject {
    @objc public var name: String
    @objc public var singer: String
    @objc public var lines: [LyricLineModel]
    @objc public var preludeEndPosition: Int
    @objc public var duration: Int
    @objc public var hasPitch: Bool
}
```

歌词数据模型。

**属性**：

- `name`：歌曲名称。

- `singer`：歌手。

- `lines`：歌词行数信息，详见 [`LyricLineModel`](#LyricLineModel)。

- `preludeEndPosition`：前奏结束的时间，单位为毫秒。

- `duration`：歌词总演唱时长，单位为毫秒。

- `hasPitch` ：该歌曲是否有标准音高线数据：

  - `true`：有标准音高线数据。

  - `false`：没有标准音高线数据。

<a id="LyricLineModel"></a>
### LyricLineModel [#lyriclinemodel]

```swift
public class LyricLineModel: NSObject {
    @objc public var beginTime: Int
    @objc public var duration: Int
    @objc public var content: String
    @objc public var tones: [LyricToneModel]
}
```

歌词行的相关信息。

**属性**：

- `beginTime`：该行歌词开始的时间，单位为毫秒。
- `duration`：该行歌词的总时长，单位为毫秒。
- `content`：该行歌词的内容。
- `tones`：每一个词的音高信息，详见 [`LyricToneModel`](#LyricToneModel)。

<a id="FirstToneHintViewStyle"></a>
### FirstToneHintViewStyle [#firsttonehintviewstyle]

```swift
public class FirstToneHintViewStyle: NSObject {
    public var backgroundColor: UIColor = .gray
    public var size: CGFloat = 10
    public var bottomMargin: CGFloat = 0
}
```

等待圆点的风格设置。

**属性**：

- `backgroundColor`：等待圆点的颜色。
- `size`：等待圆点的半径（pt）。
- `bottomMargin`：等待圆点和歌词之间的间距。

<a id="consolelogger"></a>
### ConsoleLogger [#consolelogger]

```objective-c
public class ConsoleLogger: NSObject, ILogger {
    @objc public func onLog(content: String,
                            tag: String?,
                            time: String,
                            level: LoggerLevel)
}
```

实现 `ILogger` 协议的日志记录器，用于将消息打印到控制台。

- `content`：要记录的日志内容。
- `tag`：日志标签（可选参数），用于进一步分类或标识日志。
- `time`：日志记录的时间。
- `level`：日志的级别，详见 [`LoggerLevel`](#LoggerLevel)。

<a id="filelogger"></a>
### FileLogger [#filelogger]

```objective-c
public class FileLogger: NSObject, ILogger {
    @objc public func onLog(content: String,
                            tag: String?,
                            time: String,
                            level: LoggerLevel) {
    }
}
```

实现 `ILogger` 协议的日志记录器，用于将日志信息写入日志文件。

- `onLog`：日志文件的回调。
  - `content`：要记录的日志内容。
  - `tag`：日志标签（可选参数），用于进一步分类或标识日志。
  - `time`：日志记录的时间。
  - `level`：日志的级别，详见 [`LoggerLevel`](#LoggerLevel)。

<a id="enum"></a>
<a id="downloaderrordomaintype"></a>
## Enum [#enum]
### DownloadErrorDomainType [#downloaderrordomaintype]

```swift
@objc public enum DownloadErrorDomainType: Int {
    case general = 0
    case repeatDownloading = 1
    case httpDownloadError = 2
    case httpDownloadErrorLogic = 3
    case unzipFail = 4
}
```

歌词文件下载失败的原因。

- `general`：(0) 一般错误，无明确归因。
- `repeatDownloading`：(1) 重复的 URL 请求。
- `httpDownloadError`：(2) 执行 HTTP 请求时出错，如超时。
- `httpDownloadErrorLogic`：(3) HTTP 协议逻辑层错误，如 `500`。
- `unzipFail`：(4) 解析歌词文件失败。

<a id="LoggerLevel"></a>
### LoggerLevel [#loggerlevel]

```swift
public enum LoggerLevel: UInt8, CustomStringConvertible {case debug, info, warning, error}
```

日志等级。

- `debug`：调试级别。
- `info`: 信息级别。
- `warning`: 警告级别。
- `error`: 错误级别。
