全民K歌IOT开放平台
  1. KtvSDK3.0接入说明
全民K歌IOT开放平台
  • 厂商合作流程
  • 快速接入K歌开放平台流程
  • SDK bug提单规范
  • 如何在线调试接口
  • 常见问题FAQ
  • 开放平台API错误码说明
  • 开放平台接入指南
    • 登录鉴权方式介绍V2(推荐)
    • 如何申请接入
    • CDK权限申请流程
    • 暗账号绑定明账号对接文档
    • 获取应用级token
    • 获取登录二维码
    • 查询二维码的状态
    • 获取用户级token
    • 刷新用户级token
    • 暗账号解绑K歌uid
    • 获取暗账号绑定信息
  • KtvSDK3.0接入说明
    • 厂商合作流程
    • bug提单规范
    • KtvSDK-接入指南
    • KtvSDK-打分
    • KtvSDK-登录
    • KtvSDK-歌词
    • KtvSDK-播放
    • 多屏一起唱---歌词与打分适配
    • 3.0新打分样式及五维打分
    • KtvSDK-多屏渲染
    • KtvSDK-2.0升级到3.0版本迁移指南
    • KtvSDK-3.0版本新功能
    • KtvSDK-Android4.4设备G2证书兼容处理
    • KtvSDK-播放页实现示例
    • KtvSDK-常见问题FAQ
    • KtvSDK-低性能设备处理
    • KtvSDK-反馈
    • KtvSDK-缓存管理
    • KtvSDK-切换音频视频清晰度
    • KtvSDK-跳过前奏
    • Ktv支付-米大师支付
    • 播放失败错误码说明
    • 作品录音、合成与播放2.0版
  • 基础类
    • tagId对照表
    • 歌曲详情
    • 查询mv的播放地址
    • 搜索
    • 搜索联想
    • 查询歌手歌曲
    • 获取歌曲歌词文件
    • Q音歌曲mid映射K歌
    • 短剧播放链接
    • 查询应用限免配置
    • 转换Q音或酷狗歌曲ID
  • 运营类
    • 排行榜id说明
    • 获取城市id列表
    • 获取专题分类列表
    • 获取云端配置
    • 热门ugc
    • 热搜词
    • 排行榜
    • 获取专题下歌曲信息
    • 获取车联渠道映射
    • 热门推荐
    • (新)排行榜
    • 综合歌单列表查询
    • 设置缓存设备
    • TV版分类歌单列表
    • 获取用户协议
    • 综合歌单列表查询(海外)
    • 榜单列表查询(海外)
    • 自建歌单列表查询(海外)
    • 获取广告配置
    • 拉取短剧合集的列表
  • 用户类
    • 用户信息查询
    • 删除用户UGC作品
    • 获取推荐/翻唱作品
    • 获取同城作品
    • 用户作品列表
    • 获取好友作品
    • UGC作品详情
    • 更改作品访问权限
    • 用户个推歌单
  • 支付类
    • 支付接入流程
    • 订单发货使用简述
    • 开通设备会员限免简述
    • 订单发货中通用sign计算规则
    • 通用返回结构
    • 【CDK】CDK兑换
    • 【CDK】生成CDK
    • 【CDK】CDK召回
    • 【CDK】CDK状态查询
    • 【三方支付】订单发货
    • 【三方支付】手机号发货
    • 【三方支付】订单状态查询
    • 【米大师支付】获取会员商品列表
    • 【米大师支付】未登录-查询会员商品列表
    • 【米大师支付】支付下单
    • 【米大师支付】支付成功通知
    • 【米大师支付】查询用户支付成功订单记录
    • 查询设备以及用户是否有赠送资格
    • 查询设备限免剩余时长
    • 设备会员迁移
    • 查询会员赠送时长
    • 同步支付订单接口
    • 【三方支付】存量会员迁移领取查询
    • 【三方支付】存量会员迁移接口
    • 授权设备体验会员
    • 查询用户会员信息
    • 【三方支付】超会发货
    • 取消授权设备体验会员
  • 用户作品-文件类
    • callback_url说明
    • 上传音频源文件
    • (服务端)上传音频作品的链接
  • 通用类
    • 【厂商定制】匹配搜索
    • 获取kg的短链接
  1. KtvSDK3.0接入说明

