Basic features

更新时间:
复制 MD 格式

This topic describes how to create a player instance for ApsaraVideo Player SDK for HarmonyOS NEXT and provides examples of how to use basic playback features, such as setting the volume, video seeking, monitoring the playback status, enabling loop playback, and configuring the playback speed.

Set the playback source (DataSource)

  • ApsaraVideo Player SDK for HarmonyOS NEXT supports four video-on-demand (VOD) playback methods: VidAuth (recommended for ApsaraVideo VOD users), VidSts, UrlSource, and encrypted playback.

  • ApsaraVideo Player SDK for HarmonyOS NEXT supports only one live stream playback method: UrlSource.

VOD playback

(Recommended) VidAuth VOD playback

If you use the VidAuth method to play a VOD video, set the vid property of the player to the audio or video ID and set the playAuth property to the playback credential.

  • After you upload an audio or video file, you can log in to the ApsaraVideo VOD console and choose Media Files > Audio/Video to view the ID of the audio or video file. Alternatively, you can call the SearchMedia operation to obtain the ID.

  • You can call the GetVideoPlayAuth operation to obtain the playback credential. We recommend that you integrate an ApsaraVideo VOD server-side software development kit (SDK) to obtain the playback credential. This frees you from complex signature calculations. For an example of how to call the operation to obtain a playback credential, see OpenAPI Explorer.

We recommend that ApsaraVideo VOD users use this playback method. Compared with the Security Token Service (STS) method, the VidAuth method is more secure and easier to use. For more information about the comparison, see Comparison between credentials and STS.

If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, the default parameter name is MtsHIsUriToken. For more information, see HLS encryption parameter pass-through. In this case, set the MtsHIsUriToken value in the VOD source as shown in the following code.

import { AliPlayerFactory, AliPlayer, VidAuth } from 'premierlibrary';
interface IAuthInfo { videoId: string, playAuth: string }
@Preview
@Component
export struct MyPlayerComponent {
  private authInfo: IAuthInfo = {
    videoId: 'VOD vid',
    playAuth: 'playauth',
  };
  private aliyunVodPlayer: AliPlayer = AliPlayerFactory.createAliPlayer(getContext(), '');
  playByVidAndAuth() {
    const vidAuthSource: VidAuth = new VidAuth();
    vidAuthSource.setVid(this.authInfo.videoId); // Required. The video ID.
    vidAuthSource.setPlayAuth(this.authInfo.playAuth); // Required. The playback credential. You must call the GetVideoPlayAuth operation of ApsaraVideo VOD to generate the credential.
    
    // If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console and the default parameter name is MtsHlsUriToken, you must set the config and pass it to the vid. For more information, see the following code.
    // If you do not enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, you do not need to integrate the following code.
    let config:VidPlayerConfigGen = new VidPlayerConfigGen();
    config.setMtsHlsUriToken("<yourMtsHlsUriToken>");
    vidAuthSource.setPlayerConfig(config);
    
    aliyunVodPlayer.setVidAuthDataSource(vidAuthSource);
  }
}

VidSts VOD playback

The VidSts method uses a temporary STS token instead of a playback credential to play a VOD video. You must obtain an STS token and an AccessKey pair (AccessKey ID and AccessKey secret) in advance. For more information, see Obtain an STS token.

If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, the default parameter name is MtsHIsUriToken. For more information, see HLS encryption parameter pass-through. In this case, set the MtsHIsUriToken value in the VOD source as shown in the following code.

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: 'VOD 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); // Required. The video ID.
    vidStsSource.setAccessKeyId(this.stsInfo.accessKeyId); // Required. The AccessKey ID of the temporary AccessKey pair. You must call the AssumeRole operation of STS to generate the AccessKey ID.
    vidStsSource.setAccessKeySecret(this.stsInfo.accessKeySecret); // Required. The AccessKey secret of the temporary AccessKey pair. You must call the AssumeRole operation of STS to generate the AccessKey secret.
    vidStsSource.setSecurityToken(this.stsInfo.securityToken); // Required. The STS token. You must call the AssumeRole operation of STS to obtain the STS token.
    vidStsSource.setRegion(this.stsInfo.region); // Required. The ID of the region where ApsaraVideo VOD is accessed. Default value: cn-shanghai.
    
    // If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console and the default parameter name is MtsHlsUriToken, you must set the config and pass it to the vid. For more information, see the following code.
    // If you do not enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, you do not need to integrate the following code.
    let config:VidPlayerConfigGen = new VidPlayerConfigGen();
    config.setMtsHlsUriToken("<yourMtsHlsUriToken>");
    vidStsSource.setPlayerConfig(config);
    
    aliyunVodPlayer.setVidStsDataSource(vidStsSource);
  }
}

