Advanced features

更新时间:
复制 MD 格式

This topic covers the advanced features of ApsaraVideo Player SDK for HarmonyOS NEXT and provides sample code.

Premium feature verification

Note

Some player features require a premium license. For more information, see Player SDK Feature Details. To use these features, obtain the license as described in Obtain Player SDK License.

Set the listener at application startup or before calling any player API:

import { PrivateService } from 'premierlibrary';

let premiumVerifyCallback:OnPremiumLicenseVerifyCallback = {
  onPremiumLicenseVerifyCallback: (type: PremiumBizType, isValid: boolean, errorMsg: string) => {
    console.log("onPremiumLicenseVerifyCallback type: ", type, " isValid: ", isValid, " errorMsg: ", errorMsg);
  }
}

PrivateService.setOnPremiumLicenseVerifyCallback(premiumVerifyCallback)

In this code, PremiumBizType is the enum for premium features. When you use a related feature, the player verifies the license and returns the result via this callback. If isValid is false, errorMsg contains the reason.

Playback

List playback

For typical short video feed scenarios, ApsaraVideo Player SDK for HarmonyOS NEXT provides a comprehensive list playback feature. Using features like preloading, it significantly improves the startup speed of short videos. This feature is not recommended for long video scenarios.

Limits

Enable the local cache and the preloading feature before you use list playback. For more information, see Preloading.

Procedure

  1. Create a player.

    Use the AliPlayerFactory class to create an AliListPlayer object. Sample code:

    let aliyunListPlayer: AliListPlayer = AliPlayerFactory.createAliListPlayer(getContext());
    aliyunListPlayer.setTraceId(traceId);
  2. Optional:Set listeners.

    Although optional, we recommend setting listeners to receive notifications for important player events, such as playback failures and progress updates. Key listeners include OnPreparedListener, OnErrorListener, OnCompletionListener, OnLoadingStatusListener, and OnInfoListener.

  3. Set the number of videos to preload.

    To improve startup speed, set a reasonable number of videos to preload. Sample code:

    // Set the number of videos to preload. The total number of loaded videos is: 1 + count * 2.
    aliyunListPlayer.setPreloadCount(count);
  4. Add or remove multiple playback sources.

    List playback supports two types of playback sources: Vid-based playback (including VidSts and VidPlayAuth) and UrlSource-based playback. The URL is the playback URL of the video.

    • Url: The playback URL can be a third-party VOD URL or a playback URL from ApsaraVideo VOD. You can obtain an ApsaraVideo VOD playback URL by calling the relevant API operation. We recommend integrating the ApsaraVideo VOD server-side SDK to obtain playback URLs, which simplifies the signing process. For an example of calling an API to obtain audio and video playback URLs, see OpenAPI Explorer.

    • Vid: The audio/video ID. After an audio or video file is uploaded, you can obtain its ID from the console (path: Media Files > Audio/Video) or by calling a server-side API operation (SearchMedia).

    let uid:string = generateUid();// The generateXXX method is a hypothetical local method for demonstration purposes and is not a player method.
    
    // Add a UrlSource playback source.
    let url:string = generateUrl();
    aliyunListPlayer.addUrl(url, uid);
    
    // Remove a source.
    aliyunListPlayer.removeSource(uid);
    Note

    The uid uniquely identifies a video and is used to determine whether two videos are the same. If the uids are identical, the videos are considered the same. If stream mix-ups occur during playback, check whether the same uid has been set on different pages. The uid has no format restrictions and can be any string.

  5. Set the display view.

    Bind the player to the HarmonyOS XComponent to render the video frames.

    Sample code

    // We recommend that you download the demo and view the atomic access solution in the best practices.
    // The following code is an example of a @Component in the HarmonyOS ArkTS environment.
    
    /**
     * Atomic access to the ApsaraVideo Player SDK for HarmonyOS NEXT
     * Based on the lowest-level HarmonyOS XC capability, this provides the simplest integration method and offers high freedom for custom development.
     * Three steps to implement video playback.
     */
    
    import { AliPlayerFactory, AliPlayer } from 'premierlibrary';
    
    @Preview
    @Component
    export struct MyPlayerComponent {
    
      private videoUrl: string = 'HTTP playback URL';
      private xComponentController = new XComponentController();
      private aliListPlayer: AliListPlayer = AliPlayerFactory.createAliLstPlayer(getContext(), '');
    
      build() {
        XComponent({
          id: '0', // unique XC id
          type: XComponentType.SURFACE,
          libraryname: 'premierlibrary',
          controller: this.xComponentController
        })
        .onLoad(async () => {
    
          // Prepare the URL object.
          let url: string = generateUrl();
          let uid: string = generateUid();
    
          // Bind the URL and XC_SurfaceId.
          this.aliListPlayer.addUrl(url, uid);
          this.aliListPlayer.setSurfaceId('0'); // surface ID corresponds to XC ID.
    
          // Play the video.
          this.aliListPlayer.setAutoPlay(true);
          this.aliListPlayer.moveTo(uid);
        })
        .width('100%')
        .height(200)
      }
    
      aboutToDisappear(): void {
        if (this.aliListPlayer) {
          this.aliListPlayer.stop();
          this.aliListPlayer.release();
        }
      }
    }
  6. Play a video source.

    After you add one or more playback sources and enable autoplay, call moveTo to automatically play a specific video source. Sample code:

    Sample code

    // Enable autoplay.
    aliyunListPlayer.setAutoPlay(true);
    
    // Use this interface for URLs.
    aliyunListPlayer.moveTo(uid);
  7. Play the previous or next video.

    • After calling moveTo to play a video source, call the moveToPrev and moveToNext methods to play the previous and next videos, using the video source from moveTo as the anchor. Sample code:

      Note

      When you switch video sources by calling moveTo, moveToNext, or similar methods within the same view, flickering or a black screen may occur. In this case, we recommend setting the mClearFrameWhenStop field of PlayerConfig to false during listPlayer initialization and calling setConfig to apply the change.

      Sample code

      // Enable autoplay.
      aliyunListPlayer.setAutoPlay(true);
      
      // Move to the next video. Note: This can only be used for URL sources. This method is not applicable for Vid-based playback.
      aliyunListPlayer.moveToNext();
      // Move to the previous video. Note: This can only be used for URL sources. This method is not applicable for Vid-based playback.
      aliyunListPlayer.moveToPrev();
    • Request PlayAuth information based on the vid, and then call moveTo, moveToNext, or similar methods after the request succeeds.

      Note

      Only VidPlayAuth-based playback requires requesting PlayAuth information based on the vid.

      Sample code

      requestAuth(source.getVideoId(), new OnRequestAuthResultListener() {
          @Override
          public void onResult(VidAuth vidAuth) {
              mVideoListPlayer.moveToNext(createVidAuth(vidAuth));
          }
      });
      
      private PlayAuthInfo createVidAuth(VidAuth vidAuth) {
          if (vidAuth == null) {
              return new PlayAuthInfo();
          }
          PlayAuthInfo playAuthInfo = new PlayAuthInfo();
          playAuthInfo.setPlayAuth(vidAuth.getPlayAuth());
          return playAuthInfo;
      }

Transparent video playback

Overview

ApsaraVideo Player SDK for HarmonyOS NEXT supports rendering the alpha channel to play dynamic effects such as transparent gifts. In scenarios like live streaming rooms, you can play transparent gift animations without obscuring the main content, which significantly enhances the user experience.

