logologo
售前咨询
点播云
产品简介
购买指南
快速入门
控制台指南
服务端API
SDK文档
播放器SDK
Web端播放器
Android端播放器
iOS端播放器
鸿蒙端播放器
上传SDK
服务端SDK
相关协议
文档中心
SDK文档播放器SDK鸿蒙端播放器快速开始

快速开始


1 SDK初始化

初始化有两个接口可供调用:日志回调setLogConfig和init。

import { KSLogLevel, KSMediaPlayerConfig } from '@kwai/streamlake-mediaplayer';
try {
// 1 设置日志回调监听,可以在回调里搜集日志。小于此级别的日志不会回调
let logLevel = KSLogLevel.Debug;
KSMediaPlayerConfig.setLogConfig(logLevel, {
v: (tag: string, msg: string): void => {
hilog.debug(0x0000, "demo:" + tag, '%{public}s', msg);
},
d: (tag: string, msg: string): void => {
hilog.debug(0x0000, "demo:" + tag, '%{public}s', msg);
},
i: (tag: string, msg: string): void => {
hilog.info(0x0000, "demo:" + tag, '%{public}s', msg);
},
w: (tag: string, msg: string): void => {
hilog.warn(0x0000, "demo:" + tag, '%{public}s', msg);
},
e: (tag: string, msg: string): void => {
hilog.error(0x0000, "demo:" + tag, '%{public}s', msg);
}
});
// 2 初始化播放器sdk
KSMediaPlayerConfig.init(ctx, DemoData.sAppId, DemoData.sDeviceId);
} catch (e) {
hilog.error(0x0000, "KSMediaPlayer", `init ksplayer error=${e.stack}`)
}


2 点播播放器使用

2.1 创建点播播放器

创建点播播放器是通过KSMediaPlayerBuilder#build创建,这个KSMediaPlayerBuilder里的属性在创建出IKSVodPlayer就不再变化,想要改变某个属性比如mute属性可以通过IKSVodPlayer提供的相关接口。

import {
BuildProfile,
KSUrlType,
KSDataSourceFetchCallback,
KSFetchReason,
VideoCodecType,
IKSVodPlayer,
KSDebugView,
KSDebugViewController,
KSMediaPlayerBuilder,
KSMediaPlayerCache,
KSRepresentation,
KSStartPlayType,
KSPlayerState,
KSMediaPlayerConstants
} from '@kwai/streamlake-mediaplayer';

@State qualityList: KSRepresentation[] = [];
@State mPlayingUrl?: string = ""
@State playing: boolean = false
@State xComponentId: string = "DemoPlayerSurfaceId"
@State playerWidth: number = 720;
@State playerHeight: number = 1280;
@State currentPosition: number = 0;
@State duration: number = 0;

private vodPlayer?: IKSVodPlayer;
private xComponentId: string = "DemoPlayerSurfaceId"

private initPlayer() {
let builder: KSMediaPlayerBuilder = new KSMediaPlayerBuilder()
let url = "http://tx-playback.video.yximgs.com/mediacloud/demo/demo_video/kQOGfMsmAxe1Qtu6LuZ_oh1_0uOtCogxO5hFTXBPG4227dV5OeKosh9KZq6iG-tn.mp4";
if (/* 多url列表,业务自己判断 */) {
builder.setDataSourceList(this.mediaBean.mQualityArray, url)
} else if (/* 单url,业务自己判断 */) {
builder.setDataSourceUrl(url)
} else if (/* 符合快手json结构的manifest字符串,业务自己判断 */) {
builder.setDataSourceManifest(url)
}
builder.setVideoId(this.mediaBean.videoId ?? url)
.setStartPosition(DemoSp.getInstance().getValueNumber(Const.KEY_START_PLAY_POS, -1) * 1000)
builder.setStartType(KSStartPlayType.StartOnPrepare);
builder.setEnableFirstFrameForceRender(false);
try {
this.vodPlayer = builder.build()
} catch (e) {
console.log(TAG, `build ksplayer error=${e.stack}`);
}
this.attachListeners();
}


2.2 设置点播相关监听