UrlSource VOD playback

If you use the UrlSource method to play a VOD video, set the setUrl property of the player to the playback URL.

  • Playback URL from ApsaraVideo VOD: You can call the GetPlayInfo operation to obtain the URL. We recommend that you integrate an ApsaraVideo VOD server-side SDK to obtain the playback URL. This frees you from complex signature calculations. For an example of how to call the operation to obtain a playback URL, see OpenAPI Explorer.

  • Local video URL: Make sure that you have the required access permissions to obtain the full path of the local video file using system APIs. Examples: /sdcard/xxx/xxx/xxx.mp4 or 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 playback URL';
  private aliyunVodPlayer: AliPlayer = AliPlayerFactory.createAliPlayer(getContext(), '');
  playByUrl() {
    let urlSource: UrlSource = new UrlSource();
    urlSource.setUri(this.videoUrl); // Required. The playback URL. This can be the URL of a third-party VOD service, a playback URL from ApsaraVideo VOD, or the URL of a local video.
    aliyunVodPlayer.setUrlDataSource(urlSource);
  }
}

Encrypted VOD playback

ApsaraVideo VOD supports two types of encryption methods: HTTP-Live-Streaming (HLS) encryption and Alibaba Cloud proprietary cryptography. For information about encrypted playback, see Play encrypted videos on HarmonyOS.

Live stream playback

UrlSource live stream playback

If you use the UrlSource method to play a live video, set the setUrl property of the player to the live streaming URL. The playback URL can be from a third-party live streaming service or a stream pulling URL from ApsaraVideo Live.

You can use the URL generator in the ApsaraVideo Live console to generate live streaming URLs. For more information, see Live URL generator.

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 = 'Live streaming URL';
  private aliyunVodPlayer: AliPlayer = AliPlayerFactory.createAliPlayer(getContext(), '');
  playByUrl() {
    let urlSource: UrlSource = new UrlSource();
    urlSource.setUri(this.videoUrl); // The playback URL. This can be the URL of a third-party live streaming service or a stream pulling URL from ApsaraVideo Live.
    aliyunVodPlayer.setUrlDataSource(urlSource);
  }
}
Note
  • The UrlSource method uses a URL for playback. The VidSts and VidAuth methods use a video ID (VID) for playback.

  • For more information about how to set the region, see Region IDs of ApsaraVideo VOD.

Control playback

ApsaraVideo Player SDK for HarmonyOS NEXT supports operations such as starting playback from a specific time, starting, pausing, and stopping playback.

Autoplay

You can enable video autoplay using the setAutoPlay method. This feature is disabled by default. The following code provides an example:

// aliyunVodPlayer is the player instance.
aliyunVodPlayer.setAutoPlay(true);

Prepare for playback

You can prepare the video for playback by calling the prepare method to start reading and parsing data. If autoplay is enabled, the video starts playing automatically after the data is parsed. The following code provides an example:

// aliyunVodPlayer is the player instance.
aliyunVodPlayer.prepare();

Start playback

You can start playing the video using the start method. The following code provides an example:

aliyunVodPlayer.start();

Start playback from a specific time

You can seek to a specific time and start playback from that point using the seekTo method. This is useful for scenarios such as dragging the progress bar or resuming playback. The following code provides an example:

// The position parameter specifies the time in milliseconds.
aliyunVodPlayer.seekTo(long position);

You can start playback from a specified position. This is useful when you want to start playback from a specific point in time. You must call this method once before each prepare call for the setting to take effect. The following code provides an example:

// Set the start time in milliseconds for the next prepare() call. This setting is valid only for the immediately following prepare() call.
// After prepare() is called, this value is automatically cleared. If this method is not called again before the next prepare() call, playback starts from the beginning.
// You can set seekMode to accurate or inaccurate mode.
aliyunVodPlayer.setStartTime(1000,SeekMode.Accurate);