Limits

Transparent rendering is supported in ApsaraVideo Player SDK for HarmonyOS NEXT v6.21.0 and later.

Benefits

Using MP4 videos that contain transparency information for gift effects offers better animation quality, smaller file sizes, higher compatibility, and greater development efficiency.

  1. Better animation quality: MP4 videos can preserve the original animation quality, including details and colors. Compared to other formats like APNG or IXD, MP4 can more accurately restore the animation effects created by designers.

  2. Smaller file sizes: MP4 video files can be compressed more effectively than other formats like APNG or IXD, which improves loading speed and reduces network bandwidth consumption.

  3. Higher compatibility: MP4 is a universal video format widely supported across various devices and browsers, allowing gift effects to be played and viewed on mainstream devices.

  4. Using MP4 videos for gift effects is technically straightforward. It eliminates the need for complex parsing and rendering logic, allowing developers to focus on other features and improve development efficiency.

Sample code

A new API is available to set the alpha mode, which specifies the position of the alpha channel in the video asset (top, bottom, left, or right). The default value is None.

Note
  • The position of the alpha channel in the asset must match the setting of the setAlphaRenderMode parameter.

  • The size of the player view must be proportional to the resolution of the asset.

  /**
   * Sets the alpha rendering mode.
   *
   * @param alphaRenderMode The specified alpha render mode. See {@link AlphaRenderMode}.
   */
  setAlphaRenderMode: (mode: AlphaRenderMode) => void;

AlphaSurface acts as a separate XComponent to play the alpha video independently. It is stacked on top of the main content's XComponent to achieve the gift effect. Sample code:

@Builder
AlphaSurface() {
  if (this.uiController.enableAlpha) {
    XComponent({
      id: this.alphaPlayerIndex.toString(),
      type: XComponentType.TEXTURE, // Gifts must use a texture; otherwise, a background color is displayed.
      libraryname: 'premierlibrary',
      controller: this.alphaXComponentController
    })
      .onLoad(async () => {
        console.log("HOS DEMO", "alpha enabled")
        const player = VideoController.getPlayer(this.alphaPlayerIndex);
        if (player) {
          player.setAlphaRenderMode(AlphaRenderMode.RENDER_MODE_ALPHA_AT_RIGHT);
          // Set the asset that corresponds to the alpha mode.
          const urlSource: UrlSource = new UrlSource();
          urlSource.setUri("https://alivc-player.oss-cn-shanghai.aliyuncs.com/video/%E4%B8%9A%E5%8A%A1%E9%9C%80%E6%B1%82%E6%A0%B7%E6%9C%AC/alpha%E9%80%9A%E9%81%93/alpha_right.mp4");
          player.setUrlDataSource(urlSource);
          player.setAutoPlay(true);
          player.setLoop(true);
          player.prepare();
          player.setSurfaceId(this.alphaPlayerIndex.toString());
        }
      })
      .opacity(0.5) // Gift opacity
      .width(this.uiController.alphaWidth)
      .height(this.uiController.alphaHeight)
      .position({x: this.uiController.alphaX, y: this.uiController.alphaY })
  }
}

External subtitles

ApsaraVideo Player SDK for HarmonyOS NEXT allows you to add and switch external subtitles. Subtitle files in the SubRip Subtitle (SRT), SubStation Alpha (SSA), Advanced SubStation Alpha (ASS), and WebVTT (VTT) formats are supported. However, the SDK does not provide a built-in renderer for external subtitles.

Important

This feature is available only in the Professional Edition. To use this feature, obtain a license for the Professional Edition. For more information, see Obtain a License for ApsaraVideo Player SDK.

Sample code:

  1. Set subtitle-related listeners.

    Sample code

    private mOnSubtitle: OnSubtitleDisplayListener = {
        onSubtitleExtAdded: (trackIndex: number, url: string): void => {
          // The external subtitle has been added.
        },
        onSubtitleShow: (trackIndex: number, id: number, data: string): void => {
          // The subtitle text is available in `data`. Render it as needed.
        },
        onSubtitleHide: (trackIndex: number, id: number): void => {
          // Hide the subtitle.
        },
        onSubtitleHeader: (trackIndex: number, header: string): void => {
          // Subtitle header information.
        }
      }
    
      mAliPlayer.setOnSubtitleDisplayListener(this.mOnSubtitle);
  2. Add subtitles.

    mAliPlayer.addExtSubtitle(url); // Add the subtitle after the player's onPrepared callback is triggered.
  3. Show or hide subtitles.

    After you receive the onSubtitleExtAdded callback, use the following method to show or hide subtitles:

    // trackIndex: the subtitle track index. true: shows the specified track; false: hides the specified track.
    mAliPlayer.selectExtSubtitle(trackIndex, true);

Audio-only playback

You can enable audio-only playback by disabling video playback. Configure PlayerConfig before you call the prepare method.

let config:PlayerConfig | undefined = player.getConfig();
if (config) {
  config.mDisableVideo = true; // Enable audio-only playback.
  player.setConfig(config);
}

Switching decoding modes

Note

The decoding method must be switched before playback starts, as changes do not take effect during playback.

ApsaraVideo Player SDK for HarmonyOS NEXT provides hardware decoding capabilities for H.264 and H.265, which can be controlled by using the enableHardwareDecoder switch. Hardware decoding is enabled by default. If hardware decoding fails to initialize, the player automatically falls back to software decoding to ensure normal video playback. Sample code:

// Enable hardware decoding. This is enabled by default.
mAliyunVodPlayer.enableHardwareDecoder(true);

If the player automatically switches from hardware to software decoding, the onInfo callback is triggered. Sample code:

private mOnVideoInfo: OnInfoListener = {
  onInfo: (bean: InfoBean) => {
    if (bean.getCode() === InfoCode.SwitchToSoftwareVideoDecoder) {
      console.log("[HOS DEMO] [DOWNGRADE TO SOFTWARE DECODE]")
      // Switched to software decoding.
    }
  }
}

Adaptive bitrate streaming

Important

The adaptive bitrate streaming (ABR) feature is available in Basic and high-performance Professional editions. Without the Professional Edition of ApsaraVideo Player SDK, its functionality is limited to the Basic Edition. To use the advanced ABR capabilities of the Professional Edition, refer to Get Player SDK License to obtain the required license.

Note
  • HLS adaptive bitrate video streams can be generated by using a video packaging and transcoding template group in ApsaraVideo VOD. For more information, see Configure adaptive bitrate streaming for ApsaraVideo VOD.

  • For adaptive streams generated by ApsaraVideo VOD transcoding, if you use Vid-based playback, you must specify the default playback definition list as DEFINITION_AUTO to obtain and play the adaptive stream. Otherwise, the player defaults to a low-definition stream for playback. For information about the default definition playback order, see If a video is transcoded into multiple definitions, which definition does the player SDK play by default? The following example shows how to specify the definition list for VidAuth-based playback:

    const vidAuthSource: VidAuth = new VidAuth();
    let list: Definition[] = [];
    list.push(Definition.DEFINITION_AUTO);
    vidAuthSource.setDefinition(list);
    
    player.setVidAuthDataSource(vidAuthSource);

ApsaraVideo Player SDK for HarmonyOS NEXT supports adaptive bitrate streaming for HLS and DASH video streams. After the prepare method succeeds, you can call getMediaInfo to obtain information about each stream in the form of TrackInfo objects. Sample code:

let mediaInfo: MediaInfo | null | undefined = player?.getMediaInfo();

let trackInfos: TrackInfo[] | undefined = mediaInfo?.getTrackInfos();

During playback, you can call the player's selectTrack method to switch the playback stream. Setting the value to AUTO_SELECT_INDEX enables adaptive bitrate streaming. Sample code:

let index: number | undefined = trackInfo?.getIndex();
if (index ) {
  player?.selectTrack(index);
}
player?.selectTrack(TrackInfo.AUTO_SELECT_INDEX);

The result of the switch is returned in the OnTrackChangedListener callback. You must set the listener before you call selectTrack. Sample code:

private mOnTrackChange: OnTrackChangedListener = {
  // The definition switch is successful.
  onChangedSuccess: (trackInfo: TrackInfo): void => {
    // Switch successful.
  }
}

Optional: Before you call the player's selectTrack method to enable adaptive bitrate streaming, you can configure an upper definition limit for ABR switching. This prevents the player from automatically switching to a stream that exceeds the desired quality. We recommend that you call the following code before the player calls the prepare method, or before the list player calls the moveTo method, for it to take effect. Sample code:

let config:PlayerConfig | undefined = player.getConfig();
if (config) {
  config.mMaxAllowedAbrVideoPixelNumber = 921600; // Set the ABR upper limit to 921600 pixels (width × height = 1280 × 720). ABR can switch only to streams with a pixel count less than or equal to this value.
  player.setConfig(config);
}

Snapshots

ApsaraVideo Player SDK for HarmonyOS NEXT provides a snapshot method to capture the current video frame. It captures the raw data and returns it as an ArrayBuffer. The callback interface is OnSnapShotListener. Sample code:

private mOnSnapShotListener: OnSnapShotListener = {
  onSnapShot: (arrayBuffer: ArrayBuffer, width: number, height: number): void => {
    // Must be in BGRA_8888 format.
    log.i("arrayBuffer size is " + arrayBuffer.byteLength);
    let opts: image.InitializationOptions = {
      editable: true,
      pixelFormat: 3,
      size: {
        height: height,
        width: width
      }
    };

    image.createPixelMap(arrayBuffer, opts).then((pixelMap: image.PixelMap) => {
      console.log("Succeeded in creating pixelmap");
      this.savePixelMap2SystemFileManager(pixelMap);
    }).catch((error: BusinessError) => {
      console.log(`Failed to create pixelmap. code is ${error.code}, message is ${error.message}`);
    })
  }
}

// Convert the pixelMap to an image format.
transferPixelMap2Buffer(pixelMap: image.PixelMap): Promise<ArrayBuffer> {
  return new Promise((resolve, reject) => {
    /**
     * Set packing options.
     * format: Image packing format. Only JPG and WebP are supported.
     * quality: JPEG encoding output image quality.
     * bufferSize: Image size. Default is 10M.
     */
    let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 98 };
    // Create an ImagePacker instance.
    const imagePackerApi = image.createImagePacker();
    imagePackerApi.packing(pixelMap, packOpts).then((buffer: ArrayBuffer) => {
      resolve(buffer);
    }).catch((error: BusinessError) => {
      console.info(`Failed to create pixelmap. code is ${error.code}, message is ${error.message}`);
      reject();
    })
  })
}

// Store the image to the cache directory.
async savePixelMap2SystemFileManager(pixelMap: image.PixelMap) {
  const imgBuffer = await this.transferPixelMap2Buffer(pixelMap);
  const now = new Date();
  const formattedDate = now.toISOString().slice(2, 19).replace(/[-T:]/g, '');
  const fileName = `/${formattedDate}.png`;
  const filePath = getContext().cacheDir + fileName;
  console.info("filepath is " + filePath); // Store the image in the cache path. The filename is the snapshot timestamp.

  const file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
  console.info("file has been opened " + file.fd);
  await fileIo.write(file.fd, imgBuffer);
  console.info("file has been write");
  await fileIo.close(file.fd);
  console.info("file has been close");
}

player.setOnSnapShotListener(this.mOnSnapShotListener); // Set the callback.

// Take a snapshot of the current playback frame.
player.snapshot()

Preview

ApsaraVideo Player SDK for HarmonyOS NEXT, in conjunction with ApsaraVideo VOD configurations, supports the preview feature. It supports both VidSts and VidAuth (recommended for ApsaraVideo VOD) playback methods. For more information about how to configure and use the preview feature, see Preview videos.

After you configure the preview feature, use the VidPlayerConfigGen.setPreviewTime() method to set the preview duration for the player. The following example shows the VidSts playback method:

const vidSts: VidSts = new VidSts();

....
let configGen: VidPlayerConfigGen = new VidPlayerConfigGen();
configGen.setPreviewTime(20); // 20-second preview
vidSts.setPlayConfig(configGen); // Set for the playback source.
...

When a preview duration is set, the server returns only the content for that period, not the full video.

Note
  • VidPlayerConfigGen supports request parameters that are supported by the server. For more information, see Request parameters.

  • The preview feature is not supported for videos in FLV and MP3 formats.

Set Referer

ApsaraVideo Player SDK for HarmonyOS NEXT supports setting a Referer. In conjunction with the Referer-based allowlist and blocklist configured in the console, you can control access to your videos. Use the PlayerConfig object to set the request Referer. Sample code:

let config:PlayerConfig | undefined = player.getConfig();
if (config) {
  // Set the Referer, for example, http://example.aliyundoc.com. Note: When you set a Referer, you must include the protocol.
  config.mReferrer = referer; 
  player.setConfig(config);
}

Set User-Agent

ApsaraVideo Player SDK for HarmonyOS NEXT provides PlayerConfig to set the request User-Agent (UA). After it is set, the player includes the UA information in requests. Sample code:

let config:PlayerConfig | undefined = player.getConfig();
if (config) {
  // Set the UA.
  config.mUserAgent = userAgent; 
  player.setConfig(config);
}

Network timeout and retries

You can configure the network timeout and retry count for ApsaraVideo Player SDK for HarmonyOS NEXT by using the PlayerConfig object. Sample code:

let config:PlayerConfig | undefined = player.getConfig();
if (config) {
  // Set the network timeout in milliseconds.
  config.mNetworkTimeout = 5000;
  // Set the number of retries after a timeout. The interval for each retry is networkTimeout. If networkRetryCount is set to 0, no retries are attempted, and the retry policy is determined by the app. The default value is 2.
  config.mNetworkRetryCount=2;
  player.setConfig(config);
}
Note
  • If a network issue causes the player to buffer, it retries up to NetworkRetryCount times. The interval between retries is mNetworkTimeout.

  • If the player remains in the loading state after multiple retries, the onError event is triggered. In this case, ErrorInfo.getCode() returns ErrorCode.ERROR_LOADING_TIMEOUT.

  • If NetworkRetryCount is set to 0, the player triggers the onInfo event when a network retry times out. The InfoBean.getCode() of the event returns InfoCode.NetworkRetry. In this case, you can call the player's reload method to reload the network or perform other actions.

Buffer and latency control

ApsaraVideo Player SDK for HarmonyOS NEXT provides methods in PlayerConfig to control buffering and latency. Sample code:

Sample code

