版权音乐

更新时间: 2023/10/12 01:41:32

网易云信支持独立集成版权音乐,实现在线 KTV 场景中搜索、下载和播放版权音乐的能力。

注意事项

  • 使用版权音乐时,请务必在播放界面明显位置用图标说明该音乐内容对应的版权方,界面效果类似如下图所示。版权Logo的图标请参考曲库示例项目源码
  • 您可以通过 channel 接口查询音乐的版权方。

点歌.png

前提条件

请确认您已完成以下操作:

API 时序图

版权音乐的实现流程如下图所示。

sequenceDiagram
    autonumber

  participant 应用App
  participant 曲库SDK
  participant 版权音乐服务端

  Note over 应用App, 版权音乐服务端: 歌曲列表 
  应用App->>曲库SDK: 获取歌曲列表 getSongList
  曲库SDK->>版权音乐服务端: 获取歌曲列表
  版权音乐服务端-->>曲库SDK: 返回歌曲列表
  曲库SDK-->>应用App: 返回歌曲列表 Callback<List<NECopyrightedSong>>

  Note over 应用App, 版权音乐服务端: 歌曲/伴奏下载
  应用App->>曲库SDK: 预加载歌曲 preloadSong
  曲库SDK->>版权音乐服务端: 获取歌曲详情
  版权音乐服务端-->>曲库SDK: 返回歌曲资源信息(包括歌词、MIDI、歌曲下载地址地址等)
  曲库SDK->>曲库SDK: 从远端加载歌曲/伴奏
  曲库SDK-->>应用App: 返回歌曲预加载完成回调
  应用App->>曲库SDK: 请求原唱/伴奏歌曲URI getSongURI
  曲库SDK-->>应用App: 返回原唱/伴奏URI
  应用App->>应用App: 根据歌曲URI获得歌曲音频

  Note over 应用App, 版权音乐服务端: 获得歌词
  应用App->>曲库SDK: 请求歌词 getLyric
  曲库SDK-->>应用App: 返回歌词

  Note over 应用App, 版权音乐服务端: 获得MIDI
  应用App->>曲库SDK: 请求MIDI getMidi
  曲库SDK-->>应用App: 返回MIDI

示例项目源码

曲库的示例项目源码请参见 曲库示例项目源码

步骤1 初始化组件

  1. 调用 NECopyrightedMedia getInstance 接口创建版权音乐对象。

    NECopyrightedMedia * copyRight = [NECopyrightedMedia getInstance];
    
  2. 调用 initialize 接口初始化组件。

/// 初始化 NECopyrightedMedia
/// @param appkey appkey
/// @param token token
/// @param userUuid userUuid
/// @param extras 填入Nil
/// @param callback 异步回调 NSError 为Nil 则成功
- (void)initialize:(NSString *_Nonnull)appkey
             token:(NSString *_Nonnull)token
          userUuid:(NSString *_Nullable)userUuid
            extras:(NSDictionary *_Nullable)extras
          callback:(void (^)(NSError *_Nullable error))callback;
  1. 调用 NECopyrightedMedia.setSongScene 接口,指定音乐场景为 K 歌的场景。

    版权曲库支持听歌场景(TYPE_LISTENING_TO_MUSIC)和 K 歌场景(TYPE_KTV),您需要在初始化曲库 SDK 后指定对应的场景。如果您的应用既需要 K 歌场景,又需要听歌场景,请在获取歌曲列表前重新调用本接口设置对应的场景即可。

    // 设置K歌场景
    NECopyrightedMedia.getInstance().setSongScene(TYPE_KTV)
    
  2. 调用 setEventHandler 接口注册事件通知回调。

    当您的曲库 Token 过期时,会触发 onTokenExpired 回调。此时,您需要参见曲库动态 Token 鉴权生成新的 Token,并调用 renewToken 更新 Token 后才能继续调用 NECopyrightedMedia SDK 的API。

    //设置动态Token过期代理
    [[NECopyrightedMedia getInstance] setEventHandler:self];
    //回调如下
    - (void)onTokenExpired {
    // Token过期
    //此处需要申请新的realTimeToken
    }
    
  3. 调用 renewToken 接口更新 Token。

    [[NECopyrightedMedia getInstance]       renewToken:copyrightedToken];
    

    初始化操作完毕,如果能正常调用以下接口,表示初始化成功。

步骤2 获取歌曲列表

用户可以通过搜索、请求歌曲列表两种方式获取歌曲列表。

通过搜索获取歌曲

调用 NECopyrightedMedia.searchSong 接口获取搜索的歌曲列表和歌曲的song ID。

参数 类型 描述
keyword String 搜索的关键字。
channel Integer 版权渠道,默认不传则包含所有签约渠道。
  • 1:网易云音乐
  • 2: 咪咕
  • 3:HIFIVE
pageNum Integer 页码。 默认值为 0。
pageSize Integer 每页显示的行数,默认值为 20。
callback Callback 回调

示例代码如下:

[[NECopyrightedMedia getInstance]
        searchSong:keyword
        channel:nil
           pageNum:pageNum
          pageSize:pageSize
          callback:^(NSArray<NECopyrightedSong *> *_Nonnull songList, NSError *_Nonnull error) {
            if (error) {
                NSLog(@"搜索歌曲列表失败 --- %@", error.description);
            } else {
                NSLog(@"搜索歌曲列表成功");
            }
          }]

通过推荐获取歌曲

调用getSongList 接口获取推荐歌单的歌曲 song ID。

/**
 * 歌曲列表
 * @param tags 设置nil 预留字段
 * @param channel 版权渠道,默认不传则包含所有签约渠道。1:网易云音乐; 2: 咪咕;3:HIFIVE
 * @param pageNum 页码
 * @param pageSize 页面size 默认 20
 * @param callback 回调
 */
- (void)getSongList:(NSArray<NSString *> *_Nullable)tags
            channel:(NSNumber *_Nullable)channel
            pageNum:(NSNumber *_Nullable)pageNum
           pageSize:(NSNumber *_Nullable)pageSize
           callback:(void (^)(NSArray<NECopyrightedSong *> *songList, NSError *error))callback;

示例代码如下:

[[NECopyrightedMedia getInstance] getSongList:nil channel:nil pageNum:@(0) pageSize:@(NEPageNumber) callback:^(NSArray<NECopyrightedSong *> * _Nonnull songList, NSError * _Nonnull error) {
        if (error) {
            NSLog(@"获取歌曲列表失败");
        }else{
            NSLog(@"获取歌曲列表成功");
            for (NECopyrightedSong *songItem in songList) {
              //遍历数据
                   NSLog(@"songDta --- %@",songItem);
                }
        }
    }];

通过榜单获取歌曲

调用getHotSongList 接口获取推荐歌单的歌曲 song ID。

/**
 * 榜单歌曲查询
 * @param hotType 热门类型
 * @param hotDimension 场景类型
 * @param channel 渠道 SongChannel: 可为空
 * @param pageNum 页码
 * @param pageSize 页面size 默认 20
 * @param callback 回调
 */
- (void)getHotSongList:(NECopyrightedHotType)hotType
          hotDimension:(NECopyrightedHotDimension)hotDimension
               channel:(NSNumber *_Nullable)channel
               pageNum:(NSNumber *_Nullable)pageNum
              pageSize:(NSNumber *_Nullable)pageSize
              callback:
                  (void (^)(NSArray<NECopyrightedHotSong *> *songList, NSError *error))callback;

示例代码如下:

[[NECopyrightedMedia getInstance] getHotSongList:HOTTYPE_DEFAULT channel:@1 hotDimension:HOTDIMENSION_PLATFORM pageNum:@0 pageSize:@20 callback:^(NSArray<NECopyrightedHotSong *> * _Nonnull songList, NSError * _Nonnull error) {
        if (error) {
            NSLog(@"获取歌曲列表失败");
        }else{
            NSLog(@"获取歌曲列表成功");
            for (NECopyrightedSong *songItem in songList) {
                //遍历数据
                NSLog(@"songDta --- %@",songItem);
            }
        }
    }];

步骤3 下载歌曲资源

调用 preloadSong接口下载歌曲资源,包括原唱、伴奏、歌词和MIDI。

/**
 * 预加载 Song 数据
 *
 * @param songId 歌曲id
 * @param channel 渠道
 * @param observe 观察者
 */
- (void)preloadSong:(NSString *)songId
            channel:(SongChannel)channel
            observe:(id<NESongPreloadProtocol> _Nullable)observe;

示例代码如下:

//遵循协议:
<NESongPreloadProtocol>
//请求示例:
[[NECopyrightedMedia getInstance] preloadSong:songModel.songId channel:CLOUD_MUSIC observe:self];

//请求回调:
//开始下载回调
-(void)onPreloadStart:(NSString *)songId channel:(SongChannel)channel{
    NSLog(@"onPreloadStart -- songId = %@",songId);
}
//下载进度回调
-(void)onPreloadProgress:(NSString *)songId channel:(SongChannel)channel progress:(float)progress{
    NSLog(@"onPreloadProgress -- songId = %@ ; progress = %.2f",songId,progress);
}
//下载失败/完成回调
-(void)onPreloadComplete:(NSString *)songId channel:(SongChannel)channel error:(NSError * _Nullable)error{
    if(error){
        NSLog(@"onPreloadComplete error reason:%@",error.description);
    }else{
        NSLog(@"onPreloadComplete")
    }
}

步骤4 取消预加载歌曲数据

调用cancelPreloadSong接口取消预加载歌曲数据。

/// 取消预加载 Song 数据
/// @param songId 歌曲id
/// @param channel 渠道 需要是songId对应的渠道
- (void)cancelPreloadSong:(NSString *)songId channel:(SongChannel)channel;

示例代码如下:

[[NECopyrightedMedia getInstance]cancelPreloadSong:songItem.songId channel:songItem.channel];

步骤5 检测是否已预加载歌曲数据

调用isSongPreloaded接口检测是否已预加载歌曲数据。

/**
 * 检测是否已预加载 Song 数据
 *
 * @param songId 歌曲id
 * @param channel 版权渠道,1:网易云音乐; 2: 咪咕;3:HIFIVE
 * @return 是否已预加载
 */