Pause playback

You can pause the video using the pause method. The following code provides an example:

aliyunVodPlayer.pause();

Resume playback

You can resume playing the video using the start method. The following code provides an example:

aliyunVodPlayer.start();

Stop playback

You can stop playing the video using the stop method. The following code provides an example:

aliyunVodPlayer.stop();

Player status listeners

ApsaraVideo Player SDK for HarmonyOS NEXT lets you set player listeners to monitor the playback status.

Set player listeners

// We recommend that you download the demo and view the ReadMe.md file to understand best practices. This helps you implement quick integration.

// Import the definitions of callback listeners for the player as required.
import { OnPreparedListener, OnCompletionListener, OnAudioInterruptEventListener,OnErrorListener,OnInfoListener,OnLoadingStatusListener, AudioStatus } from 'premierlibrary/src/main/ets/com/aliyun/player/IPlayer';

// The player instance.
const aliyunVodPlayer: AliPlayer = AliPlayerFactory.createAliPlayer(getContext(), traceId);

// Define callback listeners.
const mPreparedEventHandler: OnPreparedListener = { // Listen for the completion of preparation.
  onPrepared: () => {
    console.log("prepared");
  }
};
const mCompletionEventHandler: OnCompletionListener = { // Listen for the completion of playback.
  onCompletion: () => {
    console.log("play complete");
  }
}
const mOnAudioInterruptListener: OnAudioInterruptEventListener = { // Listen for audio interruption.
  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(); // Resume the playback.
          break;
        case AudioStatus.AUDIO_STATUS_PAUSE:
          statusInfo = "AUDIO_STATUS_PAUSE"
          aliyunVodPlayer.pause(); // Pause the playback.
          break;
        case AudioStatus.AUDIO_STATUS_STOP:
          statusInfo = "AUDIO_STATUS_STOP"
          aliyunVodPlayer.stop(); // Stop the playback.
          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 = { // Listen for errors.
  onError:(errorInfo) => {
    let errorCode:PlayerErrorCode = errorInfo.getCode(); // The error code.
    let errorMsg:string = errorInfo.getMsg(); // The error message.
    // errorExtra indicates the supplementary error message. The value is a JSON string. The following sample code shows the structure of the errorExtra parameter. Note that the value of ModuleCode is not the same as the value of errorCode.
    // { "Url": "xxx",
 		//	"Module": "NetWork",
  	//	"ModuleCode": "-377",
 		//  "ModuleMessage": "Redirect to a url that is not a media"}
    let errorExtra:string = errorInfo.getExtra();
    
    // Stop the player if an error occurs.
    aliyunVodPlayer.stop();
  }
}
const mOnVideoInfo: OnInfoListener = { // Listen for video information.
  // The information about the player, such as the current playback progress and buffer position.
  onInfo: (bean: InfoBean) => {
    // Call InfoCode.CurrentPosition to obtain the current playback position.
    // Call InfoCode.BufferedPosition to obtain the current buffer position.
    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 = { // Listen for the loading and stuttering status.
  onLoadingBegin: () => {
      // The loading starts. Video and audio are not sufficient for playback.
      // In general, the loading circle is displayed.
  },
  onLoadingProgress: (percent: number, netSpeed: number) => {
     // The loading progress. The loading percentage and network speed are displayed.
     // The network speed is a reserved field and is currently 0.
  },
  onLoadingEnd: () => {
      // The loading ends. Video and audio can be played.
      // The loading circle is hidden.
  }
}

// Register the listeners with the player instance.
aliyunVodPlayer.setOnPreparedListener(mPreparedEventHandler);
aliyunVodPlayer.setOnCompletionListener(mCompletionEventHandler);
aliyunVodPlayer.setOnAudioInterruptEventListener(mOnAudioInterruptListener);
aliyunVodPlayer.setOnErrorListener(mOnErrorEventListener);
aliyunVodPlayer.setOnInfoListener(mOnVideoInfo);
aliyunVodPlayer.setOnLoadingStatusListener(mOnLoadingProgressEventListener);

Listen for playback status

You can listen for the player status. The onStateChanged callback parameter indicates the current player status. The following code provides an example:

/**
   * Listen for the player status.
   */
  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);

Set the video display mode

ApsaraVideo Player SDK for HarmonyOS NEXT lets you configure display settings for playback, such as scaling, rotating, and mirroring.

Scaling

You can call the setScaleMode method to scale a video to fit the view, fill the view, or stretch to fill the view. The following code provides an example:

// Scale the video to fit the view. The aspect ratio of the video is maintained. No image distortion occurs.
aliyunVodPlayer.setScaleMode(ScaleMode.SCALE_ASPECT_FIT);
// Scale the video to fill the view. The aspect ratio of the video is maintained. No image distortion occurs.
aliyunVodPlayer.setScaleMode(ScaleMode.SCALE_ASPECT_FILL);
// Stretch the video to fill the view. If the aspect ratios of the video and the view are different, image distortion may occur.
aliyunVodPlayer.setScaleMode(ScaleMode.SCALE_TO_FILL);

Rotating

You can rotate the video image by a specified angle using the setRotateMode method. You can also query the rotation angle after it is set. The following code provides an example:

// Set the rotation angle to 0 degrees clockwise.
aliyunVodPlayer.setRotateMode(RotateMode.ROTATE_0);
// Set the rotation angle to 90 degrees clockwise.
aliyunVodPlayer.setRotateMode(RotateMode.ROTATE_90);
// Set the rotation angle to 180 degrees clockwise.
aliyunVodPlayer.setRotateMode(RotateMode.ROTATE_180);
// Set the rotation angle to 270 degrees clockwise.
aliyunVodPlayer.setRotateMode(RotateMode.ROTATE_270);
// Get the rotation angle.
aliyunVodPlayer.getRotateMode();

Mirroring

You can display the video image with a mirroring effect. Horizontal mirroring, vertical mirroring, and no mirroring are supported. You can use the setMirrorMode method to set the mirroring mode. The following code provides an example:

// Set no mirroring.
aliyunVodPlayer.setMirrorMode(MirrorMode.MIRROR_MODE_NONE);
// Set horizontal mirroring.
aliyunVodPlayer.setMirrorMode(MirrorMode.MIRROR_MODE_HORIZONTAL);
// Set vertical mirroring.
aliyunVodPlayer.setMirrorMode(MirrorMode.MIRROR_MODE_VERTICAL);

Get playback information

ApsaraVideo Player SDK for HarmonyOS NEXT lets you obtain information such as the current playback progress, video duration, and buffer position.

Get the current playback progress

You can obtain the current playback position in the onInfo callback using the getExtraValue method. The following code provides an example:

private mOnVideoInfo: OnInfoListener = {
    // The information about the player, such as the current playback progress and buffer position.
    onInfo: (bean: InfoBean) => {
      if (bean.getCode() === InfoCode.CurrentPosition) {
        // The extraValue parameter indicates the current playback position in milliseconds.
        let extraValue: number = bean.getExtraValue();
      } 
    }
  }

Get the video duration

You can obtain the total duration of the video. You can obtain the video duration only after the video is loaded. You can obtain the duration after the onPrepared event. Use the getDuration method to obtain the duration. The following code provides an example:

aliyunVodPlayer.getDuration();

Get the actual playback duration

You can obtain the actual playback duration in real time. The obtained duration does not include the time spent on pauses or stuttering during playback. The following code provides an example:

aliyunVodPlayer.getPlayedDuration();

Get buffering progress

You can obtain the current buffer position of the video in the onInfo callback using the getExtraValue method. The following code provides an example:

private mOnVideoInfo: OnInfoListener = {
  // The information about the player, such as the current playback progress and buffer position.
  onInfo: (bean: InfoBean) => {
    if (bean.getCode() === InfoCode.BufferedPosition) {
      // The extraValue parameter indicates the current buffer position in milliseconds.
      let extraValue: number = bean.getExtraValue();
    } 
  }
}

Get the real-time rendering frame rate, audio and video bitrate, and network downlink bitrate

Example:

// Get the current rendering frame rate. The returned data is of the FLOAT data type.
aliyunVodPlayer.getOption(Option.RenderFPS);
// Get the current video bitrate. The returned data is of the FLOAT data type. Unit: bit/s.
aliyunVodPlayer.getOption(Option.VideoBitrate);
// Get the current audio bitrate. The returned data is of the FLOAT data type. Unit: bit/s.
aliyunVodPlayer.getOption(Option.AudioBitrate);
// Get the current network downlink bitrate. The returned data is of the FLOAT data type. Unit: bit/s.
aliyunVodPlayer.getOption(Option.DownloadBitrate);

Audio-video out-of-sync callback

In extreme conditions, such as software decoding of 4K videos or high-speed playback of high-definition H.265 streams on low-end devices, the decoding performance may not keep up with the playback speed. In such cases, a callback is triggered. The following code provides an example:

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);

Set the volume

You can adjust the volume and mute the player.

Change the volume

You can adjust the volume. You can set the volume to a value from 0 to 2. If you set the volume to a value greater than 1, noise may occur. We recommend that you do not set the volume to a value greater than 1. You can use the setVolume method to change the volume. You can also retrieve the current volume. The following code provides an example:

// The value of volume is a real number from 0 to 2.
aliyunVodPlayer.setVolume(1.0f);
// Get the volume.
aliyunVodPlayer.getVolume();

Mute the player

You can mute the video that is being played using the setMute method. The following code provides an example:

aliyunVodPlayer.setMute(true);

Configure the playback speed

ApsaraVideo Player SDK for HarmonyOS NEXT lets you change the playback speed using the setSpeed method. You can set the playback speed to a value from 0.5x to 5x. The audio pitch remains unchanged at different speeds. The following code provides an example:

// Set the playback speed. Speeds from 0.5x to 5x are supported. Common playback speeds are multiples of 0.5, such as 0.5x, 1x, and 1.5x.
aliyunVodPlayer.setSpeed(1.0f);

Configure multi-definition settings

UrlSource live stream playback

    Note
    • This feature supports playback URLs from ApsaraVideo Live or URLs of transcoded streams that are generated using live stream transcoding. Both default transcoding and custom transcoding are supported. For more information about live stream transcoding, see Transcoding Management. For more information about how to obtain the URLs, see Generate streaming URLs.

    • This feature supports definition switching for live streams that use the FLV protocol.

    • The group of pictures (GOP) size for stream ingest must be set to 1 s or 2 s. A larger value may cause jitter during stream switching.

    • The playback domain name must have the following options enabled: Output RTMP timestamp for FLV playback and Output RTMP timestamp after upstream ingest is interrupted. The transcoding configuration must have the following options enabled: Timestamp follows source and Keyframe follows source. Otherwise, stream switching may stutter or fail. To enable these options, submit a ticket.

    • If you switch to a stream URL that does not meet the preceding requirements, the switch fails.

Switch definition

You can use the switchStream method to switch the definition. You need to pass the URL of the new definition.

aliyunVodPlayer.switchStream(newUrl);

Resolution Switching Notifications

Callbacks are triggered when definition switching succeeds or fails.

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-based VOD playback (VidAuth or VidSts)

If you use the VidAuth or VidSts method for playback, no additional settings are required. ApsaraVideo Player SDK for HarmonyOS NEXT automatically obtains the definition list from ApsaraVideo VOD.

Get definitions

After a video is loaded, you can obtain the definitions of the video.

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){
      // Get the video definition.
      console.log("track vod definition is " + trackInfos[i].getVodDefinition());
    }
  }
}