let config:PlayerConfig | undefined = player.getConfig();
if (config) {
  // The maximum latency. Note: This parameter is effective only for live streaming. If the latency is high, the player SDK internally adjusts the playback speed to keep the latency within this range.
  config.mMaxDelayTime = 5000;
  // The maximum buffer duration in milliseconds. The player loads a buffer of up to this duration at a time.
  config.mMaxBufferDuration = 50000;
  // The high buffer threshold in milliseconds. When data is being loaded due to poor network conditions, the loading state ends after the buffered data reaches this duration.
  config.mHighBufferDuration = 3000;
  // The buffer duration for playback startup in milliseconds. A smaller value results in a faster startup, but may cause the player to enter a loading state soon after playback begins.
  config.mStartBufferDuration = 500;
  ....// Other settings
  // The maximum backward buffer duration in milliseconds. The default value is 0.
  config.mMaxBackwardBufferDurationMs = 0;
  player.setConfig(config);
}
Important
  • The three buffer duration values must satisfy the following condition: mStartBufferDuration ≤ mHighBufferDuration ≤ mMaxBufferDuration.

  • The system enforces a maximum buffer limit of 5 minutes to prevent memory issues.

HTTP headers

By using the PlayerConfig object, you can add custom HTTP header parameters to the player's requests. Sample code:

let config:PlayerConfig | undefined = player.getConfig();
if (config) {
  // Define headers.
  let headers: string[] = [];
  headers.push("Host:example.com"); // For example, set the Host in the header.
  // Set headers.
  config.setCustomHeaders(headers);
  player.setConfig(config);
}

Video background color

ApsaraVideo Player SDK for HarmonyOS NEXT supports setting the background color for video rendering. The API and usage are described below.

API example

/**
 * Sets the background color of the video.
 *
 * @param color  ARGB
 *
 */
setVideoBackgroundColor: (color: number) => void;

Usage

// The parameter is an 8-digit hexadecimal value. The 8 digits are in pairs, representing A (alpha), R (red), G (green), and B (blue) in order.
// For example, 0x0000ff00 represents green.
player.setVideoBackgroundColor(0x0000ff00);

Set playback domain for VidAuth

With VidAuth-based playback, you can specify fields such as the domain name corresponding to a vid. For more information about the supported fields, see GetPlayInfo request parameters. The API and usage are described below.

API example

/**
 * Sets playback parameters.
 *
 * @param playConfig The playback parameters.
 */
setPlayerConfig: (playerConfig: VidPlayerConfigGen) => void

Usage

Use the addPlayerConfig method of the VidPlayerConfigGen interface to add the playDomain field.

const vidAuthSource: VidAuth = new VidAuth();
let configGen: VidPlayerConfigGen = new VidPlayerConfigGen();
// Add the playDomain field. For more information about the fields that can be added, see
// https://www.alibabacloud.com/help/en/apsaravideo-for-vod/latest/api-vod-2017-03-21-getplayinfo
configGen.addPlayerConfigString("playDomain", "com.xxx.xxx");
vidAuthSource.setPlayerConfig(configGen);

player.setVidAuthDataSource(vidAuthSource);

Automatic source refresh

Automatic playback source refresh prevents interruptions caused by expired sources in authentication-based scenarios. When a source expires, the player triggers a listener to obtain a new URL, ensuring continuous playback.

Prerequisites

  1. The Player SDK or All-in-One SDK is v7.9.0 or later.

  2. You are using VidAuth-based playback or have configured URL authentication for your service.

VidAuth source

API example

/**
     * Sets the listener for VidAuth source expiration events.
     *
     * This feature enables automated VidAuth source refresh to avoid playback interruptions
     * caused by expiration. When the listener is triggered, you can refresh the VidAuth source
     * and return the updated VidAuth using {@link SourceRefreshCallback#onSuccess}.
     *
     * @param listener The interface for listening to VidAuth source expiration events. See {@link OnVidAuthExpiredListener}.
     */
setOnVidAuthExpiredListener(listener: OnVidAuthExpiredListener): void;

Components

Feature components

export interface OnVidAuthExpiredListener {
    /**
     * This callback is triggered when the player detects that the VidAuth source has expired. A VidAuth source can expire if its PlayAuth or playback URL expires.
     *
     * You can refresh the VidAuth source in this callback and return the new VidAuth source
     * by using {@link SourceRefreshCallback#onSuccess}.
     *
     * @param expiredSource The expired VidAuth source object. See {@link VidAuth}.
     * @param callback The callback interface for providing the new VidAuth source to the player. See {@link SourceRefreshCallback}.
     */
    onVidAuthExpired(expiredSource: VidAuth, callback: SourceRefreshCallback<VidAuth> | null): void;
}

/**
* A callback interface for handling playback source refresh results.
*
* This interface is applicable to playback source types that require dynamic updates,
* such as a URL source or VidAuth source. When the player triggers a refresh request,
* you can return the refresh result through this interface by calling either the `onSuccess` or `onError` method.
*/
export interface SourceRefreshCallback<T> {
/**
* Called by the player when the refresh operation succeeds.
*
* @param newSource The new playback source object that contains the updated information. See {@link SourceBase}.
*
* This method indicates that the refresh operation was successfully completed. You must provide
* the new playback source within this method so that the player can load the latest resource.
*/
onSuccess(newSource: T): void;

/**
* Called by the player when the refresh operation fails.
*
* @param errorMsg A string that describes the reason for the failure.
*
* This method indicates that the refresh operation has failed. You can use the `errorMsg`
* to capture details about the failure and proceed with subsequent handling.
*/
onError(errorMsg: string): void;
}

Usage

You can obtain a playback credential by calling the GetVideoPlayAuth operation. We recommend integrating the ApsaraVideo VOD server-side SDK to obtain the credential, which simplifies the signing process. For more information, see OpenAPI Explorer.

private mOnVidAuthExpiredListener: OnVidAuthExpiredListener = ({
   onVidAuthExpired(vidAuth: VidAuth, callback: SourceRefreshCallback<VidAuth> | null) {
     let vid: String = vidAuth.getVid()

     // ------------------- Start of user implementation -------------------
     // Call your own function to get the new PlayAuth from your app server.
     // This is an example. You must implement it according to your business logic.
     XHR.fetch(``)
       .then((data) => {
         try {
           console.log("Refresh - VidAuth", data.toString());
           const response: IAuthResponse = JSON.parse(JSON.parse(data));

           if (response && response.data && response.data.playAuth) {
             // 1. Update the old vidAuth object with the new PlayAuth.
             vidAuth.setPlayAuth(response.data.playAuth);

             // 2. Pass the updated object back to the player by using the SDK's callback.
             callback?.onSuccess(vidAuth);
           } else {
             // Pass the error message back to the player by using the SDK's callback.
             callback?.onError('REFRESH_ERROR, invalid response data');
           }
         } catch (parseError) {
           console.error("Parse or callback error:", parseError);
         }
       })
       .catch((e: Error) => {
         console.error("Network error:", e);
         // Pass the error message back to the player by using the SDK's callback.
         callback?.onError('REFRESH_ERROR, network fail');
       })
   }
 })

UrlSource

API example