private attachListeners() {
let that = this
// 设置prepare监听
this.vodPlayer?.setOnPreparedListener({
onPrepared: (): void => {
console.log(TAG, `demolistener on prepared`)
this.mPlayingUrl = this.vodPlayer?.getCurrentPlayUrl()
if (this.startPlayType != KSStartPlayType.StartOnPrepare) {
this.vodPlayer?.start();
}
}
})
// 设置多码率列表回调监听, 回调参数1: 多分辨率列表; 回调参数2: 列表里当前播放的 index >= 0
this.vodPlayer?.setOnRepresentationListReadyListener({
onQualityRepresentationListReady: (reps: KSRepresentation[], index: number): void => {
console.log(TAG, `demolistener on qualitylistready info=${JSON.stringify(reps)} index=${index}`)
this.qualityList = reps
}
})
// 设置分辨率变化监听
this.vodPlayer?.setOnVideoSizeChangedListener({
onVideoSizeChanged: (width: number, height: number, sarNum: number, sarDen: number): void => {
console.log(TAG, `demolistener on size change w: ${width} h: ${height} sarNum: ${sarNum} sarDen: ${sarDen}`)
if (width > 0 && height > 0) {
this.playerWidth = width;
this.playerHeight = height;
}
}
})
// 设置错误监听
this.vodPlayer?.setOnErrorListener({
onError(what: number, extra: number) {
console.log(TAG, `demolistener on error 1=${what} 2=${extra}`)
}
})
// 设置播放结束监听
this.vodPlayer?.setOnCompletionListener({
onComplete() {
console.log(TAG, `demolistener on complete`)
}
})
// 设置播放器进度改变监听
this.vodPlayer?.setOnProgressChangeListener({
onProgressChanged: (currentPosition: number, duration: number): void => {
this.duration = duration;
this.currentPosition = currentPosition;
}
})
// 设置首帧回调监听
this.vodPlayer?.setOnFirstFrameRenderingStart({
onFirstFrameRenderingStart: (what: number, extra: number): void => {
console.log(TAG, `demolistener on first frame rendering start. what: ${what} extra: ${extra}`)
}
})
// 设置渲染开始的监听
this.vodPlayer?.setOnRenderingStartListener({
onRenderingStart: (what: number, extra: number): void => {
console.log(TAG, `demolistener on rendering start. what: ${what} extra: ${extra}`)
}
})
// 设置第一帧解码完成监听
this.vodPlayer?.setOnDecodeFirstFrame({
onDecodeFirstFrame: (what: number, extra: number): void => {
console.log(TAG, `demolistener on decode first frame. what: ${what} extra: ${extra}`);
}
})
// 设置事件监听
this.vodPlayer?.setOnEventListener({
onEvent: (what: number, extra: number): void => {
console.log(TAG, `demolistener onEvent: what: ${what} extra: ${extra}`);
if (what == KSMediaPlayerConstants.KS_MEDIA_PLAYER_PLAYBACK_STATE_CHANGED) {
console.log(TAG, `demolistener StreamlakeStateEvent player state::${extra} ${KSPlayerState[extra]}`);
this.playing = extra == KSPlayerState.Playing ? true : false;
} else if (what == KSMediaPlayerConstants.KS_MEDIA_PLAYER_EVENT_BUFFERING_START) {
console.log(TAG, `demolistener onBufferingStart`);
} else if (what == KSMediaPlayerConstants.KS_MEDIA_PLAYER_EVENT_BUFFERING_END) {
console.log(TAG, `demolistener onBufferingEnd`);
} else if (what == KSMediaPlayerConstants.KS_MEDIA_PLAYER_INFO_VIDEO_QUALITY_SWITCH_START) {
// 切换分辨率开始
} else if (what == KSMediaPlayerConstants.KS_MEDIA_PLAYER_INFO_VIDEO_QUALITY_SWITCH_END) {
// 切换分辨率完成
} else if (what == KSMediaPlayerConstants.KS_MEDIA_PLAYER_INFO_MEDIA_ACCURATE_SEEK_COMPLETE) {
// seek完成
}
}
})
this.vodPlayer?.setOnBufferingUpdate({
onBufferingUpdate: (percent: number): void => {
console.log(TAG, `demolistener onBufferingUpdate. percent: ${percent}`);
}
})
}


2.3 绑定鸿蒙XComponent组件

XComponent({
id: this.xComponentId, type: 'surface', libraryname: 'AemonPlayerNapi'
})
.width('100%')
.aspectRatio(this.playerWidth / this.playerHeight)
.onLoad((event?: object) => {
this.vodPlayer?.setXComponentId(this.xComponentId);
})
.onDestroy((event?: object) => {
this.vodPlayer?.setXComponentId('');
})


2.4 开始播放

this.vodPlayer?.prepareAsync();

如果设置 KSMediaPlayerBuilder.setStartType(KSStartPlayType.StartOnPrepare)(默认也是这个),调用prepareAsync之后播放器会自动播放;如果setStartType设置的是其他的值,需要在onPrepared回调里手动调用this.vodPlayer?.start();才会播放。