Switch between definitions

To switch the definition, call the selectTrack method and pass the index of the corresponding TrackInfo.

aliyunVodPlayer.selectTrack(index);

Definition switching notifications

Callbacks for the success or failure of a definition switch.

private mOnTrackChange: OnTrackChangedListener = {
  // The definition is switched successfully.
  onChangedSuccess: (trackInfo: TrackInfo): void => {
    
  }
}
aliyunVodPlayer.setOnTrackChangedListener(this.mOnTrackChange);

Fast switching mode

After you enable the fast switching mode, manual calls to selectTrack are responded to quickly.

playerConfig.mSelectTrackBufferMode = 1;
aliyunVodPlayer.setConfig(playerConfig)

Loop playback

ApsaraVideo Player SDK for HarmonyOS NEXT supports loop playback. You can call the setLoop method to enable loop playback. After the video finishes playing, it automatically starts again from the beginning. The following code provides an example:

aliyunVodPlayer.setLoop(true);

The onInfo callback is triggered when loop playback starts. The following code provides an example:

private mOnVideoInfo: OnInfoListener = {
  // The information about the player, such as the current playback progress and buffer position.
  onInfo: (bean: InfoBean) => {
    if (bean.getCode() === InfoCode.LoopingStart) {
      // The event for the start of loop playback.
    } 
  }
}