/**
 * Sets the listener for URL source expiration events.
 *
 * This feature enables URL refresh to avoid playback interruptions caused by
 * URL expiration due to authentication. When the listener is triggered,
 * you can refresh the URL source and return the updated URL source by using {@link SourceRefreshCallback#onSuccess}.
 *
 * @param listener Listener for handling URL source expiration events. See {@link OnURLSourceExpiredListener}.
 *
 * <p>For more information about how to configure URL authentication, see
 * <a href="https://www.alibabacloud.com/help/en/apsaravideo-for-vod/latest/url-signing">URL authentication</a>.</p>
 */
setOnURLSourceExpiredListener(listener: OnURLSourceExpiredListener): void;

Components

Feature components

/**
 * A callback interface for handling playback source refresh results.
 *
 * This interface is applicable to playback source types that require dynamic updates,
 * such as a URL source or VidAuth source. When the player triggers a refresh request,
 * you can return the refresh result through this interface by calling either the `onSuccess` or `onError` method.
 */
export interface SourceRefreshCallback<T> {
    /**
     * Called by the player when the refresh operation succeeds.
     *
     * @param newSource The new playback source object that contains the updated information. See {@link SourceBase}.
     *
     * This method indicates that the refresh operation was successfully completed. You must provide
     * the new playback source within this method so that the player can load the latest resource.
     */
    onSuccess(newSource: T): void;
    /**
     * Called by the player when the refresh operation fails.
     *
     * @param errorMsg A string that describes the reason for the failure.
     *
     * This method indicates that the refresh operation has failed. You can use the `errorMsg`
     * to capture details about the failure and proceed with subsequent handling.
     */
    onError(errorMsg: string): void;
}
/**
 * Sets the listener for URL source expiration events.
 *
 * This feature enables URL refresh to avoid playback interruptions caused by
 * URL expiration due to authentication. When the listener is triggered,
 * you can refresh the URL source and return the updated URL source by using {@link SourceRefreshCallback#onSuccess}.
 *
 * @param listener Listener for handling URL source expiration events. See {@link OnURLSourceExpiredListener}.
 *
 * <p>For more information about how to configure URL authentication, see
 * <a href="https://www.alibabacloud.com/help/en/apsaravideo-for-vod/latest/url-signing">URL authentication</a>.</p>
 */
export interface OnURLSourceExpiredListener {
    /**
     * This callback is triggered when the player detects that the URL source (UrlSource) has expired.
     *
     * You can refresh the URL source in this callback and return the new UrlSource
     * by using {@link SourceRefreshCallback#onSuccess}.
     *
     * @param expiredSource The expired UrlSource object. See {@link UrlSource}.
     * @param callback The refresh callback used to return the updated UrlSource to the player. See {@link SourceRefreshCallback}.
     */
    onUrlSourceExpired(expiredSource: UrlSource, callback: SourceRefreshCallback<UrlSource> | null): void;
}

/**
* A callback interface for handling playback source refresh results.
*
* This interface is applicable to playback source types that require dynamic updates,
* such as a URL source or VidAuth source. When the player triggers a refresh request,
* you can return the refresh result through this interface by calling either the `onSuccess` or `onError` method.
*/
export interface SourceRefreshCallback<T> {
/**
* Called by the player when the refresh operation succeeds.
*
* @param newSource The new playback source object that contains the updated information. See {@link SourceBase}.
*
* This method indicates that the refresh operation was successfully completed. You must provide
* the new playback source within this method so that the player can load the latest resource.
*/
onSuccess(newSource: T): void;

/**
* Called by the player when the refresh operation fails.
*
* @param errorMsg A string that describes the reason for the failure.
*
* This method indicates that the refresh operation has failed. You can use the `errorMsg`
* to capture details about the failure and proceed with subsequent handling.
*/
onError(errorMsg: string): void;
}

Usage

private mOnURLSourceExpiredListener: OnURLSourceExpiredListener = ({
  onUrlSourceExpired(urlSource: UrlSource, callback: SourceRefreshCallback<UrlSource> | null) {
    // 1. Extract the original URL from the expired URL (using authentication method A as an example).
    let playURL: String = urlSource.getUri();

    let urlAuthKeyIndex = playURL.indexOf('?auth_key=');
    if (urlAuthKeyIndex == -1) {
      urlAuthKeyIndex = playURL.indexOf("&auth_key=");
    }

    if (urlAuthKeyIndex === -1) {
      callback?.onError('PARSE_ERROR, Cannot find auth_key in URL');
      return;
    }

    // Restore the original resource address by removing the URL parameter part, for example, "?auth_key=".
    // This ensures safe handling even if auth_key is not found.
    const originalUrl = playURL.substring(0, urlAuthKeyIndex);

    // 2. Generate a new authentication URL.
    let key = '';
    if (mAuthKey != null) {
      key = mAuthKey
    }

    // Calculate the timeout for the playback URL (validity period).
    const newExpireTime = Math.floor(Date.now() / 1000) + parseInt(mValidTime); // Current time + 1 hour

    // Use the utility class to generate a new authentication URL.
    const newAuthUrl = CdnAuthUtil.aAuth(originalUrl, key, newExpireTime);

    // 3. Check the generated authentication URL and return the result through the callback.
    if (newAuthUrl) {
      let urlSource: UrlSource = new UrlSource();
      urlSource.setUri(newAuthUrl);
      callback?.onSuccess(urlSource);
    } else {
      callback?.onError('REFRESH_ERROR, refresh fail');
    }
  }
})

Utility functions

Additional utility functions

class CdnAuthUtil {
  /**
   * Authentication method A
   */
  static aAuth(uri: string, key: string, exp: number): string | null {
    const match = uri.match(URI_PATTERN);
    if (!match) {
      return null;
    }

    const scheme = match[1] ? `${match[1]}://` : 'http://';
    const host = match[2];
    const path = match[3] || '/';
    const args = match[4] || '';

    const rand = '0';
    const uid = '0';
    const sstring = `${path}-${exp}-${rand}-${uid}-${key}`;
    md5sum(sstring).then(res => {
      authKey = `${exp}-${rand}-${uid}-${res}`;
    })

    const separator = args ? '&' : '?';
    return `${scheme}${host}${path}${args}${separator}auth_key=${authKey}`;
  }

  /**
   * Authentication method B
   */
  static bAuth(uri: string, key: string, exp: number): string | null {
    const match = uri.match(URI_PATTERN);
    if (!match) {
      return null;
    }

    const scheme = match[1] ? `${match[1]}://` : 'http://';
    const host = match[2];
    const path = match[3] || '/';
    const args = match[4] || '';

    // Convert the timestamp to UTC time and format it as yyyyMMddHHmm.
    const date = new Date(exp * 1000);
    const utcStr = date.toUTCString(); // Use toUTCString and parse or format manually.
    const formatter = new Intl.DateTimeFormat('zh-CN', {
      timeZone: 'UTC',
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: false
    });
    const parts = formatter.formatToParts(date);
    const getPart = (type: string) => parts.find(p => p.type === type)?.value || '';
    const nexp = `${getPart('year')}${getPart('month')}${getPart('day')}${getPart('hour')}${getPart('minute')}`;

    const sstring = key + nexp + path;
    const hashvalue = md5sum(sstring);

    return `${scheme}${host}/${nexp}/${hashvalue}${path}${args}`;
  }

  /**
   * Authentication method C
   */
  static cAuth(uri: string, key: string, exp: number): string | null {
    const match = uri.match(URI_PATTERN);
    if (!match) {
      return null;
    }

    const scheme = match[1] ? `${match[1]}://` : 'http://';
    const host = match[2];
    const path = match[3] || '/';
    const args = match[4] || '';

    const hexexp = exp.toString(16); // Convert decimal to hexadecimal.
    const sstring = key + path + hexexp;
    const hashvalue = md5sum(sstring);

    return `${scheme}${host}/${hashvalue}/${hexexp}${path}${args}`;
  }
}