KtvSDK-接入指南

1.sdk集成

1.1 sdk及demo包下载

sdk只支持本地引入aar,不支持maven方式接入
demo下载地址
sdk下载地址

若有权限问题,请查看SDK合作流程及规范。

1.2 demo包运行说明

在local.properties中设置K歌开放平台的appId与appKey:

KTV_SDK_APP_ID=
# 正式环境appKey,没有则不填
KTV_SDK_APP_KEY=
# 测试环境appKey,没有则不填
KTV_SDK_TEST_APP_KEY=

KtvSDK默认是正式环境,如果需要手动切换sdk的环境,可在初始化sdk后,调用KtvSdk.setProductEnv()方法来切换,重启应用后生效。
在demo中,也可打开“SDK开发者设置”页,切换环境:

image.png
推荐运行环境:

  • jdk1.8
  • gradle-wrapper.properties中的gradle版本: gradle-6.9

1.3 sdk集成

KtvSdk通过aar的方式对外提供,三方按照aar的方式集成即可:

  • 将 AAR 包复制到项目的 libs 目录下
  • 在项目的 build.gradle 文件中添加以下代码:
repositories {
    flatDir {
        dirs 'libs'
    }
}
  • 在项目的 app 模块的 build.gradle 文件中添加以下代码:
dependencies {
    implementation(name: 'library-name', ext: 'aar')
}

sync之后即可使用;

1.3.1 添加三方依赖

由于sdk依赖部分三方库,但未打包到sdk中,需要宿主在项目的build.gradle 文件中添加以下依赖

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.3"
implementation "com.squareup.okhttp3:okhttp:3.12.0"
implementation "com.google.zxing:core:3.3.3"
implementation "com.tencent:mmkv:1.0.23"
implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementaion "androidx.constraintlayout:constraintlayout:2.0.1"
implementation "androidx.multidex:multidex:2.0.1"
implementation "com.google.code.gson:gson:2.6.2"
implementation "androidx.fragment:fragment-ktx:1.2.5"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.21"
implementation("com.google.android.exoplayer:exoplayer-core:2.18.5") {
    exclude group: 'androidx.core'
    exclude group: 'androidx.annotation'
    exclude group: 'androidx.fragment'
}

1.3.2 添加混淆配置

由于sdk已做混淆,因此app配置sdk相关类不混淆即可:

-keep class com.tme.**{*;}
-keep class com.tencent.karaoke.**{*;}
-keep class com.tencent.qmsq.**{*;}
-keep class com.tencent.news.**{*;}
-keep class com.tencent.threadpool.**{*;}
-keep class com.tencent.libunifydownload.**{*;}
-keep class com.tencent.karaoketv.**{*;}
-keep class com.tencent.qqmusic.business.lyricnew.**{*;}
-keep class com.ola.star.**{*;}
-keep class com.ola.qmsq.**{*;}
-keep class ksong.support.**{*;}
-keep class easytv.common.**{*;}

其余需要app主动依赖的三方开源库,按照三方库要求的混淆规则配置即可

1.4 sdk初始化

建议在application中初始化:

KtvSdk.init(application: Application, ktvInitParams: KtvInitParams)

其中ktvInitParams是sdk初始化需要传入的参数, 主要设置内容如下:

data class KtvInitParams(
    //宿主信息
    val hostInfo: IKAppInfo,
    //播放阻断相关处理
    val appRequestProvider: AppRequestProvider,
    //图片加载实现
    val imageLoader: IKImageLoader,
    //Android权限请求实现,一般不需要自定义,使用sdk内置实现即可
    val permissionProvider: IKPermissionProvider? = null,
    //日志实现,默认打印到logcat
    var logger: IKLog? = null,
)

1.4.1 hostInfo参数说明

IKAppInfo 用于声明宿主app的基本信息。

public interface IKAppInfo {

    /**
     * appId,可向K歌开放平台申请获得
     * 必传
     * @return
     */
    String getAppId();

    /**
     * 开放平台appkey,可向K歌开放平台申请获得
     * 自实现登录方式不需要传
     * @return
     */
    String getAppKey();