Switch audio tracks

ApsaraVideo Player SDK for HarmonyOS NEXT lets you switch audio tracks. This is useful in scenarios where users can switch between dubbed languages when watching videos with multiple language options.

Instructions

Currently, this feature supports switching between audio streams for non-list playback streams (such as MP4 streams), single-bitrate mixed HLS streams, and single-bitrate non-mixed HLS streams. It also supports substream switching for multi-bitrate mixed HLS streams. The following table describes the video stream types.

Video stream type

Video stream suffix

Number of bitrates

Number of child m3u8 files

Substream type

Switching instructions

Non-list playback stream (such as an MP4 stream)

.mp4

1

-

A playback stream contains one video stream, and may contain multiple audio streams and multiple caption streams.

Supports switching between multiple audio streams.

Single-bitrate mixed HLS stream

.m3u8

1

1

A playback stream contains one video stream, and may contain multiple audio streams and multiple caption streams.

Supports switching between multiple audio streams.

Single-bitrate non-mixed HLS stream

.m3u8

1

n

m3u8. Each substream can be a video stream, an audio stream, or a caption stream.

Supports switching between multiple audio streams.

Multi-bitrate mixed HLS stream

.m3u8

n

n

m3u8. Each substream contains one video stream, and may contain multiple audio streams and multiple caption streams. Different substreams have different bitrates.