export default CdnAuthUtil;

Performance

Set player scene

Setting a player scene automatically applies optimal parameters for the selected scenario, such as buffer settings and feature toggles. This feature is compatible with custom parameters set via thesetConfig interface. Custom settings take precedence.

Note
  • After you set a player scene, you can call thegetConfig method to view the parameter configuration.

API example

/**
* Sets a player scene.
* @param scene The specified player scene.
*/
setPlayerScene: (scene: PlayerScene) => void;

Player scenes

export enum PlayerScene {
  /**
   * No scene
   */
  NONE,
  /**
   * Long video scene: Suitable for videos longer than 30 minutes.
   */
  LONG,
  /**
   * Medium video scene: Suitable for videos between 5 and 30 minutes.
   */
  MEDIUM,
  /**
   * Short video scene: Suitable for videos up to 5 minutes.
   */
  SHORT,
  /**
   * Live streaming scene
   */
  LIVE,
  /**
   * Real-Time Streaming (RTS) live scene
   */
  RTS_LIVE
}

Usage

// Set the short video scene.
aliyunVodPlayer.setPlayerScene(PlayerScene.SHORT)

// Set the medium video scene.
aliyunVodPlayer.setPlayerScene(PlayerScene.MEDIUM)

// Set the long video scene.
aliyunVodPlayer.setPlayerScene(PlayerScene.LONG)

// Set the live streaming scene.
aliyunVodPlayer.setPlayerScene(PlayerScene.LIVE)

Local cache

ApsaraVideo Player SDK for HarmonyOS NEXT provides a local cache feature. When playing a video multiple times, this feature improves startup speed and seek speed, reduces stuttering, and saves network traffic.

Enable local caching

The local cache feature is disabled by default. To use it, you must enable it manually by usingenableLocalCache inAliPlayerGlobalSettings. The following is a code sample:

Sample code

/**
   * Enables the local cache. If enabled, content is cached to local files.
   * @param enable true: enables local caching. false: disables local caching. This feature is disabled by default.
   * @param maxBufferMemoryKB The maximum memory size for a single source, in KB.
   * @param localCacheDir The absolute path of the directory for local cache files.
   */
  static enableLocalCache(enable: boolean, maxBufferMemoryKB: number, localCacheDir: string)

    /**
   *  Configures the automatic cleanup of local cache files.
   * @param expireMin The expiration time of the cache in minutes. Default value: 30 days. Expired cache items are always removed during cleanup, regardless of their size.
   * @param maxCapacityMB The maximum cache capacity in MB. Default value: 20 GB. During cleanup, if the total cache size exceeds this limit, items are deleted one by one based on their last access time (oldest first) until the total size is within the limit.
   * @param freeStorageMB The minimum free disk space in MB. Default value: 0. During cleanup, if the available disk space is less than this value, cache items are deleted one by one based on their last access time until the free space meets the requirement or all cache items are removed.
   */
  static setCacheFileClearConfig(expireMin: number, maxCapacityMB: number, freeStorageMB: number)

  /**
   * Sets the callback for generating a URL hash. If not set, the SDK uses the MD5 algorithm.
   */
  setCacheUrlHashCallback(cb: OnGetUrlHashCallback)
Note
  • If a video playback URL contains authentication parameters, these parameters can change, which reduces the local cache hit rate. To improve the cache hit rate for the same URL with different authentication parameters, you can remove the parameters from the URL before calculating its hash value (such as MD5) by using the setCacheUrlHashCallback interface. For example, if a video playback URL with authentication parameters is http://****.mp4?aaa, you can use http://****.mp4 to calculate the hash value when the video is loaded. However, for an encrypted M3U8 video, this approach can cause playback to fail. If you remove the authentication parameters from its keyURL before calculating the hash, different videos may be cached with the same key. Solution: In the setCacheUrlHashCallback callback, you can check the domain name. Remove the authentication parameters only from the playback domain URL (such as http(s)://xxxxx.m3u8?aaaa), but do not remove them from the URL of the domain that corresponds to the keyURL (such as http(s)://yyyyy?bbbb).

    # playURL (Playback domain)
    curl "https://xxx/xxx-hd-encrypt-stream.m3u8?MtsHlsUriToken=xxx&auth_key=xxx"
    
    # Response content (m3u8 playlist)
    #EXTM3U
    #EXT-X-VERSION:3
    #EXT-X-ALLOW-CACHE:YES
    #EXT-X-TARGETDURATION:10
    #EXT-X-MEDIA-SEQUENCE:0
    # keyURL (Key domain. Do not remove authentication parameters.)
    #EXT-X-KEY:METHOD=AES-128,URI="https://xxx/decrypt?Ciphertext=xxx&MtsHlsUriToken=xxx"
    #EXTINF:10.000000,
    xxx-hd-encrypt-stream-00001.ts?auth_key=xxx
    #EXTINF:10.000000,
    xxx-hd-encrypt-stream-00002.ts?auth_key=xxx
    ...
  • If a server supports both HTTP and HTTPS for the same media file, you can improve the cache hit rate by normalizing the URL before calculating the hash. Examples:

    • If the playback URLs arehttps://****.mp4 andhttp://****.mp4, use****.mp4 to calculate the hash.

    • If the playback URL ishttps://****.mp4, consistently convert it tohttp://****.mp4 before calculating the hash.

  • If a playback URL for an HLS stream contains authentication parameters, you can set thePlayerConfig.mEnableStrictAuthMode field to choose an authentication mode. The default value is false for versions earlier than 7.13.0 and true for versions 7.13.0 and later.

    • Non-strict authentication (false): Authentication information is cached along with media data. If a video is only partially cached, the player uses the cached authentication to request subsequent segments. If the URL authentication has a short validity period, or if playback is resumed after a long pause, the authentication may expire. To ensure uninterrupted playback if authentication expires, you must integrate the automatic source refresh feature.

    • Strict authentication (true): Authentication information is not cached. The player authenticates every time playback starts. This can cause playback to fail without a network connection.

Enable or disable local caching for a single URL

You can enable or disable local caching for a specific URL by setting the appropriate property in thePlayerConfig object.

let config:PlayerConfig | undefined = player.getConfig();
if (config) {
  // Specifies whether to enable local caching for the playback URL. Default value: true.
  // For the local cache to be effective for this URL, global caching in AliPlayerGlobalSettings must also be enabled, and this value must be true.
  // If set to false, local caching is disabled for this specific URL.
  config.mEnableLocalCache = true; 
  player.setConfig(config);
}

Preload

ApsaraVideo Player SDK for HarmonyOS NEXT provides a preload feature, which is an enhancement of the local cache. It improves video startup speed by caching a specified duration of content before playback begins.

Important

This feature requires a Professional Edition license. For more information, see Obtain Player SDK License.

The preload feature has the following limits:

  • It supports only single media files, such as MP4, MP3, FLV, and HLS.

Note

By default, the SDK automatically schedules network resources during preloading to minimize impact on the currently playing video. This strategy allows preload requests only after the current video's buffer reaches a certain threshold.