    /**
     *  平台标识
     *  车机:52
     *  智能音箱或其它:53
     *  必传
     * @return
     */
    String getPlatformId();

    /**
     * 厂商自己的设备id,必传
     */
    String getImei();

    /**
     * 厂商用户id,可选
     */
    String getUid();

    /**
     * 厂商渠道号,需改为真实的渠道号, 一般为appid
     */
    String getChannelId();

    /**
     * 宿主是否为正式环境,必传
     */
    boolean isProductEnv();

    /**
     * 是否为开发调试模式,若是,sdk内部应用一些开发调试配置,有助于问题定位,但对sdk性能可能有影响。
     */
    boolean isDevMode();

    /**
     * app唯一版本标识,可选。非腾讯类的app不用传
     */
    String getQua();

    /**
     * 要传给sdk的附加信息,可选
     */
    Map<String, String> getExtraInfo();
}

HostInfo 参照demo中SampleHostInfo:继承KAppInfoAdapter,提供宿主信息,如果方法返回类型不可空,则属于必填参数,可空则不强制要求,如果有其他需要传入的设备信息,通过getExtraInfo的Map传入。

KtvSDK默认是正式环境,如果需要手动切换sdk的环境,可在初始化sdk后,调用KtvSdk.setProductEnv()方法来切换。

1.4.2 播放阻断:AppRequestProvider

全民K歌提供一天内免费唱几首的功能(具体次数与产品确认),当超过免费唱次数后,sdk会记录当前页面是播放页,会通过此接口回调播放阻断,app侧可以做相应的业务逻辑(如跳转会员页等)。
这里定义了一个通用请求接口(目前只有播放阻断的场景),方法签名如下:

fun request(
   groupId: String,
   eventType: String,
   status: Any?,
   extra: Map<String, Any>?
): Any?

参数说明:

参数类型说明
groupIdString请求大类,标识属于哪一类请求,比如登陆、录唱、支付等
eventTypeString请求类型,区分具体什么请求,如"guideUrl"代表获取mic引导链接
statusAny?请求状态,通用类型的请求参数,可为空
extraMap<String, Any>?其他额外的请求参数放在Map中传入,可为空

返回值:返回true则表示此操作正在处理,APP可以跳到支付页,当支付完成后,让播放页露出时重新收到onStart()后,sdk的播放逻辑会继续执行,这样就可以续播。
返回false则表明已处理完成,sdk不再根据当前context监听onStart事件。
需要业务方根据传参提供具体实现。

初始化的方式参考demo中HostApp的initKG方法,但是AppRequestProvider需要业务方根据具体场景实现。

问题: 什么是播放歌曲阻断?
答案: 调用预加载或播放会触发对播放次数的统计,如果当前用户不是VIP会员,则播放VIP歌曲会直接触发歌曲播放阻断。其它歌曲都是限免歌曲,如果超过配置的限免数,就会报“限免达到上限”。

如播放歌曲阻断(如会员歌曲/免费歌曲达到次数上限等)时,sdk会通过此接口通知到app端,app侧可以做相应的业务逻辑(如跳转会员页等)
这种场景下:
groudId: "type_play"
eventType: "play_intercept"
status: 阻断原因,可能有如下值

    interface InterceptType {
        String UNKNOWN = "unknown";
        String FREE_TRAIL = "free_limit";  //限免阻断,错误码50015
        String VIP = "vip_limit";       //VIP阻断,错误码50016
        String LOGIN = "login_limit";       //登录阻断, 错误码40010。仅自实现登录会回调,其它登录方式走LoginError回调错误。
        String AUDIO_HQ_NEED_VIP = "AUDIO_HQ_NEED_VIP"; //音频HQ权益阻断,错误码50025
        String VIDEO_1080P_NEED_VIP = "VIDEO_1080P_NEED_VIP";   //1080P权益阻断,错误码50026
        String VIDEO_4K_NEED_VIP = "VIDEO_4K_NEED_VIP"; //4K权益阻断,错误码50027
    }