2.5 销毁播放器

aboutToDisappear(): void {
this.vodPlayer?.releaseAsync();
}


3 直播播放器使用

3.1 创建直播播放器

创建直播播放器是通过KSLivePlayerBuilder#build创建出IKSLivePlayer实例。

private livePlayer?: IKSLivePlayer;

private initPlayer() {
let that = this
try {
let url = this.mediaBean.url
let builder: KSLivePlayerBuilder = new KSLivePlayerBuilder()
builder.setDataSource({ url: url, streamId: "123" })
this.livePlayer = builder.build()
this.attachListeners()
} catch (e) {
console.log(TAG, `init liveplayer error=${e.stack}`);
}
}


3.2 设置直播相关监听

private attachListeners() {
// 设置播放结束监听
this.livePlayer?.setOnCompletionListener({
onComplete: (): void => {
}
})
// 设置错误监听
this.livePlayer?.setOnErrorListener({
onError: (what: number, extra: number): void => {
console.log(TAG, `listener on error what=${what} extra=${extra}`);
}
})
// 设置播放视频分辨率变化监听
this.livePlayer?.setOnVideoSizeChangedListener({
onVideoSizeChanged: (w: number, h: number, sarNum: number, sarDen: number): void => {
console.log(TAG, `listener on videosizechanged w=${w} h=${h} sarNum=${sarNum} sarDen=${sarDen}`);
if (w > 0 && h > 0) {
this.playerWidth = w;
this.playerHeight = h;
this.livePlayer?.setXComponentId(this.surfaceId)
}
}
})
// 设置渲染监听
this.livePlayer?.setRenderListener({
onVideoRenderingStart: (): void => {
console.log(TAG, `listener on video render start`);
},
onAudioRenderingStart: (): void => {
console.log(TAG, `listener on audio render start`);
},
onSwitchToAudioStreamFromVideoStream: (): void => {
console.log(TAG, `listener on switch to audio stream from video stream`);
},
onRenderingStartAfterResume: (): void => {
console.log(TAG, `listener on render start after resume`);
},
onLivePlayViewShow: (): void => {
console.log(TAG, `listener on live playview show`);
}
})
// 设置播放状态变化监听
this.livePlayer?.setStateChangeListener({
onStateChange: (newState: KSLivePlayerState): void => {
this.playing = newState == KSLivePlayerState.PLAYING
}
})
// 设置缓存信息监听
this.livePlayer?.setBufferListener({
onBufferStart: (): void => {
console.log(TAG, "listener onEvent buffer start");
},
onBufferEnd: (): void => {
console.log(TAG, "listener onEvent buffer end");
},
onBufferEmpty: (): void => {
console.log(TAG, "listener onEvent buffer empty");
}
})
// 设置m3u8 url hook接口
this.livePlayer?.setLiveRequestListener({
onRequestBegin: (url: string): string => {
console.log(TAG, "replace url out2: listenOnKwaiHttpRequestListener=" + url)
return url;
}
})
// sei信息回调
this.livePlayer?.setOnSeiInfoListener({
onSeiInfo: (data: ArrayBuffer, size: number, payloadType: number) => {
let uint8Array = new Uint8Array(data);
let str = new util.TextDecoder().decodeToString(uint8Array);
console.log(TAG, `listener OnLiveSei data info::${str} size=${size} payloadType=${payloadType}`);
}
})
}


3.3 绑定鸿蒙XComponent组件

同 2.3章节,这里省略。


3.4 开始播放

直播播放器会自动播放,无需手动调用。


3.5 销毁播放器

aboutToDisappear(): void {
this.livePlayer?.releaseAsync();
}


4 基础功能

4.1 播放/暂停

start: () => void
pause: () => void


4.2 拖拽播放进度

/**
* 改变视频播放位置到某个时间点 单位ms
*/
seekTo: (mSec: number) => void


4.3 倍速播放

/**
* 倍速播放功能
* @param speed 小于1慢速,大于1快速
*/
setSpeed(speed: number): void


4.4 播放音量

/**
* 设置音量
* @param leftVolume 左声道音量(0-1)
* @param rightVolume 右声道音量(0-1)
*/
setVolume(leftVolume: number, rightVolume: number): void


4.5 开启静音/解除静音

/**
* 开启关闭静音
* @param mute 是否静音
*/
setMute(mute: boolean): void;


4.6 是否prepare完成

/**
* 是否已经prepared
*/
isPrepared(): boolean;


4.7 是否正在播放

/**
* 是否正在播放
*/
isPlaying(): boolean;


4.8 设置循环播放/是否循环播放