- (bool)isSongPreloaded:(NSString *)songId channel:(SongChannel)channel;

示例代码如下:

[[NECopyrightedMedia getInstance] isSongPreloaded:songItem.songId channel:songItem.channel];

步骤6 生成歌曲 URI

调用 getSongURI 获取 伴奏/原唱 的本地路径

/**
 * 原唱&伴奏:传给 NERtc 播放的 URI
 *
 * @param songId           音乐 ID
 * @param channel         版权渠道,1:网易云音乐; 2: 咪咕;3:HIFIVE
 * @param songResType           1:原唱,2:伴奏
 * @return 返回资源的本地路径
 */
- (NSString *_Nullable)getSongURI:(NSString *_Nonnull)songId
                          channel:(SongChannel)channel
                      songResType:(SongResType)songResType;
          

示例代码如下:

return [[NECopyrightedMedia getInstance] getSongURI:songItem.songId channel:songItem.channel songResType:SongResType];

步骤7 获得歌词内容

调用getLyric获取加载完成后的歌词内容

/**
 * 歌词
 * @param songId           音乐 ID
 * @param channel         版权渠道,1:网易云音乐; 2: 咪咕;3:HIFIVE
 * @return 歌词内容
 */
- (NSString *_Nullable)getLyric:(NSString *_Nonnull)songId channel:(SongChannel)channel;

示例代码如下:

[[NECopyrightedMedia getInstance] getLyric:songItem.songId channel:songItem.channel];

步骤8 获得打分内容

调用getMidi获取加载完成后的打分内容

/**
 * 打分
 * @param songId           音乐 ID
 * @param channel 版权渠道,1:网易云音乐; 2: 咪咕;3:HIFIVE
 * @return 打分内容
 */
- (NSString *_Nullable)getPitch:(NSString *_Nonnull)songId channel:(SongChannel)channel;

示例代码如下:

[[NECopyrightedMedia getInstance] getPitch:songItem.songId channel:songItem.channel];

步骤9 预加载歌词内容

调用preloadSongLyric 接口单独加载歌词

/// 预加载歌词
/// @param songId  音乐ID
/// @param callback 回调
- (void)preloadSongLyric:(NSString *)songId
                 channel:(SongChannel)channel
                callback:(void (^)(NSString *_Nullable content, NSString *_Nullable lyricType,
                                   NSError *_Nullable error))callback;

示例代码如下:

[[NECopyrightedMedia getInstance] preloadSongLyric:songModel.songId channel:songItem.channel callback:^(NSString * _Nullable content, NSString * _Nullable lyricType, NSError * _Nullable error) {
    if (error) {
        NSLog(@"下载歌词失败");
    }else{
        NSLog(@"下载歌词成功");
    }
}];

步骤10 使用 NERTC 播放并发送音乐

  1. 调用 preloadSong 接口预加载歌词。
  2. 加载成功后,加入音视频房间,调用 NERTC 的 playEffectWitdId 接口播放音乐。

示例代码如下:

更详细的示例代码请参考曲库示例项目源码

// 调用以下代码会播放并上行伴奏:
  NERtcCreateAudioEffectOption *aOption = [[NERtcCreateAudioEffectOption alloc] init];
    aOption.path = accompanyPath;
    aOption.playbackVolume = 播放音量;
    aOption.sendVolume = 发送音量;
    aOption.sendEnabled = true;
    aOption.loopCount = 1;
    aOption.sendWithAudioType = kNERtcAudioStreamTypeMain;
    int aCode = [[NERtcEngine sharedEngine] playEffectWitdId:optPureEffectId effectOption:aOption];//optPureEffectId 自己定义的伴奏effect id
// 调用以下代码会播放并上行原唱:
    NERtcCreateAudioEffectOption *oOption = [[NERtcCreateAudioEffectOption alloc] init];
    oOption.path = originalPath;
    oOption.playbackVolume = aCode == 0 ? 0 : 播放音量; // 如果伴奏播放失败则播放原唱
    oOption.sendVolume = aCode == 0 ? 0 : 发送音量;
    oOption.sendEnabled = true;
    oOption.loopCount = 1;
    oOption.sendWithAudioType = kNERtcAudioStreamTypeMain;
    [[NERtcEngine sharedEngine] playEffectWitdId:optPureEffectId effectOption:aOption]; //optOriginalEffectId 自己定义的原唱effect id

此文档是否对你有帮助?
有帮助
去反馈
  • 注意事项
  • 前提条件
  • API 时序图
  • 示例项目源码
  • 步骤1 初始化组件
  • 步骤2 获取歌曲列表
  • 通过搜索获取歌曲
  • 通过推荐获取歌曲
  • 通过榜单获取歌曲
  • 步骤3 下载歌曲资源
  • 步骤4 取消预加载歌曲数据
  • 步骤5 检测是否已预加载歌曲数据
  • 步骤6 生成歌曲 URI
  • 步骤7 获得歌词内容
  • 步骤8 获得打分内容
  • 步骤9 预加载歌词内容
  • 步骤10 使用 NERTC 播放并发送音乐