示例:

    override fun request(
        context: Context,
        groupId: String,
        eventType: String,
        status: Any?,
        extra: Map<String, Any>?
    ): Any? {
        if (groupId == "type_play" && eventType == "play_intercept") {
            status.startActivity(Intent(this, SamplePlayListActivity::class.java))
        }
        return true
    }

注意:另外需要在播放页的初始化时增加如下代码
PlayerManager.getPlayPermissionProvider()?.attachPage(activity)

如需要跳转到宿主的播放页的场景,此时:
groudId: "type_play"
eventType: "goto_play_page"
status: PendSong
客户端收到此回调时,主动跳转到播放页,并播放当前mid的歌曲

1.4.3 imageLoader: 宿主需实现图片下载接口

logger: 宿主日志实现

1.4.4 Application中初始化实现样例

    fun initKG() {
        val params = KtvInitParams(
            hostInfo = SampleHostInfo(),
            appRequestProvider = SampleAppRequestProvider(),
            imageLoader = GlideImageLoaderImpl(),
            logger = SimpleLog(),
        )
        KtvSdk.init(this, params)
    //如果需要在测试环境测试,可设置sdk为测试环境
    //KtvSdk.setProductEnv(false)
        customConfig()
    }

    /**
     * 播放可选配置,相关配置项都有默认值,一般不需要单独配置。
     */
    private fun customConfig() {
        KtvPlayerConfig.getInstance()
//    //            .useTextureView()
//            .setCacheStrategyFactory(object : CacheStrategyFactory() {
//                override fun createCacheStrategy(cacheDirPath: String): AbstractCacheStrategy {
//                    return LruCacheStrategy(cacheDirPath, 1024 * 1024 * 1024 * 2L)    //设置硬盘缓存
//                }
//            })
//            .forceUseSystemAudioOutput(true)
//             .installAudioInstaller(PuremicOutputInstaller(),PuremicReceiverInstaller())
//            .setKtvPlayerEventReportCallback { mid: String?, event: Int -> }
//            .setSupportAudioRecordReceiver(true)
//            .enableDebugLog(true)
//            .enableDownloadLog(true)
//            .downloadRetryCount(3) //下载重试次数
//            .setUserAgent("Demo") //User-Agent
//            .useOpenGL(false)     //是否使用GLSurfaceView
            .commit()    //此方法必须被调用

    }

2. 登录

sdk需要登录态才能唱歌。登录集成方式详见:KtvSDK-登录

3. 播放API

播放器为KaraokePlayer,播放界面自行开发。
如果有Android4.4的设备,要处理证书兼容性问题-KtvSDK-Android4.4设备G2证书兼容处理

3.3 KaraokePlayer Api

播放相关的接口如下:

KaraokePlayer ApiDescribe
void play(SongInfoObject object)播放歌曲
void pause()暂停播放
void resume()恢复播放
void stop()释放播放资源,相当于release。退出播放时调用;或播放下一首时,先调用stop()再调用play()
void replay()重新播放
int getPlayState()播放状态 {VideoState.STATE_IDLE:0, VideoState.STATE_START:1, VideoState.STATE_PLAYING:2, VideoState.STATE_PAUSE:3, VideoState.STATE_ENDED:4}
KaraokePlayer setDataSourceType(DataSourceType sourceType)切换原唱/伴奏
KaraokePlayer setLoopMode(LoopMode mode)Loop or Once
KaraokePlayer setTonePitchShift(int offset)设置升降调的值(-12到12)
int getTonePitchShift( )获取设置升降调的值(-12到12)
DataSourceType getDataSourceType()获取伴奏类型
KaraokePlayer setVolume(float volume)设置伴奏音量(0.0-1.0f)
KaraokePlayer setMicVolume(float volume)设置mic 音量(0.0-1.0f)
float getVolume()获取伴奏音量
float getMicVolume()获取mic 音量
KaraokePlayer addCallback(KaraokePlayerListener callback)添加播放回调或播放器监听
KaraokePlayer removeCallback(KaraokePlayerListener callback)移除播放回调或播放器监听
KaraokePlayer addOnScoreListener(OnScoreListener listener)添加打分回调或打分监听
KaraokePlayer removeOnScoreListener(OnScoreListener listener)移除打分回调或打分监听
KaraokePlayer setFadeAudioVolumeTime(long time)渐变音时间
KaraokePlayer setFadeAudioEnable(boolean flag)是否允许渐变音
long getCurrentTime()当前解码时间, sdk内部使用,获取当前播放时间建议用getTimeLineTime()
long getTimeLineTime()当前播放时间
long getDuration()歌曲总时长
KaraokePlayer setKtvVideoLayout(IVideoView videoLayout)设置视频View,详见下面介绍
void seek(long seekTimeMs)seek功能,K歌时只能向后seek,播放纯MV时可快进快退
void setScoreInfo(KaraokeScoreInfo scoreInfo)设置歌词与打分需要的数据,在使用LyricInitializer初始化歌词信息后调用
long getPreludeFinishTime()前奏结束时间前5秒,用于显示跳过前奏