AliPlayerGlobalSettings.enableNetworkBalance(false);
  1. Enable the local cache feature. For details, see Local Cache.

  2. Call the pre-initialization method.

    privateService.preInitService(getContext());
  3. Set the data source.

    VidAuth (recommended)

    let vidAuth: VidAuth = new VidAuth();
    vidAuth.setVid("Your_Vid");// Required. The Video ID.
    vidAuth.setPlayAuth("<yourPlayAuth>");// Required. The playback credential. Generate it by calling the GetVideoPlayAuth operation of the VOD service.
    vidAuth.setRegion("Your_Region");// Optional. Default value: cn-shanghai.
    vidAuth.setQuality("Selected_Quality");// "AUTO" represents auto bitrate.

    VidSts

    let vidSts: VidSts = new VidSts();
    vidSts.setVid("Your_Vid");// Required. The Video ID.
    vidSts.setAccessKeyId("<yourAccessKeyId>");// Required. The Access Key ID of the temporary STS token pair. Generate it by calling the AssumeRole operation of STS.
    vidSts.setAccessKeySecret("<yourAccessKeySecret>");// Required. The Access Key Secret of the temporary STS token pair. Generate it by calling the AssumeRole operation of STS.
    vidSts.setSecurityToken("<yourSecurityToken>");// Required. The Security Token of the temporary STS token pair. Generate it by calling the AssumeRole operation of STS.
    vidSts.setRegion("Your_Region"); // Optional. Default value: cn-shanghai.
    vidSts.setQuality("Selected_Quality");// "AUTO" represents auto bitrate.

    UrlSource

    // Create a data source object and set the playback URL.
    let urlSource: UrlSource = new UrlSource();
    // Required parameter.
    urlSource.setUri("Your_Playback_URL");
  4. Set the task parameters.

    Note

    This applies only to multi-bitrate video. You only need to choose one ofsetDefaultBandWidth,setDefaultResolution, orsetDefaultQuality.

    let mPreloadConfig: PreloadConfig = new PreloadConfig();
    // Set the preload bitrate for multi-bitrate streams.
    preloadConfig.setDefaultBandWidth(400000);
    // Set the preload resolution for multi-bitrate streams.
    preloadConfig.setDefaultResolution(640 * 480);
    // Set the preload quality for multi-bitrate streams.
    preloadConfig.setDefaultQuality(“FD“);
    // Set the preload duration.
    preloadConfig.setDuration(1000);
  5. Add a task listener.

    private PreloadListenerImpl: OnPreloadListener = {
      onError: (taskId: string, urlOrVid: string, errorInfo: ErrorInfo): void => {
        console.error("OnPreloadListener -> " + " taskId: " + taskId + " ErrorMsg: " + errorInfo.getMsg())
      },
      onCompleted: (taskId: string, urlOrVid: string): void => {
        console.info("OnPreloadListener -> " + "onCompleted" + " taskId: " + taskId);
      },
      onCanceled: (taskId: string, urlOrVid: string): void => {
        console.info("OnPreloadListener -> " + "onCanceled" + " taskId: " + taskId)
      }
    }
  6. Build the task, add it to theMediaLoaderV2 instance, and start preloading.

    VidAuth (recommended)

    // Build the preload task.
    let mPreloadTask: PreloadTask = new PreloadTask(vidAuth, mPreloadConfig);
    // Get the MediaLoaderV2 instance.
    let mediaLoaderV2: MediaLoaderV2 = MediaLoaderV2.getInstance();
    // Add the task and start preloading.
    let taskId: String = mediaLoaderV2.addTask(mPreloadTask, PreloadListenerImpl)

    VidSts

    // Build the preload task.
    let mPreloadTask: PreloadTask = new PreloadTask(vidSts, mPreloadConfig);
    // Get the MediaLoaderV2 instance.
    let mediaLoaderV2: MediaLoaderV2 = MediaLoaderV2.getInstance();
    // Add the task and start preloading.
    let taskId: String = mediaLoaderV2.addTask(mPreloadTask, PreloadListenerImpl)

    UrlSource

    // Build the preload task.
    let mPreloadTask: PreloadTask = new PreloadTask(urlSource, mPreloadConfig);
    // Get the MediaLoaderV2 instance.
    let mediaLoaderV2: MediaLoaderV2 = MediaLoaderV2.getInstance();
    // Add the task and start preloading.
    let taskId: String = mediaLoaderV2.addTask(mPreloadTask, PreloadListenerImpl)
  7. Optional: Manage tasks.

    mediaLoaderV2.cancelTask(taskId);// Cancels the preload task with the specified task ID.
    mediaLoaderV2.pauseTask(taskId);// Pauses the preload task with the specified task ID.
    mediaLoaderV2.resumeTask(taskId);// Resumes the preload task with the specified task ID.
  8. Delete the loaded files.

    To save space, you can delete preloaded files. The SDK does not provide a deletion API; you must delete the files from the loading directory in your app.

Get the download speed

You can get the download speed of the currently playing video from the onInfo callback using thegetExtraValue method. The following is a code sample:

private mOnVideoInfo: OnInfoListener = {
    // Information from the player, such as the current progress and buffer position.
    onInfo: (bean: InfoBean) => {
      if (bean.getCode() === InfoCode.CurrentDownloadSpeed) {
        /// Current download speed
        let extraValue: number = bean.getExtraValue();
      } 
    }
  }

Network features

HTTPDNS

HTTPDNS sends DNS resolution requests to a dedicated HTTPDNS server for faster, more stable results and to reduce the risk of DNS hijacking.

Alibaba Cloud Player SDK offers an enhanced HTTPDNS feature, designed specifically for Alibaba Cloud CDN domain names. It supports precise scheduling on the Alibaba Cloud CDN network and real-time resolution updates, effectively improving network performance.

Note

The enhanced HTTPDNS feature is supported in Alibaba Cloud Player SDK for HarmonyOS NEXT v6.21.0 and later. To enable this feature, you must first submit a ticket or contact your Alibaba Cloud account manager.

Enhanced HTTPDNS example

The HTTPDNS feature serves only Alibaba Cloud CDN domain names. Ensure that the accelerated domain name is configured for Alibaba Cloud CDN and is running properly. To add and configure an accelerated domain name in ApsaraVideo for VOD, see Add an accelerated domain name. For more information about CDN domain names, see Alibaba Cloud CDN.

// Enable enhanced HTTPDNS.
AliPlayerGlobalSettings.enableEnhancedHttpDns(true);

// Optional: Add a domain name for HTTPDNS pre-resolution.
DomainProcessor.addPreResolveDomain("player.***alicdn.com");

HTTP/2

Alibaba Cloud Player SDK for HarmonyOS NEXT supports HTTP/2. This protocol improves playback performance by using multiplexing to prevent head-of-line (HOL) blocking. Sample code:

AliPlayerGlobalSettings.setUseHttp2(true);

Video download

The ApsaraVideo Player SDK for HarmonyOS NEXT lets you download videos from ApsaraVideo VOD and cache them for offline playback. It offers two download methods: normal download and secure download.

  • Normal download

    Alibaba Cloud does not encrypt videos downloaded in this mode, so they can be played by third-party players.

  • Secure download

    Alibaba Cloud encrypts videos downloaded in this mode. Only ApsaraVideo Player can play these videos; third-party players cannot.