/**
* 是否循环播放
*/
isLooping: () => boolean

/**
* 设置循环播放
*/
setLooping(isLooping: boolean): void;


4.9 获取当前播放url

getCurrentPlayUrl(): string;


4.10 获取视频时长

/**
* 视频时常,ms
* @returns duration
*/
getDuration(): number


4.11 获取播放进度

/**
* 获取当前播放位置, ms
* @returns cur pos
*/
getCurrentPosition(): number;


4.12 获取debugInfo

/**
* 获取调试信息
* @returns debuginfo
*/
getDebugInfo(): KwaiPlayerDebugInfo;


5 高级功能

5.1 首帧强制渲染

如果不想立即播放,只是显示第一帧的图像,可以这样调用:

KSMediaPlayerBuilder#setStartType(KSStartPlayType.PreDecode);
KSMediaPlayerBuilder#setEnableFirstFrameForceRender(true);


5.2 清除缓存

每一次视频的播放,都会在sd卡中存储一些数据,默认最大值256M, 超过这个值后SDK下载器会采用LRU策略用新缓存代替老缓存。如果想清除全部缓存,可以如下调用:

KSMediaPlayerCache#clearCache()


5.3 自定义cacheKey

SDK内部的下载器根据cacheKey进行数据的下载、存储、读取,cacheKey的生成策略很重要,默认的生成策略是将url播放地址的path部分进行算法转换得到,这样可以保证一个点播地址的鉴权信息(属于query部分)变化的时候其cacheKey保持不变。如果用户想要自定义cacheKey,比如要将播放地址的query参数信息参与cacheKey的计算,那么有如下两种方案:

// 1: 这个接口的第二个参数传入自己计算好的cacheKey,仅支持单url。
KSMediaPlayerBuilder#setDataSourceUrl(url: string, cacheKey?: string)


// 2: 调用这个设置接口,替代默认的cacheKey生成规则。这个是全局的单一实例。
KSMediaPlayerCache#setCustomCacheKeyGenerator(cacheKeyGenerator: KSCacheKeyGenerator)


5.4 播放重试

/**
* 主动重试
*/
retryPlayback: () => void


5.5 清晰度切换

// 调用这个接口成功后会触发 KSOnRepresentationListReadyListener 的回调
switchVideoQuality(url: string, cacheKey?: string): void


5.6 外挂字幕

/**
* 设置字幕列表
* @param subtitles 字幕列表
* @param selectIndex 默认的选中的index
* @returns this
*/
KSMediaPlayerBuilder#setSubtitle(subtitles: string[], selectIndex: number): KSMediaPlayerBuilder


/**
* 设置字幕选中状态
* @param index 选中的字幕index
* @param selected 是否选中
*/
setSubtitleSelected: (index: number, selected: boolean) => void;

/**
* 设置字幕相关回调
*
* @param listener
*/
setOnSubtitleListener: (listener: KSOnSubtitleListener) => void;


5.7 强制软硬解

/**
* 强制软硬解
* @param type 0默认 1强制硬解 2强制软解
* @returns this
*/
KSMediaPlayerBuilder#setForceDecodeType(type: VideoCodecType): KSMediaPlayerBuilder

/**
* 强制软硬解
* @param type 0默认 1强制硬解 2强制软解
* @returns this
*/
KSLivePlayerBuilder#setLiveDecodeType(type: VideoCodecType): KSLivePlayerBuilder


5.8 预加载

5.8.1 构建 IKSPrefetchTask
let task: IKSPrefetchTask | undefined = new KSPrefetchTaskBuilder().setType(this.type)
.setUrl(this.url)
.setVideoId(this.videoId)
.setConfig(this.config)
.setDownloadListener(this.listener)
.build()


5.8.2 提交任务
/**
* 添加预加载任务
* @param task 任务
* @returns ADD_TASK_RESULT_OK:成功,否则:失败
*/
KSPrefetcher.getInstance()?.addTask(task);


5.8.3 任务管理
/**
* 暂停所有预加载任务
*/
pauseAllTasks(): void;

/**
* 恢复所有预加载任务
*/
resumeAllTasks(): void;

/**
* 移除预加载任务
* @param task
*/
removePrefetchTask(task?: IKSPrefetchTask): void;

/**
* 移除所有预加载任务
*/
removeAll(): void;


5.9 直播sei信息回调

/**
* 直播sei信息回调
* @param listener 回调
*/
setOnSeiInfoListener(listener: KSOnSeiInfo): void



上一篇:集成准备下一篇:API参考
该篇文档内容是否对您有帮助?
有帮助没帮助