3.4 播放及预加载

播放歌曲的步骤如下:

  1. 在布局中加入视频View KtvVideoLayout
  2. 播放页创建时,创建播放器实例
  3. 设置播放参数,添加播放器监听。通过**PlayerManger.preload()**方法先加载歌曲信息,加载成功后,调用KaraokePlayer.play()方法进行播放(见文档3.4.1节)

下面列出了详细步骤:

布局中加入视频View KtvVideoLayout:

<ksong.support.video.ktv.KtvVideoLayout
        android:id="@+id/video_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

不要对KtvVideoLayout进行多次addView/removeView操作,不然会出现视频黑屏现象。

播放页创建时,创建播放器实例,一个界面只用一个播放器,退出时销毁。

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        createKaraokePlayer()
    }

    private fun createKaraokePlayer() {
        if(currentPlayer == null) {
            //KtvVideoLayout为视频View
            val videoLayout: KtvVideoLayout = findViewById(R.id.ktv_video_layout)
            //创建播放器实例
            currentPlayer = KtvPlayerImpl()
            currentPlayer.setKtvVideoLayout(videoLayout)
        }
    }

创建好播放器后,再根据下面"3.4.1 使用sdk请求歌曲信息"节的信息进行歌曲加载与播放。

3.4.1 使用sdk请求歌曲信息(推荐)

厂商实现登录后,就可以只提供歌曲id,实现播放功能。
如果是预加载,只调用PlayManager.preload()接口即可。

    ...
    //停止当前歌曲播放
    player?.stop()

    val builder = SongInfoObject.Builder()
        builder.setMid(currentMid)
        //设置歌曲类型,从SongType类取值,SongType类型详见下面介绍
        builder.setSongType(songType)
        val songInfoObject = builder.build()

        //使用PlayerManager加载歌曲资源
        PlayerManager.preload(songInfoObject) { event: PlayPreLoaderEvent ->
                when (event) {
                    //预加载完成
                    is PlayPreLoaderEvent.Success -> {
                        val song = event.songInfoObject ?: return@preload
                        //进行播放
                        playSong(song)
                    }
            
                    //预加载的一些日志打印
                    is PlayPreLoaderEvent.Trace -> {
                    }
                    
                    //歌曲加载进度
                    is PlayPreLoaderEvent.Progress -> {
                    }
                    
                    //预加载失败
                    is PlayPreLoaderEvent.Failed -> {
                        Logger.i(TAG, "preload $event")
                    }
                }
            }
        
    private fun playSong(songInfo: SongInfoObject) {
        val player = currPlayer   //创建播放器实例

        //设置播放参数
        player
            .setTonePitchShift(0)
            .setDataSourceType(dataSourceType)
            .setMicVolume(PlayConsole.get().micVolume.value?.volume?.div(10.toFloat()) ?: 0.7F)
            .setVolume(PlayConsole.get().accompanyVolume.value?.volume?.div(10.toFloat()) ?: 1.0F)
            .addCallback(createCallback()) //添加播放回调
        
        //调用play()
        player.play(songInfo)
    }

播放页实现示例详见Ktv SDK 播放功能接入说明。

4. 歌词 LyricView

更多歌词内容请见 KtvSDK-歌词

5. 打分

更多打分内容请见 KtvSDK-打分

修改于 2025-09-01 07:13:13
上一页
bug提单规范
下一页
KtvSDK-打分
Built with