Usage notes

  • The video download feature is supported only for VidSts and VidAuth sources.

  • To use the video download feature, you must enable and configure the download mode in the ApsaraVideo VOD console. For more information, see offline download.

  • Resumable downloads are supported.

Procedure

  1. Optional: Configure the key file. This step is required only for secure download.

    Note

    Ensure the configured key file matches your app information to prevent download failures.

    For secure downloads, you must configure the player SDK with the key file generated in the ApsaraVideo VOD console. This file is required for decryption and verification during video download and playback. To generate the key file, see Enable secure download.

    After generating the key file, place it in the rawfile directory of your project (create the directory if it does not exist). The directory structure is as follows:

    src/main/resources/
    └── rawfile/
        └── encrypt/
            └── encryptedApp.dat

    After placing the file, configure it using the following sample code:

    try {
      getContext().resourceManager.getRawFileContent('encrypt/encryptedApp.dat', (error, value) => {
        if (error != null) {
          console.log('downloader init error is ' + error);
        } else {
          let rawFile = value;
          let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM : true });
          let rawFileString = textDecoder.decodeToString( rawFile , {stream: false});
          console.log(`downloader get encryptedApp.dat value: ${rawFileString}`);
          PrivateService.initServiceWithBytes(getContext(), rawFileString);
        }
      })
    } catch (error) {
      let code = (error as BusinessError).code;
      let message = (error as BusinessError).message;
      console.error(`callback getRawFileContent failed, error code: ${code}, message: ${message}.`);
    }
  2. Create and set up the downloader.

    Create a downloader using AliDownloaderFactory. Sample code:

    ......
    // Create the downloader.
    let mAliDownloader:AliMediaDownloader = AliDownloaderFactory.create(getApplicationContext());
    // Configure the path to save downloaded files.
    mAliDownloader.setSaveDir(getContext().cacheDir);
  3. Set listeners.

    You can set multiple listeners for the downloader. Sample code:

    Sample code

    // Callback for successful download preparation. After the callback is invoked, use the {@linkplain #selectItem(int)} method to select the track to download.
    export interface OnPreparedListener {
      onPrepared: (mediaInfo: MediaInfo) => void;
    }
    
    // Progress callback.
    export interface OnProgressListener {
       // The download progress percentage.
      onDownloadingProgress: (percent: number) => void;
      // The processing progress percentage.
      onProcessingProgress: (percent: number) => void;
    }
    
    // Completion callback.
    export interface OnCompletionListener {
      onCompletion: () => void;
    }
    
    // Error callback.
    export interface OnErrorListener {
      // The download error message.
      onError: (errorInfo: ErrorInfo) => void;
    }
  4. Prepare the download source.

    Use the prepare method to prepare the download source. VidSts and VidAuth sources are supported. Sample code:

    • VidSts

      // Create a VidSts source.
      let aliyunVidSts : VidSts = new VidSts();
      aliyunVidSts.setVid("Your Video ID");// The Video ID.
      aliyunVidSts.setAccessKeyId("<yourAccessKeyId>");// The AccessKey ID of the temporary STS token, obtained by calling the STS AssumeRole operation.
      aliyunVidSts.setAccessKeySecret"<yourAccessKeySecret>");// The AccessKey Secret of the temporary STS token, obtained by calling the STS AssumeRole operation.
      aliyunVidSts.setSecurityToken("<yourSecurityToken>");// The security token, obtained by calling the STS AssumeRole operation.
      aliyunVidSts.setRegion("Your region");// The region where ApsaraVideo VOD is enabled. Default: cn-shanghai.
      
      // If you enabled HLS standard encryption parameter passthrough in the ApsaraVideo VOD console
      // and the default parameter name is MtsHlsUriToken, you need to set the config
      // and pass it to the VidSts object as shown in the following code.
      // If you have not enabled HLS standard encryption parameter passthrough, you can skip the following code.
      let config:VidPlayerConfigGen = new VidPlayerConfigGen();
      config.setMtsHlsUriToken("<yourMtsHlsUriToken>");
      aliyunVidSts.setPlayerConfig(config);
          
      
      // Prepare the download source.
      mAliDownloader.prepare(aliyunVidSts)
    • VidAuth

      // Create a VidAuth source.
      let vidAuth : VidAuth = new VidAuth();
      vidAuth.setVid("Your Video ID");// The Video ID.
      vidAuth.setPlayAuth("<yourPlayAuth>");// The playback credential, obtained by calling the ApsaraVideo VOD GetVideoPlayAuth operation.
      vidAuth.setRegion("Your region");// Deprecated. The region is parsed automatically.
       // If you enabled HLS standard encryption parameter passthrough in the ApsaraVideo VOD console
       // and the default parameter name is MtsHlsUriToken, you need to set the config
       // and pass it to the VidAuth object as shown in the following code.
       // If you have not enabled HLS standard encryption parameter passthrough, you can skip the following code.
      let config:VidPlayerConfigGen = new VidPlayerConfigGen();
      config.setMtsHlsUriToken("<yourMtsHlsUriToken>");
      vidAuth.setPlayerConfig(config);
      // Prepare the download source.
      mAliDownloader.prepare(vidAuth);
    Note
    • The format of the downloaded file is the same as that of the source file and cannot be changed.

    • If you enable HLS standard encryption parameter passthrough in the ApsaraVideo VOD console, the default parameter name is MtsHlsUriToken. For more information, see HLS standard encryption parameter passthrough. In this case, you must set the MtsHlsUriToken value in the source object as shown in the preceding code.

  5. Select a track and start the download.

    When preparation is complete, the OnPreparedListener callback is triggered. The returned TrackInfo contains information about each video stream, such as its definition. Select a track to download. Sample code:

    mAliDownloader.setOnPreparedListener({
      onPrepared: (mediaInfo: MediaInfo) => {
        // The download source is successfully prepared.
        let trackInfos : TrackInfo[] = mediaInfo.getTrackInfos();
        // For example, download the first track.
        mAliDownloader.selectItem(trackInfos[0].getIndex());
        // Start the download.
        mAliDownloader.start();
      }
    });
  6. (Optional) Update the download source.

    To prevent VidSts and VidAuth from expiring, update the download source information before starting the download. For example:

    // Update the download source.
    mAliDownloader.updateVidStsSource(VidSts);
    // Start the download.
    mAliDownloader.start();
  7. Release the downloader after the download completes or fails.

    When the download finishes, call the release method within the onCompletion or onError callback.

    mAliDownloader.stop();
    mAliDownloader.release();
  8. Optional: Delete the downloaded files.

    You can delete downloaded files during or after the download. Sample code:

    // Delete the file using the object.
    mAliDownloader.deleteFile();
    // Delete the file using the static method. If the deletion succeeds, 0 is returned.
    AliDownloaderFactory.deleteFile("Path to the download folder to be deleted","Video ID","Video format","Index of the downloaded video");

Next steps

To play the downloaded videos with ApsaraVideo Player, follow these steps:

  1. After the download is complete, obtain the absolute path of the video file.

    let path: string = mAliDownloader.getFilePath();
  2. Set the absolute path using a UrlSource to play the video.

    let urlSource: UrlSource = new UrlSource();
    urlSource.setUri(path);// Set the absolute path of the downloaded video file.
    aliPlayer.setUrlDataSource(urlSource);

Encrypted video playback

On-demand videos support HLS encryption and Alibaba Cloud proprietary encryption. For more information, see Play encrypted videos.

Related documents