Currently, only switching between substreams is supported. Switching between multiple audio streams within a substream is not supported.

Usage example

  1. Set the callback.

    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();
    
            // Determine the track to select.
            let trackInfo: TrackInfo = myfunc(trackInfos);
          }
        }
      }
    }
    
    aliyunVodPlayer.setOnSubTrackReadyListener(this.mOnSubTrackReady);
  2. Switch the audio track.

    index = myTrack.getIndex();
    aliyunVodPlayer.selectTrack(index);

Get SDK logs

During runtime, the player SDK generates detailed logs, including the status of network requests, results of system calls, and permission requests. You can view these logs to debug code or troubleshoot issues, which improves development efficiency.

Method 1: Get SDK logs from the console of the development tool

This method is suitable for scenarios where you can reproduce the issue and capture logs on your local machine.

  1. Enable logging and set the log level.

    // Logger is under com.cicada.player.utils
    import { Logger, LogLevel, OnLogCallback } from 'premierlibrary/src/main/ets/com/cicada/player/utils/Logger'
    
    // Enable console logging.
    Logger.getInstance(context).enableConsoleLog(true);
    // Set the log level. The default level is AF_LOG_LEVEL_INFO. To troubleshoot issues, you can set it to AF_LOG_LEVEL_TRACE.
    Logger.getInstance(context).setLogLevel(LogLevel.AF_LOG_LEVEL_INFO);
  2. Set frame-level logging.

    // Set frame-level logging (optional).
    // A value of 0 for the option disables the feature, and a value of 1 enables it.
    Logger.getInstance(this).setLogOption(LogOption.FRAME_LEVEL_LOGGING_ENABLED,value);
    Note

    Frame-level logging is mainly used for troubleshooting.

  3. Collect logs.

    After reproducing the issue, you can obtain the logs from the console of your development tool, such as Logcat.

Method 2: Listen for SDK output logs using LogCallback

This method is suitable for scenarios where the issue occurs on the user's side and you cannot reproduce it to capture logs locally. You can use LogCallback to listen for the SDK's output logs and automatically write them to your app's log channel.

  1. Enable logging and set the log level.

    // Logger is under com.cicada.player.utils
    // Set the log level. The default level is AF_LOG_LEVEL_INFO. To troubleshoot issues, you can set it to 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);
  2. Collect logs.

    After the issue is reproduced, the logs are automatically written to your app's log file through your app's log channel.