本文为您介绍如何创建鸿蒙HarmonyOS NEXT播放器实例并提供设置音量、设置拖拽播放、监听播放状态、设置循环播放、设置倍速播放等基础播放功能的使用示例。
设置播放源(DataSource)
鸿蒙HarmonyOS NEXT版播放器SDK支持4种点播播放方式,包括:VidAuth播放(视频点播用户推荐使用)、VidSts播放、UrlSource播放、加密播放。
鸿蒙HarmonyOS NEXT版播放器SDK仅支持1种直播播放方式,UrlSource播放。
点播视频播放
点播VidAuth播放(推荐)
使用VidAuth播放方式播放点播视频,需要将播放器的vid属性设置为音视频ID,将playauth属性设置为音视频播放凭证。
音视频ID:可以在音视频上传完成后通过控制台(路径:媒资库>音/视频。)或服务端接口(SearchMedia)获取。
音视频播放凭证:可以调用GetVideoPlayAuth接口获取。建议您集成点播服务端SDK来获取音视频播放凭证,免去自签名的麻烦。调用接口获取音视频播放凭证的示例请参见开发者门户。
推荐视频点播用户采用此播放方式。相比STS播放方式,PlayAuth播放方式在易用性和安全性上更有优势,对比详情请参见凭证方式与STS方式对比。
若您在VOD控制台开启HLS标准加密参数透传,默认的参数名为MtsHIsUriToken,详情见HLS标准加密参数透传,那么请按照下述代码,将MtsHIsUriToken值设入点播源中。
import { AliPlayerFactory, AliPlayer, VidAuth } from 'premierlibrary';
interface IAuthInfo { videoId: string, playAuth: string }
@Preview
@Component
export struct MyPlayerComponent {
private authInfo: IAuthInfo = {
videoId: '点播vid',
playAuth: 'playauth',
};
private aliyunVodPlayer: AliPlayer = AliPlayerFactory.createAliPlayer(getContext(), '');
playByVidAndAuth() {
const vidAuthSource: VidAuth = new VidAuth();
vidAuthSource.setVid(this.authInfo.videoId);// 必选参数,视频ID(VideoId)。
vidAuthSource.setPlayAuth(this.authInfo.playAuth);// 必选参数,播放凭证,需要调用点播服务的GetVideoPlayAuth接口生成。
//若您在VOD控制台开启了HLS标准加密参数透传,且默认的参数名为MtsHlsUriToken,那么需要设置config,并将其传入vid中,参考下述
//若您未在VOD控制台开启了HLS标准加密参数透传,那么则不需要集成下述代码
let config:VidPlayerConfigGen = new VidPlayerConfigGen();
config.setMtsHlsUriToken("<yourMtsHlsUriToken>");
vidAuthSource.setPlayerConfig(config);
aliyunVodPlayer.setVidAuthDataSource(vidAuthSource);
}
}
点播VidSts播放
使用点播VidSts播放方式播放点播视频是指用STS临时凭证而非点播音视频播放凭证播放。STS安全令牌和STS临时AK对(AccessKeyId和AccessKeySecret)需要提前获取,获取方式请参见获取STS Token。
若您在VOD控制台开启HLS标准加密参数透传,默认的参数名为MtsHIsUriToken,详情见HLS标准加密参数透传,那么请按照下述代码,将MtsHIsUriToken值设入点播源中。
import { AliPlayerFactory, AliPlayer, VidSts } from 'premierlibrary';
interface ISTSInfo { videoId: string, accessKeyId: string, securityToken: string, accessKeySecret: string, region: string }
@Preview
@Component
export struct MyPlayerComponent {
private stsInfo: ISTSInfo = {
videoId: '点播vid',
accessKeyId: 'STS-accessKeyId',
securityToken: 'STS-token',
accessKeySecret: 'STS-accessKeySecret',
region: 'regionId'
};
private aliyunVodPlayer: AliPlayer = AliPlayerFactory.createAliPlayer(getContext(), '');
playByVidAndSTS() {
const vidStsSource: VidSts = new VidSts();
vidStsSource.setVid(this.stsInfo.videoId);// 必选参数,视频ID(VideoId)。
vidStsSource.setAccessKeyId(this.stsInfo.accessKeyId);// 必选参数,STS临时AK对的访问密钥ID,需要调用STS服务的AssumeRole接口生成。
vidStsSource.setAccessKeySecret(this.stsInfo.accessKeySecret);// 必选参数,STS临时AK对的访问密钥,需要调用STS服务的AssumeRole接口生成。
vidStsSource.setSecurityToken(this.stsInfo.securityToken);// 必选参数,STS安全令牌,需要调用STS服务的AssumeRole接口生成。
vidStsSource.setRegion(this.stsInfo.region);// 必选参数,点播服务的接入地域,默认为cn-shanghai。
//若您在VOD控制台开启了HLS标准加密参数透传,且默认的参数名为MtsHlsUriToken,那么需要设置config,并将其传入vid中,参考下述
//若您未在VOD控制台开启了HLS标准加密参数透传,那么则不需要集成下述代码
let config:VidPlayerConfigGen = new VidPlayerConfigGen();
config.setMtsHlsUriToken("<yourMtsHlsUriToken>");
vidStsSource.setPlayerConfig(config);
aliyunVodPlayer.setVidStsDataSource(vidStsSource);
}
}
点播UrlSource播放
使用点播UrlSource播放方式播放点播视频,需要将播放器的setUrl属性设置为播放地址。
阿里云视频点播服务中的播放地址:可以调用GetPlayInfo接口获取。建议您集成点播服务端SDK来获取音视频播放地址,免去自签名的麻烦。调用接口获取音视频播放地址的示例请参见开发者门户。
本地视频地址:请确保有访问权限,可以通过系统API获取到可访问的本地视频文件完整路径,例如:
/sdcard/xxx/xxx/xxx.mp4
或file://xxx/xxx/xx.mp4
。
import { AliPlayerFactory, AliPlayer } from 'premierlibrary';
import { UrlSource } from 'premierlibrary/src/main/ets/com/aliyun/player/source/UrlSource';
@Preview
@Component
export struct MyPlayerComponent {
private videoUrl: string = 'http播放地址';
private aliyunVodPlayer: AliPlayer = AliPlayerFactory.createAliPlayer(getContext(), '');
playByUrl() {
let urlSource: UrlSource = new UrlSource();
urlSource.setUri(this.videoUrl);// 必选参数,播放地址,可以是第三方点播地址,或阿里云视频点播服务中的播放地址,也可以是本地视频地址。
aliyunVodPlayer.setUrlDataSource(urlSource);
}
}
点播加密播放
点播视频支持HLS标准加密、阿里云私有加密。加密播放请参见Harmony端播放加密视频。
直播视频播放
直播UrlSource播放
使用UrlSource播放方式播放直播视频,需要将播放器的setUrl属性设置为直播拉流地址。播放地址可以是第三方直播地址或阿里云直播服务中的拉流地址。
阿里云直播拉流地址可以通过直播控制台的地址生成器生成。详情请参见直播地址生成器。
import { AliPlayerFactory, AliPlayer } from 'premierlibrary';
import { UrlSource } from 'premierlibrary/src/main/ets/com/aliyun/player/source/UrlSource';
@Preview
@Component
export struct MyPlayerComponent {
private videoUrl: string = '直播播放地址';
private aliyunVodPlayer: AliPlayer = AliPlayerFactory.createAliPlayer(getContext(), '');
playByUrl() {
let urlSource: UrlSource = new UrlSource();
urlSource.setUri(this.videoUrl);// 播放地址,可以是第三方直播地址,或阿里云直播服务中的拉流地址。
aliyunVodPlayer.setUrlDataSource(urlSource);
}
}
UrlSource是直接通过URL播放,VidSts,VidAuth是通过Vid进行播放。
接入地域Region的设置,请参见点播地域标识。
控制播放
鸿蒙HarmonyOS NEXT播放器SDK支持从指定时间点播放、开始、暂停、停止播放等操作。
自动播放
指自动播放视频,由setAutoPlay
接口实现(默认为关闭状态)。示例如下:
// aliyunVodPlayer为播放器实例
aliyunVodPlayer.setAutoPlay(true);
准备播放
指准备播放视频,调用prepare
接口开始读取并解析数据。若开启自动播放,数据解析完成后将开始自动播放视频。示例如下:
// aliyunVodPlayer为播放器实例
aliyunVodPlayer.prepare();
开始播放
指开始播放视频,由start
接口实现。示例如下:
aliyunVodPlayer.start();
从指定时间开始播放
指跳转到某个时刻进行播放,由seekTo
接口实现。适用于用户拖拽进度条,或续播等需要从指定时间点开始播放的场景。示例如下:
// posotion为指定的时间,单位:毫秒。
aliyunVodPlayer.seekTo(long position);
暂停播放
指暂停播放视频,由pause
接口实现。示例如下:
aliyunVodPlayer.pause();
恢复播放
指恢复播放视频,由start
接口实现。示例如下:
aliyunVodPlayer.start();
停止播放
指停止播放视频,由stop
接口实现。示例如下:
aliyunVodPlayer.stop();
播放器状态监听
鸿蒙HarmonyOS NEXT播放器SDK支持设置播放器监听和监听播放状态。
设置播放器监听
// 推荐下载Demo工程,参阅ReadMe.md了解最佳实践方式,帮助您快速集成。
// 按需 引入播放器事件回调类型定义
import { OnPreparedListener, OnCompletionListener, OnAudioInterruptEventListener,OnErrorListener,OnInfoListener,OnLoadingStatusListener, AudioStatus } from 'premierlibrary/src/main/ets/com/aliyun/player/IPlayer';
// 播放器实例
const aliyunVodPlayer: AliPlayer = AliPlayerFactory.createAliPlayer(getContext(), traceId);
// 定义回调监听
const mPreparedEventHandler: OnPreparedListener = { // prepare完成
onPrepared: () => {
console.log("prepared");
}
};
const mCompletionEventHandler: OnCompletionListener = { // 播放完成
onCompletion: () => {
console.log("play complete");
}
}
const mOnAudioInterruptListener: OnAudioInterruptEventListener = { // 音频打断
onAudioInterruptEvent: (audioStatus: AudioStatus) => {
if(aliyunVodPlayer){
console.log("[HOS DEMO] [AUDIO INTERRUPT]: " + audioStatus);
let statusInfo: string = "";
switch (audioStatus) {
case AudioStatus.AUDIO_STATUS_DEFAULT:
statusInfo = "AUDIO_STATUS_DEFAULT"
break;
case AudioStatus.AUDIO_STATUS_RESUME:
statusInfo = "AUDIO_STATUS_RESUME"
aliyunVodPlayer.start(); // 继续播放
break;
case AudioStatus.AUDIO_STATUS_PAUSE:
statusInfo = "AUDIO_STATUS_PAUSE"
aliyunVodPlayer.pause(); // 暂停播放
break;
case AudioStatus.AUDIO_STATUS_STOP:
statusInfo = "AUDIO_STATUS_STOP"
aliyunVodPlayer.stop(); // 停止播放
break;
case AudioStatus.AUDIO_STATUS_DUCK:
statusInfo = "AUDIO_STATUS_DUCK"
break;
case AudioStatus.AUDIO_STATUS_UNDUCK:
statusInfo = "AUDIO_STATUS_UNDUCK"
break;
default:
break;
}
showToast("CALLBACK: onAudioInterrupt " + statusInfo);
}
}
}
const mOnErrorEventListener: OnErrorListener = { // 错误回调
onError:(errorInfo) => {
let errorCode:PlayerErrorCode = errorInfo.getCode(); //错误码
let errorMsg:string = errorInfo.getMsg(); //错误描述
//errorExtra为额外错误信息,形式为json字符串,示例如下,需要注意ModuleCode并不完全等同于errorCode
// { "Url": "xxx",
// "Module": "NetWork",
// "ModuleCode": "-377",
// "ModuleMessage": "Redirect to a url that is not a media"}
let errorExtra:string = errorInfo.getExtra();
//出错后需要停止掉播放器。
aliyunVodPlayer.stop();
}
}
const mOnVideoInfo: OnInfoListener = { // 视频信息回调
//播放器中的一些信息,包括:当前进度、缓存位置等等。
onInfo: (bean: InfoBean) => {
//当前进度:InfoCode.CurrentPosition
//当前缓存位置:InfoCode.BufferedPosition
if (bean.getCode() === InfoCode.CurrentPosition) {
this.videoProgress = bean.getExtraValue() / this.mVideoDuration * 100;
this.mDuration = CommonUtils.getDurationString(this.mVideoDuration, bean.getExtraValue());
} else if (bean.getCode() === InfoCode.BufferedPosition) {
this.buffer = CommonUtils.secondToTime(Math.floor(bean.getExtraValue() / 1000));
this.bufferedProgress = bean.getExtraValue() / this.mVideoDuration * 100;
}
}
}
const mOnLoadingProgressEventListener: OnLoadingStatusListener = { // 加载、卡顿状态下回调
onLoadingBegin: () => {
//开始加载。画面和声音不足以播放。
//一般在此处显示圆形加载
},
onLoadingProgress: (percent: number, netSpeed: number) => {
//加载进度。百分比和网速。
//网速为预留字段,暂时为0。
},
onLoadingEnd: () => {
//结束加载。画面和声音可以播放。
//一般在此处隐藏圆形加载。
}
}
// 将监听注册到播放器实例中
aliyunVodPlayer.setOnPreparedListener(mPreparedEventHandler);
aliyunVodPlayer.setOnCompletionListener(mCompletionEventHandler);
aliyunVodPlayer.setOnAudioInterruptEventListener(mOnAudioInterruptListener);
aliyunVodPlayer.setOnErrorListener(mOnErrorEventListener);
aliyunVodPlayer.setOnInfoListener(mOnVideoInfo);
aliyunVodPlayer.setOnLoadingStatusListener(mOnLoadingProgressEventListener);
监听播放状态
指监听播放器的状态,onStateChanged回调参数为当前播放器状态。示例如下:
/**
* 状态回调
*/
private mOnStatusChangedListener: OnStateChangedListener = {
onStateChanged: (status: number) => {
/*
int idle = 0;
int initalized = 1;
int prepared = 2;
int started = 3;
int paused = 4;
int stopped = 5;
int completion = 6;
int error = 7;
*/
}
}
aliyunVodPlayer.setOnStateChangedListener(this.mOnStatusChangedListener);
设置显示模式
鸿蒙HarmonyOS NEXT播放器SDK支持填充、旋转、镜像等显示设置。
填充
支持设置宽高比适应、宽高比填充和拉伸填充这3种画面填充模式,由setScaleMode
接口实现。示例如下:
// 设置宽高比适应(将按照视频宽高比等比缩小到view内部,不会有画面变形)
aliyunVodPlayer.setScaleMode(ScaleMode.SCALE_ASPECT_FIT);
// 设置宽高比填充(将按照视频宽高比等比放大,充满view,不会有画面变形)
aliyunVodPlayer.setScaleMode(ScaleMode.SCALE_ASPECT_FILL);
// 设置拉伸填充(如果视频宽高比例与view比例不一致,会导致画面变形)
aliyunVodPlayer.setScaleMode(ScaleMode.SCALE_TO_FILL);
旋转
指画面按指定角度旋转,由setRotateMode
接口实现。设置后还可查询旋转角度。示例如下:
// 设置画面顺时针旋转0度
aliyunVodPlayer.setRotateMode(RotateMode.ROTATE_0);
// 设置画面顺时针旋转90度
aliyunVodPlayer.setRotateMode(RotateMode.ROTATE_90);
// 设置画面顺时针旋转180度
aliyunVodPlayer.setRotateMode(RotateMode.ROTATE_180);
// 设置画面顺时针旋转270度
aliyunVodPlayer.setRotateMode(RotateMode.ROTATE_270);
// 获取旋转角度
aliyunVodPlayer.getRotateMode();
镜像
指画面按不同镜像效果显示,支持水平镜像、垂直镜像和无镜像,由setMirrorMode
接口实现。示例如下:
// 设置无镜像
aliyunVodPlayer.setMirrorMode(MirrorMode.MIRROR_MODE_NONE);
// 设置水平镜像
aliyunVodPlayer.setMirrorMode(MirrorMode.MIRROR_MODE_HORIZONTAL);
// 设置垂直镜像
aliyunVodPlayer.setMirrorMode(MirrorMode.MIRROR_MODE_VERTICAL);
获取播放信息
鸿蒙HarmonyOS NEXT播放器SDK支持获取当前的播放进度、播放时长和缓冲进度等信息。
获取当前播放进度
指获取当前的播放时刻,需要在onInfo回调中获取,由getExtraValue
接口实现。示例如下:
private mOnVideoInfo: OnInfoListener = {
//播放器中的一些信息,包括:当前进度、缓存位置等等。
onInfo: (bean: InfoBean) => {
if (bean.getCode() === InfoCode.CurrentPosition) {
// extraValue为当前播放进度,单位为毫秒
let extraValue: number = bean.getExtraValue();
}
}
}
获取播放时长
指获取视频总时长。需要在视频加载完成以后才可以获取到,可以在onPrepared事件后获取。由getDuration
接口实现。示例如下:
aliyunVodPlayer.getDuration();
获取实际播放时长
指实时获取实际播放时长,获取到的时长不包含播放过程中的暂停、卡顿等时间。示例如下:
aliyunVodPlayer.getPlayedDuration();
获取缓冲进度
指获取视频当前的缓冲进度,需要在onInfo回调中获取,由getExtraValue
接口实现。示例如下:
private mOnVideoInfo: OnInfoListener = {
//播放器中的一些信息,包括:当前进度、缓存位置等等。
onInfo: (bean: InfoBean) => {
if (bean.getCode() === InfoCode.BufferedPosition) {
// extraValue为当前缓冲进度,单位为毫秒
let extraValue: number = bean.getExtraValue();
}
}
}
获取实时渲染帧率、音视频码率、网络下行码率
示例如下:
// 获取当前渲染的帧率,数据类型为Float。
aliyunVodPlayer.getOption(Option.RenderFPS);
// 获取当前播放的视频码率,数据类型为Float,单位为bps。
aliyunVodPlayer.getOption(Option.VideoBitrate);
// 获取当前播放的音频码率,数据类型为Float,单位为bps。
aliyunVodPlayer.getOption(Option.AudioBitrate);
// 获取当前的网络下行码率,数据类型为Float,单位为bps。
aliyunVodPlayer.getOption(Option.DownloadBitrate);
音画不同步回调
指极端条件下(软解播放4K或者低端机高倍速播放高清H265流等),解码性能无法跟上播放速度时,会通过回调提示。示例如下:
private mAvNotSync: OnAVNotSyncStatusListener = {
onAVNotSyncStart: (type: number): void => {
showToast("onAVNotSyncStart start");
let aliyunVodPlayer: AliPlayer | undefined = this.getPlayer();
if (aliyunVodPlayer) {
if (aliyunVodPlayer.getSpeed() > 1) {
aliyunVodPlayer.setSpeed(1);
}
}
},
onAVNotSyncEnd: (): void => {
showToast("onAVNotSyncStart end");
}
}
aliyunVodPlayer.setOnAVNotSyncStatusListener(this.mAvNotSync);
设置音量
设置音量包括音量调节和静音设置。
音量调节
指调节音量大小,支持0~2倍,当音量大于1时,可能出现噪音,不推荐使用。由setVolume
接口实现。设置后还可获取音量信息。示例如下:
// volume的值为0~2之间的实数。
aliyunVodPlayer.setVolume(1.0f);
// 获取音量信息。
aliyunVodPlayer.getVolume();
静音设置
指将播放中的视频设置为静音状态,由setMute
接口实现。示例如下:
aliyunVodPlayer.setMute(true);
倍速播放
鸿蒙HarmonyOS NEXT播放器SDK提供了倍速播放视频的功能,通过设置setSpeed
方法,能够以0.5倍~5倍速去播放视频。同时保持变声不变调。示例如下:
// 设置倍速播放:支持0.5~5倍速的播放,通常按0.5的倍数来设置,例如0.5倍、1倍、1.5倍等
aliyunVodPlayer.setSpeed(1.0f);
多清晰度设置
直播UrlSource播放方式
支持阿里云视频直播的播放地址或经直播转码后(现支持通用转码和自定义转码)的转码流地址,直播转码详情请参见转码管理;地址获取方式请参见生成推流地址和播放地址。
支持FLV协议的直播流的不同清晰度切换。
推流的gop size需要设置为1s或2s,过大会导致切流跳变。
播放域名需开启选项:FLV播放时输出RTMP时间戳、上游断流后输出RTMP时间戳;转码配置需开启选项:时间戳随源、关键帧随源,否则会导致切流卡顿或失败。如需开启请提交工单申请。
切换到不符合上述要求的流地址时,会切换失败。
切换清晰度
通过switchStream
方法切换清晰度,传递对应新清晰度的URL即可。
aliyunVodPlayer.switchStream(newUrl);
清晰度切换通知
清晰度切换成功与失败回调。
private mOnStreamSwitchedListener: OnStreamSwitchedListener = {
onSwitchedSuccess: (url: string): void => {
console.log('onSwitchedSuccess', url);
},
onSwitchedFail: (url: string, errorInfo: ErrorInfo): void => {
console.log('onSwitchedFail', url);
}
}
aliyunVodPlayer.setOnStreamSwitchedListener(this.mOnStreamSwitchedListener);
点播Vid播放方式(VidAuth或VidSts)
如果使用Vid方式(VidAuth或VidSts)播放,无需额外设置。鸿蒙HarmonyOS NEXT播放器SDK会从点播服务获取清晰度列表。
获取清晰度
当视频加载完成后,可以获取视频的清晰度。
let mediaInfo: MediaInfo | null | undefined = aliyunVodPlayer?.getMediaInfo();
let trackInfos: TrackInfo[] | undefined = mediaInfo?.getTrackInfos();
if (trackInfos) {
for (let i: number = 0; i< trackInfos.length; i++) {
if(trackInfos[i].getType() == TrackType.TYPE_VOD){
//获取视频清晰度
console.log("track vod definition is " + trackInfos[i].getVodDefinition());
}
}
}
切换清晰度
通过selectTrack
方法切换清晰度,传递对应TrackInfo的index即可。
aliyunVodPlayer.selectTrack(index);
清晰度切换通知
清晰度切换成功与失败回调。
private mOnTrackChange: OnTrackChangedListener = {
//清晰度切换成功
onChangedSuccess: (trackInfo: TrackInfo): void => {
}
}
aliyunVodPlayer.setOnTrackChangedListener(this.mOnTrackChange);
快切模式
开启快切模式后,手动调用selectTrack
时,都会快速得到响应。
playerConfig.mSelectTrackBufferMode = 1;
aliyunVodPlayer.setConfig(playerConfig)
循环播放
鸿蒙HarmonyOS NEXT播放器SDK提供了循环播放视频的功能。调用setLoop
开启循环播放,播放完成后,将会自动从头开始播放视频。示例如下:
aliyunVodPlayer.setLoop(true);
同时循环开始的回调将会使用onInfo
中通知。示例如下:
private mOnVideoInfo: OnInfoListener = {
//播放器中的一些信息,包括:当前进度、缓存位置等等。
onInfo: (bean: InfoBean) => {
if (bean.getCode() === InfoCode.LoopingStart) {
//循环播放开始事件
}
}
}
切换音轨
鸿蒙HarmonyOS NEXT播放器SDK提供了切换音轨的功能,适用于用户观看多语言配音的视频时可以自主进行配音语言切换等场景。
使用说明
目前仅支持非列表播放流(例如MP4流)、单码率混合HLS流、单码率非混合HLS流的音频流之间的切换以及多码率混合HLS流的子流切换。各类型视频流说明如下:
视频流类型 | 视频流后缀 | 码率数量 | 子m3u8数量 | 子流类型 | 切换说明 |
非列表播放流(例如MP4流) | .mp4 | 1 | - | 一条播放流汇聚了一路视频流、可能多路音频流和多路字幕流。 | 支持多路音频流之间的切换。 |
单码率混合HLS流 | .m3u8 | 1 | 1 | 一条播放流汇聚了一路视频流、可能多路音频流和多路字幕流。 | 支持多路音频流之间的切换。 |
单码率非混合HLS流 | .m3u8 | 1 | n | m3u8,每条子流只能是视频流、音频流或字幕流中的一种。 | 支持多路音频流之间的切换。 |
多码率混合HLS流 | .m3u8 | n | n | m3u8,每条子流汇聚了一路视频流、可能多路音频流和多路字幕流,不同子流之间码率不同。 | 目前仅支持子流之间的切换,不支持子流的多路音频流之间的切换。 |
使用示例
设置回调。
private mOnSubTrackReady: OnSubTrackReadyListener = { onSubTrackReady: (mediaInfo: MediaInfo): void => { let aliyunVodPlayer: AliPlayer | undefined = this.getPlayer(); if ((!aliyunVodPlayer)) { console.log("[HOS DEMO] PLAYER PAGE register listeners ", "NUL ", this.aliPlayerIndex); } if (aliyunVodPlayer) { let subInfo: MediaInfo | null = aliyunVodPlayer.getSubMediaInfo(); if (subInfo) { let trackInfos: TrackInfo[] = subInfo.getTrackInfos(); //判断要选择的Track let trackInfo: TrackInfo = myfunc(trackInfos); } } } } aliyunVodPlayer.setOnSubTrackReadyListener(this.mOnSubTrackReady);
切换音轨。
index = myTrack.getIndex(); aliyunVodPlayer.selectTrack(index);
获取SDK日志
在播放器SDK运行过程中会生成详细的日志信息,包括网络请求的状态、系统调用的结果、权限申请情况等各种运行时事件。开发者可以通过查看这些日志进行代码调试或排查问题,提高开发效率。
方式一:通过开发工具的控制台获取播放器SDK日志
此方式适用于在您本地可以复现问题并抓取日志的场景。
打开日志并设置日志级别。
// Logger在com.cicada.player.utils下 import { Logger, LogLevel, OnLogCallback } from 'premierlibrary/src/main/ets/com/cicada/player/utils/Logger' // 打开日志开关 Logger.getInstance(context).enableConsoleLog(true); // 设置日志级别,默认为AF_LOG_LEVEL_INFO,如需排查问题,可设置为AF_LOG_LEVEL_TRACE Logger.getInstance(context).setLogLevel(LogLevel.AF_LOG_LEVEL_INFO);
设置帧级别日志。
//设置帧级别日志打印(可选) //选项value 0代表关闭 1代表打开 Logger.getInstance(this).setLogOption(LogOption.FRAME_LEVEL_LOGGING_ENABLED,value);
说明设置帧级别日志功能主要在排查故障场景下使用。
收集日志。
复现问题后,可在您开发工具(例如Logcat)的控制台获取日志。
方式二:通过LogCallback监听播放器SDK的输出日志
此方式适用于问题发生在您的用户侧,在您本地无法复现问题并抓取日志的场景。可以通过LogCallback监听播放器SDK的输出日志,并自动输出到您App的日志通道中。
打开日志并设置日志级别。
// Logger在com.cicada.player.utils下 // 设置日志级别,默认为AF_LOG_LEVEL_INFO,如需排查问题,可设置为AF_LOG_LEVEL_TRACE Logger.getInstance(context).setLogLevel(LogLevel.AF_LOG_LEVEL_INFO); let mOnLogCallBack: OnLogCallback = { onLog: (level: LogLevel, msg: string) => { let filePath = getContext().cacheDir + '/log/localLog.txt'; if (!fs.accessSync(filePath) && !fs.accessSync(getContext().cacheDir + '/log/')) { fs.mkdirSync(getContext().cacheDir + '/log/'); } let uri = fileUri.getUriFromPath(filePath); let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); let filestat = fs.statSync(filePath); let options: WriteOptions = {offset: filestat.size}; fs.write(file.fd, msg, options, (err: BusinessError, writeLen: number) => { if (err) { console.error("write data to file failed with error message:" + err.message + ", error code: " + err.code); } else { console.info("write data to file succeed and size is:" + writeLen); } fs.closeSync(file); }); } } Logger.getInstance(getContext()).setLogCallback(this.mOnLogCallBack);
收集日志。
复现问题后,日志将通过您App的日志通道自动输出到您App的日志文件。