Advanced features

Updated at:
Copy as MD

Use advanced features of the Android Player SDK, including playlist playback, subtitles, video download, and encrypted playback. API reference.

Important

To run the demo, download it and follow the instructions in Run the demo to compile and run the demo.

Professional Edition license verification

Note

Some player features require a Professional Edition license. Check supported features in Player SDK feature details. To use these features, complete authorization as described in Obtain a player SDK license.

Set a listener before the app starts or before calling any player API:

import com.aliyun.private_service.PrivateService;

PrivateService.setOnPremiumLicenseVerifyCallback(new PrivateService.OnPremiumLicenseVerifyCallback() {
    @Override
    public void onPremiumLicenseVerifyCallback(PrivateService.PremiumBizType type, boolean isValid, String errorMsg) {
        Log.d(TAG, "onPremiumLicenseVerifyCallback: " + type + " isValid: " + isValid + " errorMsg: " + errorMsg);
    }
});

PremiumBizType enumerates professional features. When you use a related feature, the player verifies the license and returns the result through this callback. If isValid is false, errorMsg contains the reason.

Playback

Playlist playback

The Android Player SDK provides playlist playback with preloading to significantly improve startup speed for short videos.

Procedure

  1. Create a player.

    Create an AliListPlayer instance using the AliPlayerFactory class. Example:

    AliListPlayer aliListPlayer;
    .....
    aliListPlayer = AliPlayerFactory.createAliListPlayer(getApplicationContext());
    aliListPlayer.setTraceId("traceId");  // traceId is a unique identifier for the device or user, typically IMEI or IDFA.

  2. Optional: Set listeners.

    Listeners are optional but recommended. Without them, you cannot receive event notifications. Key listeners: OnPreparedListener, OnErrorListener, OnCompletionListener, OnLoadingStatusListener, and OnInfoListener.

    Expand to view code

    aliListPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
        @Override
        public void onCompletion() {
            // Playback completed.
        }
    });
    aliListPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
        @Override
        public void onError(ErrorInfo errorInfo) {
            // Error occurred.
        }
    });
    aliListPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
        @Override
        public void onPrepared() {
            // Preparation succeeded.
        }
    });
    aliListPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(int width, int height) {
            // Video resolution changed.
        }
    });
    aliListPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() {
        @Override
        public void onRenderingStart() {
            // First frame rendered.
        }
    });
    aliListPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
        @Override
        public void onInfo(int type, long extra) {
            // Other information events. Type includes: loop playback started, buffer position, current playback position, autoplay started, etc.
        }
    });
    aliListPlayer.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
        @Override
        public void onLoadingBegin() {
            // Buffering started.
        }
        @Override
        public void onLoadingProgress(int percent, float kbps) {
            // Buffering progress.
        }
        @Override
        public void onLoadingEnd() {
            // Buffering ended.
        }
    });
    aliListPlayer.setOnSeekCompleteListener(new IPlayer.OnSeekCompleteListener() {
        @Override
        public void onSeekComplete() {
            // Seeking completed.
        }
    });
    aliListPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
        @Override
        public void onSubtitleShow(long id, String data) {
            // Show subtitle.
        }
        @Override
        public void onSubtitleHide(long id) {
            // Hide subtitle.
        }
    });
    aliListPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
        @Override
        public void onChangedSuccess(TrackInfo trackInfo) {
            // Audio/video stream or definition switched successfully.
        }
        @Override
        public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
            // Audio/video stream or definition switch failed.
        }
    });
    aliListPlayer.setOnStateChangedListener(new IPlayer.OnStateChangedListener() {
        @Override
        public void onStateChanged(int newState) {
            // Player state changed.
        }
    });
    aliListPlayer.setOnSnapShotListener(new IPlayer.OnSnapShotListener() {
        @Override
        public void onSnapShot(Bitmap bm, int with, int height) {
            // Screenshot taken.
        }
    });
  3. Set the number of preloaded items.

    Set the number of preloaded items to improve startup speed. Example:

    // Set the number of preloaded items. The total number of loaded items is 1 + count × 2.
    aliListPlayer.setPreloadCount(int count);
  4. Add or remove multiple playback sources.

    Playlist playback supports Vid (VidSts and VidPlayAuth) and UrlSource sources. Examples:

    • URL: A third-party or Alibaba Cloud VOD playback address. To obtain an Alibaba Cloud playback address, call GetPlayInfo. Integrate the VOD server SDK to obtain addresses and avoid self-signing. Developer Portal.

    • Vid: The audio and video ID. You can obtain this ID from the console (path: Media Library > Audio/Video) or using the server API (Search media information) after uploading the audio or video.

    // Add a Vid playback source.
    aliListPlayer.addVid(String videoId, String uid);
    // Add a UrlSource playback source.
    aliListPlayer.addUrl(String url, String uid);
    // Remove a source.
    aliListPlayer.removeSource(String uid);
    Note

    The uid uniquely identifies a video. Videos with the same uid are treated as identical. If stream mixing occurs during playback, check whether the same uid is set in different views. The uid can be any string.

  5. Set the display view.

    The player supports SurfaceView and TextureView. Choose one:

    • Set SurfaceView. Example:

      Expand to view code

      SurfaceView surfaceView = findViewById(R.id.surface_view);
      surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
          @Override
          public void surfaceCreated(SurfaceHolder holder) {
              aliListPlayer.setSurface(holder.getSurface());
          }
      
          @Override
          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
              aliListPlayer.surfaceChanged();
          }
      
          @Override
          public void surfaceDestroyed(SurfaceHolder holder) {
              aliListPlayer.setSurface(null);
          }
      });
    • Set TextureView. Example:

      Expand to view code

      TextureView textureView = findViewById(R.id.texture_view);
      textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
          @Override
          public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
              aliListPlayer.setSurface(new Surface(surface));
          }
      
          @Override
          public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
              aliListPlayer.surfaceChanged();
          }
      
          @Override
          public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
              aliListPlayer.setSurface(null);
              return false;
          }
      
          @Override
          public void onSurfaceTextureUpdated(SurfaceTexture surface) {
      
          }
      });
  6. Play a video source.

    After adding one or more playback sources and enabling autoplay, call moveTo to automatically play a specific video source. Example:

    Expand to view code

    // Enable autoplay.
    aliListPlayer.setAutoPlay(true);
    
    // Use this method for URL sources.
    aliPlayer.moveTo(String uid);
    // Use this method for Vid sources. You must pass stsInfo, which includes the STS temporary credentials and temporary AccessKey pair. Obtain these credentials in advance. For more information, see Create a RAM role and perform STS temporary authorization.
    aliPlayer.moveTo(String uid, StsInfo info);
  7. Play the previous or next video.

    • After calling moveTo to play a video source, call moveToPrev and moveToNext to play the previous or next video, using the video source specified by moveTo as the anchor. Example:

      Note

      When switching video sources by calling moveTo, moveToNext, or similar methods based on the same view, flickering or black screens may occur. In this case, when initializing listPlayer, configure the PlayerConfig field mClearFrameWhenStop to false and call setConfig to apply the setting.

      Expand to view code

      // Enable autoplay.
      aliListPlayer.setAutoPlay(true);
      
      // Move to the next video. Note: This method applies only to URL sources and not to Vid playback.
      aliListPlayer.moveToNext();
      // Move to the previous video. Note: This method applies only to URL sources and not to Vid playback.
      aliListPlayer.moveToPrev();
      // Move to the next video. Note: This method applies only to Vid playback.
      aliListPlayer.moveToNext(StsInfo info);
      // Move to the previous video. Note: This method applies only to Vid playback.
      aliListPlayer.moveToPrev(StsInfo info);
Note

For a better playlist playback experience, use the short drama solution. Short drama client development.

Playback of videos with transparency

Feature overview

The ApsaraVideo Player SDK supports alpha channel rendering for transparent gift animations. In live streaming scenarios, these animations play without obscuring the live content.

Limits

Integrated SDK version 6.8.0 or later, or Player SDK version 6.9.0 or later, supports transparent rendering.

Benefits

MP4 videos with transparency offer better animation quality, smaller file sizes, higher compatibility, and improved development efficiency compared to APNG or IXD.

  1. Better animation quality: MP4 retains original details and colors more accurately than APNG or IXD.

  2. Smaller file size: MP4 compresses more efficiently, improving loading speed and reducing bandwidth consumption.

  3. Higher compatibility: MP4 is universally supported across devices and browsers.

  4. Higher development efficiency: Developers do not need to implement complex parsing and rendering logic.

Sample code

Add the following interface: Set the alpha mode (position of the alpha channel in the video asset: top, bottom, left, right). The default value is None.

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

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

/**
 * Set alpha render mode.
 *
 * @param alphaRenderMode The specified alpha render mode. See {@link AlphaRenderMode}.
 */
abstract public void setAlphaRenderMode(AlphaRenderMode alphaRenderMode);
//--------------View usage-------------
// For View, transparency must be set.
//TextureView
TextureView aliplayerView; // View used for playback.
aliplayerView.setOpaque(false);

//SurfaceView
SurfaceView aliplayerView; // View used for playback.
aliplayerView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
aliplayerView.setZOrderOnTop(true); // Place SurfaceView at the top of the display window.

//-----------AliPlayer usage-----------
// Set alpha mode.
aliPlayer.setAlphaRenderMode(IPlayer.AlphaRenderMode.RENDER_MODE_ALPHA_AT_RIGHT);
// Set the asset corresponding to the alpha mode.
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");
aliPlayer.setDataSource(urlSource);
aliPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
    @Override
    public void onCompletion() {
        // Optional: If transition issues occur after single-instance playback completes, clear the screen.
        aliPlayer.clearScreen();
    }
}
aliPlayer.setAutoPlay(true);
aliPlayer.prepare();

External subtitles

Note

For detailed code examples, refer to the API-Example External subtitle demonstration and switching (ExternalSubtitle) module. This Java-based example project for the ApsaraVideo Player SDK for Android helps developers quickly master core SDK integration features.

The Android Player SDK supports adding and switching external subtitles in SRT, SSA, ASS, and VTT formats.

  1. Create a view to display subtitles.

    Create different views based on the subtitle format.

    Expand to view code

    // For displaying SRT and VTT subtitles.
    SubtitleView subtitleView = new SubtitleView(getContext());
    // For player V7.6.0 and later, we recommend using VttSubtitleView to display SRT and VTT subtitles.
    VttSubtitleView vttSubtitleView = new VttSubtitleView(getContext());
    // For displaying ASS and SSA subtitles.
    AssSubtitleView assSubtitleView = new AssSubtitleView(getContext());
    // Add the subtitle view to the layout.
    viewGroup.addView(assSubtitleView);

    When integrating player V7.6.0 or later and using VttSubtitleView to display SRT and VTT subtitles, set the following listener:

    // Required for player 7.6.0 and later.
    mAliPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(int width, int height) {
            int viewWidth = getWidth();
            int viewHeight = getHeight();
            IPlayer.ScaleMode mode = mVideoListPlayer.getScaleMode();
            SubTitleBase.VideoDimensions videoDimensions = SubTitleBase.getVideoDimensionsWhenRenderChanged(width, height, viewWidth, viewHeight, mode);
            vttSubtitleView.setVideoRenderSize(videoDimensions.videoDisplayWidth, videoDimensions.videoDisplayHeight);
        }
    });
  2. Add subtitles.

    Important

    Set subtitle files in the onPrepared callback.

    mAliPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
        @Override
        public void onPrepared() {
            // Set subtitles (must be done in onPrepared).
            mAliPlayer.addExtSubtitle(EXT_SUBTITLE_URL);
        }
    });
  3. Set subtitle-related listeners.

    Expand to view code

    mAliPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
                @Override
                public void onSubtitleExtAdded(int trackIndex, String url) {
                    // trackIndex: subtitle index; true: show the subtitle; false: hide the subtitle.
                    mAliPlayer.selectExtSubtitle(trackIndex, true);
                }
    
                @Override
                public void onSubtitleShow(int trackIndex, long id, String data) {
                    // Subtitle.
                    SubtitleView.Subtitle subtitle = new SubtitleView.Subtitle();
                    subtitle.id = String.valueOf(id);
                    subtitle.content = data;
                    // Show subtitle.
                    mSubtitleView.show(subtitle);
                }
    
                @Override
                public void onSubtitleHide(int trackIndex, long id) {
                    // Remove subtitle.
                    mSubtitleView.dismiss(String.valueOf(id));
                }
    
                @Override
                public void onSubtitleHeader(int trackIndex, String header) {
                }
            }
        );

External subtitles (custom rendering based on rendering components)

Full support for WebVTT external subtitles is implemented using VttSubtitleView and WebVttResolver, allowing flexible customization of subtitle font size, color, and specific fonts.

Note

Applicable scenarios:

  • Customizing WebVTT subtitle styles.

  • Integrating ApsaraVideo Player SDK version 7.11.0 or later.

Important

Prerequisites:

  • Font files (.ttf) are placed in the assets/fonts/ directory of your project.

  • Project minSdk ≥ 21 (recommended).

  • Subtitle listeners are added and WebVTT content can be obtained.

  1. Create CustomStyleWebVttResolver and implement WebVttResolver.

    public class CustomStyleWebVttResolver extends WebVttResolver {
    
        // Implement creation method.
        public CustomStyleWebVttResolver(Context context) {
            super(context);
            // Initialize fonts and other resources here later.
        }
    }
  2. Override applyTextSpans to customize styles.

    This method is called after the parent class parses basic styles, allowing secondary processing of subtitles.

    • Method 1: Modify VttContentAttribute and call the parent class method.

      /**
       * Override text style application logic to implement custom style effects.
       * This method is called after the parent class parses basic styles, allowing secondary processing of font size, color, and other attributes.
       *
       * @param spannableStringBuilder Used to build styled text.
       * @param vttContentAttribute Style attribute object for the current text segment (includes font, color, size, etc.).
       * @param start Start position for style application (inclusive).
       * @param end End position for style application (exclusive).
       */
      @Override
      protected void applyTextSpans(SpannableStringBuilder spannableStringBuilder, VttContentAttribute vttContentAttribute, int start, int end) {
          // Set.
          // Save original font size (in px) for later adjustment.
          // Default font size is 0.0533f times video height.
          double originalFontSizePx = vttContentAttribute.fontSizePx;
      
          // Double the font size.
          vttContentAttribute.fontSizePx = originalFontSizePx * 2;
          
          // Change font color to red.
          vttContentAttribute.mPrimaryColour = Color.argb(255, 255, 0, 0);
      
          // Call parent class method to apply text.
          super.applyTextSpans(spannableStringBuilder, vttContentAttribute, start, end);
      }
    • Directly operate SpannableStringBuilder to modify WebVTT styles directly.

      Important

      This method may cause loss of native WebVTT styles.

      /**
       * Override text style application logic to implement custom style effects.
       * This method is called after the parent class parses basic styles, allowing secondary processing of font size, color, and other attributes.
       *
       * @param spannableStringBuilder Used to build styled text.
       * @param vttContentAttribute Style attribute object for the current text segment (includes font, color, size, etc.).
       * @param start Start position for style application (inclusive).
       * @param end End position for style application (exclusive).
       */
      @Override
      protected void applyTextSpans(SpannableStringBuilder spannableStringBuilder, VttContentAttribute vttContentAttribute, int start, int end) {
          // Set font color.
          spannableStringBuilder.setSpan(
              new ForegroundColorSpan(Color.RED),
              start, end,
              Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
          );
          
          // Set absolute size.
          spannableStringBuilder.setSpan(
              new AbsoluteSizeSpan(20), // Unit: px.
              start, end,
              Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
          );
          
          // Set relative size.
          // spannableStringBuilder.setSpan(
          //     new RelativeSizeSpan(2.0f), // Multiple of TextView default font size.
          //     start, end,
          //     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
          // );
      }
  3. Set custom fonts (Typeface).

    1. Load custom fonts from the asset/fonts/ directory.

      private Typeface mTypeface;
      
      public CustomStyleWebVttResolver(Context context) {
          super(context);
          initializeFonts(context);
      }
      
      private void initializeFonts(Context context) {
          try {
              // Load font from assets/fonts/.
              mTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/LongCang.ttf");
          } catch (Exception e) {
              Log.e("Font", "Failed to load font", e);
              mTypeface = Typeface.DEFAULT; // Safe fallback.
          }
      }
    2. Apply custom fonts to subtitles.

      @Override
      protected void applyTextSpans(SpannableStringBuilder builder, VttContentAttribute attr, int start, int end) {
          // Apply custom font.
          // Must be placed after super.applyTextSpans() to override fonts possibly set by the parent class.
          // Calling super.applyTextSpans() is optional.
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
              builder.setSpan(new TypefaceSpan(mTypeface), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
          } else {
              builder.setSpan(new CustomTypefaceSpan(mTypeface), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
          }
      }

      Compatibility with older Android versions: Since TypefaceSpan in Android P (API 28) and earlier does not support directly passing a Typeface object, you need to create a custom MetricAffectingSpan.

      /**
        * Custom Typeface Span class.
        * Inherits from MetricAffectingSpan to correctly apply Typeface during text drawing and measurement.
        * Solves the issue where standard TypefaceSpan cannot directly use a Typeface object.
      */
      private static class CustomTypefaceSpan extends MetricAffectingSpan {
      
          // Custom font to apply.
          private final Typeface typeface;
      
          /**
            * Constructor.
            *
            * @param typeface Typeface object to apply (must not be null).
            */
          public CustomTypefaceSpan(Typeface typeface) {
              this.typeface = typeface;
          }
      
          /**
            * Update text drawing state.
            * Called during actual text drawing to set the paint's font.
            *
            * @param tp TextPaint object used for drawing text.
            */
          @Override
          public void updateDrawState(TextPaint tp) {
              tp.setTypeface(typeface);
          }
      
          /**
            * Update text measurement state.
            * Called during text layout calculation (e.g., width, line breaks) to ensure measurement matches actual drawing.
            *
            * @param p TextPaint object used for measuring text.
            */
          @Override
          public void updateMeasureState(TextPaint p) {
              p.setTypeface(typeface);
          }
      }
  4. Integrate with the player.

    1. Initialize the subtitle view.

      // Initialize subtitleView.
      private void initSubtitleView() {
          // Get context.
          Context context = getContext();
      
          // Create CustomStyleWebVttResolver.
          CustomStyleWebVttResolver mResolver = new CustomStyleWebVttResolver(context);
      
          // Create VttSubtitleView and pass CustomStyleWebVttResolver.
          VttSubtitleView mVttSubtitleView = new VttSubtitleView(context, mResolver);
      
          // Add to video container.
          rootView.addView(mVttSubtitleView);
      }
    2. Bind external subtitle callbacks.

      // Set subtitle listener.
      mAliPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
          @Override
          public void onSubtitleExtAdded(int trackIndex, String url) {
              mAliPlayer.selectExtSubtitle(trackIndex, true);
          }
      
          @Override
          public void onSubtitleShow(int trackIndex, long id, String data) {
              if (mVttSubtitleView != null) {
                  // Show subtitle.
                  mVttSubtitleView.show(id, data); 
              }
          }
      
          @Override
          public void onSubtitleHide(int trackIndex, long id) {
              // Hide subtitle.
              mVttSubtitleView.dismiss(id);
          }
      
          @Override
          public void onSubtitleHeader(int i, String header) {
              if (!TextUtils.isEmpty(header)) {
                  // Apply WebVTT header styles.
                  mVttSubtitleView.setVttHeader(header);
              }
          }
      });

Audio-only playback

Disable video playback to achieve audio-only playback. Configure PlayerConfig before calling prepare.

PlayerConfig config = aliPlayer.getConfig();
config.mDisableVideo = true;  // Enable audio-only playback.
aliPlayer.setConfig(config);

Software/hardware decoder switching

Note

Switch the decoding method before playback starts. Switching during playback has no effect.

The Android Player SDK provides H.264 and H.265 hardware decoding with the enableHardwareDecoder switch. Hardware decoding is enabled by default and automatically falls back to software decoding if initialization fails. Example:

// Enable hardware decoding. Enabled by default.
aliPlayer.enableHardwareDecoder(true);

If the player automatically switches from hardware to software decoding, it triggers the onInfo callback. Example:

mApsaraPlayerActivity.setOnInfoListener(new IPlayer.OnInfoListener() {
    @Override
    public void onInfo(InfoBean infoBean) {
        if (infoBean.getCode() == InfoCode.SwitchToSoftwareVideoDecoder) {
            // Switched to software decoding.
        }
    }
});

H.265 adaptive playback

If the device is on the cloud-based H.265 hardware decoding blacklist or H.265 hardware decoding fails, adaptive degradation triggers: if an H.264 backup stream exists, the player uses it; otherwise, it degrades to H.265 software decoding.

Note
  • This feature is enabled only after you activate the client-cloud integrated adaptive decoding value-added service. You need to submit a Yida form to apply for license authorization.

  • The client-cloud integrated adaptive decoding value-added service includes: 1. Dynamic delivery of cloud-based hardware decoding compatibility data; 2. Adaptive degradation of H.265 streams to H.264 streams.

  • The SDK still has the capability to automatically switch to software decoding upon hardware decoding failure, even without activating the value-added service.

    Example of setting a backup stream:

// Maintain a Map at the application layer to store key-value pairs of original URLs and backup URLs. When switching, query the backup URL in the Map based on the original URL.
 AliPlayerGlobalSettings.setAdaptiveDecoderGetBackupURLCallback(new AliPlayerGlobalSettings.OnGetBackupUrlCallback() {
    @Override
    public String getBackupUrlCallback(int oriBizScene, int oriCodecType, String original_url) {
        String kurl = original_url;
        if (!H265toH264Map.get(kurl).isEmpty()) {
            return H265toH264Map.get(kurl);
        } else {
            return "";
        }
    }
});

Network-adaptive video definition switching

Note
  • HLS adaptive bitrate video streams can be generated through the video packaging and transcoding template group in ApsaraVideo VOD. For detailed operations, see Configure adaptive bitrate for VOD.

  • For adaptive streams generated by ApsaraVideo VOD transcoding, if you use Vid playback, you must specify the default playback definition list as DEFINITION_AUTO to obtain and play the adaptive video stream. Otherwise, the player selects a low-definition video stream according to the default logic. For the default definition playback order, see Which definition does the player SDK play by default when multiple definitions are transcoded?. Example of specifying the definition list for VidAuth playback:

    VidAuth vidAuth = new VidAuth();
    List<Definition> list = new ArrayList<>();
    list.add(Definition.DEFINITION_AUTO);
    vidAuth.setDefinition(list);

The Android player SDK supports adaptive bitrate HLS and DASH video streams. After prepare succeeds, you can obtain information about each bitrate stream, namely TrackInfo, by calling getMediaInfo. Example:

List<TrackInfo> trackInfos  = aliPlayer.getMediaInfo().getTrackInfos();

During playback, you can switch the playing bitrate stream by calling the player's selectTrack method. When the value is AUTO_SELECT_INDEX, it enables adaptive bitrate switching. Example:

int index = trackInfo.getIndex();
// Switch bitrate.
aliPlayer.selectTrack(index);
// Switch bitrate and enable adaptive switching.
aliPlayer.selectTrack(TrackInfo.AUTO_SELECT_INDEX);

The switching result is returned through the OnTrackChangedListener callback (set before calling selectTrack). Example:

aliPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
    @Override
    public void onChangedSuccess(TrackInfo trackInfo) {
        // Switch succeeded.
    }
    @Override
    public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
        // Switch failed. Obtain the failure reason from errorInfo.getMsg().
    }
});

Optional: Before calling the player's selectTrack method to switch to adaptive bitrate, you can set the upper limit for adaptive bitrate (ABR) switching in config to avoid automatic switching to unexpected bitrates. Example: (We recommend calling the following code before the player calls the prepare method or before the playlist player calls the moveTo method to make it effective.)

PlayerConfig config = aliPlayer.getConfig();
config.mMaxAllowedAbrVideoPixelNumber = 921600; // Set the pixel count upper limit for ABR definition to 921600 (width × height = 1280 × 720), so ABR allows switching to definitions with pixel counts ≤ this value.
aliPlayer.setConfig(config);

Screenshot

The Android player SDK provides a screenshot feature for the current video, implemented by the snapshot interface. It captures the original data and returns it as a bitmap. The callback interface is OnSnapShotListener. Example:

// Set screenshot callback.
aliPlayer.setOnSnapShotListener(new OnSnapShotListener(){
    @Override
    public void onSnapShot(Bitmap bm, int with, int height){
        // Obtain the bitmap and image dimensions.
    }
});
// Capture the current playback frame.
aliPlayer.snapshot();

Preview playback

By configuring ApsaraVideo VOD, the Android player SDK can implement preview playback, supporting both VidSts and VidAuth playback methods (VidAuth is recommended for VOD). For configuration and usage instructions, see Preview videos.

After configuring preview playback, set the preview duration for the player using the VidPlayerConfigGen.setPreviewTime() method. Example for VidSts playback:

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

When the preview duration is set, the server returns only the content within the preview period instead of the full video when playing through the Android player SDK.

Note
  • VidPlayerConfigGen supports server request parameters. Request parameter description.

  • FLV and MP3 video formats do not support preview playback.

Set blacklist

The Android player SDK provides a hardware decoding blacklist mechanism. For devices that explicitly cannot use hardware decoding, software decoding is used directly to avoid ineffective operations. Example:

DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.model="Lenovo K320t";
AliPlayerFactory.addBlackDevice(BlackType.HW_Decode_H264 ,deviceInfo );
Note

The blacklist is automatically invalidated after the app exits.

Set Referer

Set the request Referer using PlayerConfig. Combined with the Referer blacklist/whitelist in the console, this controls access permissions. Example:

// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Set referer, for example: http://example.aliyundoc.com. (Note: Include the protocol part when setting the referer.)
config.mReferrer = referrer;
....// Other settings.
  // Set configuration for the player.
aliPlayer.setConfig(config);

Set UserAgent

Set the request UserAgent using PlayerConfig. The player includes the UA in requests. Example:

// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Set UA.
config.mUserAgent = "UserAgent to set";
....// Other settings.
  // Set configuration for the player.
aliPlayer.setConfig(config);

Configure network retry time and count

Set the network timeout and retry count using PlayerConfig. Example:

// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Set network timeout duration, in milliseconds.
config.mNetworkTimeout = 5000;
// Set timeout retry count. The interval between retries is networkTimeout. networkRetryCount=0 means no retry; the retry policy is determined by the app. Default value is 2.
config.mNetworkRetryCount=2;
....// Other settings.
  // Set configuration for the player.
aliPlayer.setConfig(config);
Note
  • If NetworkRetryCount is set and a network issue causes loading, the player retries NetworkRetryCount times, with each interval being mNetworkTimeout.

  • If loading status persists after multiple retries, the onError event is triggered, with ErrorInfo.getCode()=ErrorCode.ERROR_LOADING_TIMEOUT.

  • If NetworkRetryCount is set to 0, when network retry times out, the player triggers the onInfo event, with InfoBean.getCode()=InfoCode.NetworkRetry. At this point, you can call the player's reload method to reload the network or handle it otherwise.

Configure cache and latency control

The Android player SDK provides interfaces to control cache and latency through PlayerConfig. Example:

Expand to view code

// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Maximum latency. Note: Valid for live streaming. When latency is large, the player SDK internally synchronizes frames to keep latency within this range.
config.mMaxDelayTime = 5000;
// Maximum buffer duration, in ms. The player loads up to this duration of buffer data each time.
config.mMaxBufferDuration = 50000;
// High buffer duration, in ms. When poor network conditions cause data loading, loading stops when buffer duration reaches this value.
config.mHighBufferDuration = 3000;
// Startup buffer duration, in ms. Shorter duration means faster startup but may cause quick entry into loading state after playback starts.
config.mStartBufferDuration = 500;
....// Other settings.
// Maximum backward buffer duration, in ms. Default is 0.
config.mMaxBackwardBufferDurationMs = 0;

// Set configuration for the player.
aliPlayer.setConfig(config);

Important
  • The buffer durations must satisfy: mStartBufferDuration ≤ mHighBufferDuration ≤ mMaxBufferDuration.

  • If mMaxBufferDuration exceeds 5 minutes, the system defaults to 5 minutes to prevent memory exceptions caused by excessive buffer size.

Set HTTP headers

Using the PlayerConfig method, you can add HTTP header parameters to requests in the player. Example:

// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Define headers.
String[] headers = new String[1];
headers[0]="Host:example.com";// For example, set Host in the header.
// Set headers.
config.setCustomHeaders(headers);
....// Other settings.
  // Set configuration for the player.
aliPlayer.setConfig(config);

Picture-in-Picture

Note

For detailed code examples, refer to the API-Example Picture-in-Picture playback (PictureInPicture) module. This Java-based example project for the ApsaraVideo Player SDK for Android helps developers quickly master core SDK integration features.

Procedure:

  1. In the AndroidManifest.xml file, declare Picture-in-Picture permissions.

    <activity
      android:name=".PictureInPictureActivity"
      android:exported="true"
      android:supportsPictureInPicture="true"
      android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" />
  2. Switch the target Activity to Picture-in-Picture mode.

    Rational aspectRatio = new Rational(16, 9); // Aspect ratio for Picture-in-Picture; adjust based on your business needs.
    PictureInPictureParams.Builder pipBuilder = new PictureInPictureParams.Builder();
    pipBuilder.setAspectRatio(aspectRatio);
    enterPictureInPictureMode(pipBuilder.build());

    You can trigger Picture-in-Picture mode from OnClick (click event), when leaving the app, or when returning to the app. Implementation methods:

    OnClick (click event) trigger

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Rational aspectRatio = new Rational(16, 9); // Aspect ratio for Picture-in-Picture.
            PictureInPictureParams.Builder pipBuilder = new PictureInPictureParams.Builder();
            pipBuilder.setAspectRatio(aspectRatio);
            enterPictureInPictureMode(pipBuilder.build());
        }
    });

    Trigger when leaving the app

    @Override
    protected void onUserLeaveHint() {
        super.onUserLeaveHint();
        Rational aspectRatio = new Rational(16, 9); // Aspect ratio for Picture-in-Picture.
        PictureInPictureParams.Builder pipBuilder = new PictureInPictureParams.Builder();
        pipBuilder.setAspectRatio(aspectRatio);
        enterPictureInPictureMode(pipBuilder.build());
    
        Log.e(TAG, "Picture-in-Picture onUserLeaveHint");
    }

    Trigger when returning to the app

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        // Trigger from back press.
        enterPictureInPictureMode();
    }
  3. Handle UI for Picture-in-Picture display/disappearance.

    @Override
    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
        super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
        if (isInPictureInPictureMode) {
            // Handle entering Picture-in-Picture mode.
            // hide UI
            Log.e(TAG, "Entered Picture-in-Picture mode");
        } else {
            // Handle exiting Picture-in-Picture mode.
            // show UI 
            Log.e(TAG, "Exited Picture-in-Picture mode");
        }
    }

Live RTS degradation

Note

For detailed code examples, refer to the API-Example RTS ultra-low latency live playback (RtsLiveStream) module. This Java-based example project for the ApsaraVideo Player SDK for Android helps developers quickly master core SDK integration features.

RTS live playback.

Switch left/right audio channels

The Android player SDK provides the setOutputAudioChannel method to set the output audio channel. If the input source is stereo, you can switch to the left or right channel using this method. If the input source is mono, the setting has no effect.

Note

The output audio channel setting affects both audio rendering and PCM data callbacks.

/*
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_LEFT switches to left channel playback,
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_RIGHT switches to right channel playback,
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_NONE does not switch channels, maintaining the input source channels.
*/
aliPlayer.setOutputAudioChannel();

Parse audio streams

Set a listener to obtain audio and video stream data. The streams must not be encrypted, as encrypted streams cannot be parsed.

Expand to view code

// Optional configuration 1: Whether to return the address of underlying data.
IPlayer.RenderFrameCallbackConfig config = new IPlayer.RenderFrameCallbackConfig();
config.mVideoDataAddr = true;// Whether to return only the address of underlying video data.
config.mAudioDataAddr = true;// Whether to return only the address of underlying audio data.
aliPlayer.setRenderFrameCallbackConfig(config);

// Optional configuration 2: For hardware decoding, RenderFrame returns texture_oes_id; for software decoding, RenderFrame returns source data.
aliPlayer.enableHardwareDecoder(true);
// Set listener to obtain audio and video data.
aliPlayer.setOnRenderFrameCallback(frameInfo -> {
    if (frameInfo.frameType == FrameInfo.FrameType_video) {
        // Video data.
    } else {
        // Audio data.
    }
    return false;
});

Set video background color

The Android player SDK supports setting the background color for player rendering. Interface and usage instructions:

Interface example

/**
 * Set video background color.
 *
 * @param color  ARGB
 */
abstract public void setVideoBackgroundColor(int color);

Usage instructions

// Parameter is an 8-digit hexadecimal value. Each pair of digits represents A (alpha transparency), R (red), G (green), B (blue) in order.
// For example, 0x0000ff00 represents green.
aliPlayer.setVideoBackgroundColor(0x0000ff00);

vidAuthSet specified playback domain

Using vidAuth, you can specify fields such as the domain for the vid. For supported fields, see GetPlayInfo request parameters. Interface and usage instructions:

Interface example

/**
 * Set playback parameters.
 *
 * @param playConfig Playback parameters.
 */
public void setPlayConfig(VidPlayerConfigGen playConfig);

Usage instructions

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

vidAuth = new VidAuth();
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
// Add playDomain field. For other fields you can add, refer to
//https://www.alibabacloud.com/help/zh/vod/developer-reference/api-vod-2017-03-21-getplayinfo
configGen.addPlayerConfig("playDomain", "com.xxx.xxx");
vidAuth.setPlayConfig(configGen);

H.266 decoding plugin

H.266 (VVC/Versatile Video Coding) is a next-generation video coding standard that significantly reduces bitrate at equivalent quality. The H.266 decoding capability is independently packaged as a plugin for on-demand integration.

Prerequisites

  1. Player/integrated SDK version V7.6.0 or later.

  2. Professional Edition license authorization completed. Obtain a player SDK license.

  3. ApsaraVideo Player with the H.266 decoding plugin supports only H.266 videos transcoded by ApsaraVideo VOD audio and video transcoding.

Integrate plugin

Player SDK

Maven integration (recommended)

Add the dependency for the specified plugin version in your app's build.gradle file:

Note

For the latest Android player SDK versions, see Android SDK release history.

// x.x.x matches the player SDK version number.
com.aliyun.sdk.android:AlivcVVCCodec:x.x.x

Local integration

Download the latest Android player SDK and copy the AlivcVVCCodec package to your project's libs directory (create it manually if it doesn't exist). For details, see Local integration.

Integrated SDK

Maven integration

Add the dependency for the specified plugin version in your app's build.gradle file:

// x.x.x matches the integrated SDK version number.
com.aliyun.sdk.android:AlivcVVCCodec:x.x.x-aio

Activate plugin

Note

Starting from Android player SDK 7.7.0, the plugin is enabled by default after integration and does not require manual activation.

AliPlayerGlobalSettings.enableCodecPlugin("vvc", true);

Related error codes

For H.266 decoding plugin error codes, see Common issues for players on all platforms.

Auto-refresh playback sources

Enabling auto-refresh for playback sources prevents playback interruptions caused by source expiration under authentication mechanisms.

Prerequisites

  1. Player/integrated SDK version V7.9.0 or later.

  2. Using VidAuth source for playback or your business has configured URL signing.

VidAuth source

Interface example

/**
 * Set 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}.
 */
abstract public void setOnVidAuthExpiredListener(OnVidAuthExpiredListener listener);

Feature components

Feature components

/**
 * Listener for VidAuth source expiration notifications.
 * Handles events when a VidAuth source expires.
 */
public interface OnVidAuthExpiredListener {

    /**
     * Called when the player detects that the VidAuth source has expired.
     *
     * You can refresh the VidAuth source in this callback and return the new VidAuth
     * using {@link SourceRefreshCallback#onSuccess}.
     *
     * @param expiredSource The expired VidAuth source object. See {@link VidAuth}.
     * @param callback The callback used to provide the updated VidAuth source to the player. See {@link SourceRefreshCallback}.
     */
    void onVidAuthExpired(VidAuth expiredSource, SourceRefreshCallback<VidAuth> callback);
}

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

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

Usage instructions

Obtain video playback credentials using the GetVideoPlayAuth API. We recommend integrating the VOD server SDK to obtain credentials and avoid self-signing. For more information, see OpenAPI portal.

// Set VID playback credential expiration listener.
aliPlayer.setOnVidAuthExpiredListener(new AliPlayer.OnVidAuthExpiredListener() {
    @Override
    public void onVidAuthExpired(VidAuth vidAuth, UrlPlayer.SourceRefreshCallback<VidAuth> sourceRefreshCallback) {
        
        String vid = vidAuth.getVid();

        // ------------------- User implementation starts -------------------
        // Call your own function to get new PlayAuth from your app server.
        // clinetGetPlayAuthFunction is an example function name; replace it with your own implementation.
        clinetGetPlayAuthFunction(vid, new PlayAuthCallback() {
            
            /**
             * Callback when new credentials are successfully obtained.
             * @param newPlayAuth New playback credential string obtained from your server.
             */
            @Override
            public void onAuthSuccess(String newPlayAuth) {                
                // 1. Update the old vidAuth object with the new PlayAuth.
                vidAuth.setPlayAuth(newPlayAuth);
                
                // 2. Return the updated object to the player via the SDK callback.
                sourceRefreshCallback.onSuccess(vidAuth);
            }

            /**
             * Callback when obtaining new credentials fails.
             * @param errorMessage Detailed error message.
             */
            @Override
            public void onAuthError(String errorMessage) {                
                // Return the error message to the player via the SDK callback.
                sourceRefreshCallback.onError(errorMessage);
            }
        });
        // ------------------- User implementation ends -------------------
    }
});

UrlSource source

Interface example

/**
 * Set 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 using {@link SourceRefreshCallback#onSuccess}.
 *
 * @param listener Listener for handling URL source expiration events. See {@link OnURLSourceExpiredListener}.
 *
 * <p>For more information on configuring URL authentication, see
 * <a href="https://www.alibabacloud.com/help/zh/vod/user-guide/configure-url-signing?spm=a2c4g.11186623.0.0.560c4140fGh8MW">URL authentication documentation</a>.</p>
 */
abstract public void setOnURLSourceExpiredListener(OnURLSourceExpiredListener listener);

Feature 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 URL source or VidAuth source. When the player triggers a refresh request,
 * the refresh result can be returned via this interface by invoking either the `onSuccess` or `onError` method.
 */
public interface SourceRefreshCallback<T extends SourceBase> {
    /**
     * Called by the player when the refresh operation succeeds.
     *
     * @param newSource The new playback source object containing the updated information. See {@link SourceBase}.
     *
     * This method indicates that the refresh operation was successfully completed. Developers should provide
     * the new playback source within this method so that the player can load the latest resource.
     */
    void onSuccess(T newSource);

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

/**
 * Listener for URL source expiration notifications.
 * This helps process expired sources and prevents playback interruptions.
 */
public interface OnURLSourceExpiredListener {

    /**
     * Called 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
     * 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}.
     */
    void onUrlSourceExpired(UrlSource expiredSource, SourceRefreshCallback<UrlSource> callback);
}

Usage instructions

// Set the player's URL expiration listener.
mAliyunVodPlayer.setOnURLSourceExpiredListener(new UrlPlayer.OnURLSourceExpiredListener() {
    @Override
    public void onUrlSourceExpired(UrlSource urlSource, UrlPlayer.SourceRefreshCallback<UrlSource> sourceRefreshCallback) {
        String expiredUrl = urlSource.getUri();
        Log.d(TAG, "[onUrlSourceExpired] Received expired URL: " + expiredUrl);

        // 1. Check if the authentication key is valid (assuming authenticationKey is a member variable of the class).
        if (authenticationKey == null || authenticationKey.trim().isEmpty()) {
            Log.e(TAG, "Refresh failed: Authentication key is empty.");
            sourceRefreshCallback.onError("REFRESH_ERROR: Authentication key is missing.");
            return; // Exit early if the key is invalid.
        }

        // 2. Calculate the validity duration (expiration time) for the playback URL.
        // If the class member validTime is valid, use it; otherwise, default to 3600 seconds (1 hour).
        long validityDuration = (AliyunVodPlayerView.this.validTime > 0) ? validTime : 3600;
        long newExpireTime = (System.currentTimeMillis() / 1000) + validityDuration;

        // 3. Extract the original URL from the expired URL (using authentication type A as an example).
        // Restore the original resource address by removing URL parameters (e.g., "?auth_key=").
        int authKeyIndex = expiredUrl.indexOf("?auth_key=");
        if (authKeyIndex == -1) {
            authKeyIndex = expiredUrl.indexOf("&auth_key=");
        }
        // Safely handle cases where auth_key is not found.
        String originalUrl = (authKeyIndex != -1) ? expiredUrl.substring(0, authKeyIndex) : expiredUrl;

        // 4. Generate a new authenticated URL using a utility class.
        String newAuthUrl = CdnAuthUtil.aAuth(originalUrl, authenticationKey, newExpireTime);

        // 5. Check the generated authenticated URL and return the result via callback.
        if (newAuthUrl != null && !newAuthUrl.isEmpty()) {
            Log.i(TAG, "Refresh success, new URL: " + newAuthUrl);
            // Create a UrlSource object as required by the SDK and set the new URL.
            UrlSource resultSource = new UrlSource();
            resultSource.setUri(newAuthUrl);
            sourceRefreshCallback.onSuccess(resultSource);
        } else {
            Log.e(TAG, "Refresh failed: Failed to generate new authorized URL.");
            sourceRefreshCallback.onError("REFRESH_ERROR: Failed to generate new URL.");
        }
    }
});

Supplementary utility functions

Using authentication type A as an example.

Supplementary utility functions

// Authenticated URL generation function.
private String generateAuthUrl(String uri, String key, long exp) {
    Pattern uriPattern = Pattern.compile("^(https?://)?([^/?]+)(/[^?]*)?(\\?.*)?$");
    Matcher m = uriPattern.matcher(uri);

    if (!m.matches()) {
        return null;
    }

    String scheme = (m.group(1) != null) ? m.group(1) : "http://";
    String host = m.group(2);
    String path = (m.group(3) != null) ? m.group(3) : "/";
    String args = (m.group(4) != null) ? m.group(4) : "";

    String rand = "0";
    String uid = "0";

    String sstring = String.format("%s-%d-%s-%s-%s", path, exp, rand, uid, key);
    String hashvalue = md5sum(sstring);
    String authKey = String.format("%d-%s-%s-%s", exp, rand, uid, hashvalue);

    if (!args.isEmpty()) {
        return String.format("%s%s%s%s&auth_key=%s", scheme, host, path, args, authKey);
    } else {
        return String.format("%s%s%s%s?auth_key=%s", scheme, host, path, args, authKey);
    }
}

// MD5 calculation utility function.
private String md5sum(String src) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(src.getBytes(StandardCharsets.UTF_8));
        byte[] digest = md.digest();

        StringBuilder hexString = new StringBuilder();
        for (byte b : digest) {
            hexString.append(String.format("%02x", b));
        }
        return hexString.toString();
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException("MD5 algorithm not found", e);
    }
}

Switch bound NIC

The Android player SDK provides the AliPlayerGlobalSettings.enableSwitchNIC method to automatically switch NICs during network anomalies, ensuring stable resource playback. Example:

Note

This takes effect only when the switch is enabled and multiple NICs exist.

AliPlayerGlobalSettings.enableSwitchNIC(true);

Audio enhancement

The Android player SDK provides an audio enhancement plugin to improve audio playback experience, featuring volume normalization, voice enhancement, and surround sound.

Feature introduction

  • Volume normalization: Automatically adjusts all audio content to a consistent volume level, significantly improving playback experience for videos with excessively low or high original volume.

    • Supported channels: Mono / Stereo / 5.1 / 7.1.

    • Supported sample rates: 16kHz / 44.1kHz / 48kHz.

  • Voice enhancement: Intelligently enhances dialogue while preserving original timbre, making voices clearer and brighter in noisy scenes.

    • Supported channels: Stereo.

    • Supported sample rates: 44.1kHz / 48kHz.

  • Surround sound: Applies virtual surround rendering to multi-channel and stereo videos, providing an immersive experience on headphones or standard devices. Includes 3DSurround (stereo surround) and MegaBass (super bass) modes.

    • Supported channels: Mono / Stereo / 5.1 / 7.1.

    • Supported sample rates: 44.1kHz / 48kHz.

Prerequisites

  1. Player/integrated SDK version V7.13.0 or later.

  2. Professional Edition License authorization obtained. Obtain a player SDK license.

Important

Audio source support for audio enhancement:

Integrate plugin

Maven integration (recommended)

Add the dependency for the specified plugin version in your app's build.gradle file:

Note

For the latest Android player SDK versions, see Android SDK release history.

// x.x.x matches the player SDK version number.
implementation 'com.aliyun.sdk.android:AlivcAudioEnhanceFilter:x.x.x'

Local integration

Download the latest Android player SDK and copy the AlivcAudioEnhanceFilter package to your project's libs directory (create it manually if it doesn't exist). For details, see Local integration.

Feature interfaces

setFilterValid

Controls the master switch for audio enhancement. The target name for the audio enhancement filter is audioEnhance. When disabled, all three sub-features are inactive (disabled by default).

player.setFilterValid("audioEnhance", true);   // Enable.
player.setFilterValid("audioEnhance", false);  // Disable.
setFilterConfig

Set FilterConfig before prepare. It takes effect after playback starts.

FilterConfig filterConfig = new FilterConfig();
FilterConfig.Filter filterItem = new FilterConfig.Filter("audioEnhance");
FilterConfig.FilterOptions opts = new FilterConfig.FilterOptions();
// Surround sound.
opts.setOption("enable_surround", true);
opts.setOption("surround_effect_type", "3DSurround"); // Type must be set together with enable_surround on first use.
// Voice enhancement.
opts.setOption("enable_dialoguenhance", true);
opts.setOption("dialoguenhance_voice", 1.0f); // 1.0 ~ 10.0. Voice must be set together with enable_dialoguenhance on first use.
// Volume normalization.
opts.setOption("enable_normalizer", true);

filterItem.setOptions(opts);
filterConfig.addFilter(filterItem);
player.setFilterConfig(filterConfig);

Parameter

Type

Description

enable_surround

Boolean

Surround sound feature switch.

surround_effect_type

String

Surround sound type: "3DSurround" / "MegaBass".

enable_dialoguenhance

Boolean

Voice enhancement feature switch.

dialoguenhance_voice

Float

Voice enhancement strength, range 1.0 ~ 10.0.

enable_normalizer

Boolean

Volume normalization feature switch.

updateFilterConfig

During or after player preparation, to dynamically adjust parameters, call this interface to update them.

Note

Calling updateFilterConfig before prepare has no effect. Use setFilterConfig for initial configuration.

AVPFilterOptions *opts = [[AVPFilterOptions alloc] init];
[opts setOptions:@"enable_surround" value:@YES];
[opts setOptions:@"surround_effect_type" value:@"3DSurround"]; // If not the first time enabling surround, this Type setting is invalid because initialization is already complete.
[player updateFilterConfig:@"audioEnhance" options:opts];
Important

Surround sound type ("3DSurround" / "MegaBass") and voice enhancement strength (dialoguenhance_voice) must be set together with the enable attribute on first use. Otherwise, default values are used for initialization (surround sound defaults to "3DSurround", voice strength defaults to 1.0), and they cannot be modified during playback.

Performance

Set playback scenario

Setting the playback scenario automatically configures optimal parameters (including buffer settings and feature switches). It is compatible with custom parameter settings via the setConfig interface (custom settings take precedence).

Note
  • After setting the playback scenario, you can view the parameter configuration using the getConfig interface.

Interface example

/**
 * Set the player scenario.
 *
 * @param scene 
 */
abstract public void setPlayerScene(PlayerScene scene);

Playback scenarios

public enum PlayerScene {
    /**
     * Scenario: none.
     */
    NONE,
    /**
     * Long video scenario: applies to videos longer than 30 minutes.
     */
    LONG,
    /**
     * Medium video scenario: applies to videos between 5 and 30 minutes.
     */
    MEDIUM,
    /**
     * Short video scenario: applies to videos up to 5 minutes.
     */
    SHORT,
    /**
     * Live scenario.
     */
    LIVE,
    /**
     * Ultra-low latency live scenario.
     */
    RTS_LIVE
}

Usage instructions

// Set short video scenario.
aliPlayer.setPlayerScene(PlayerScene.SHORT)

// Set medium video scenario.
aliPlayer.setPlayerScene(PlayerScene.MEDIUM)

// Set long video scenario.
aliPlayer.setPlayerScene(PlayerScene.LONG)

// Set live scenario.
aliPlayer.setPlayerScene(PlayerScene.LIVE)

Pre-rendering

The Android player SDK supports quickly rendering the first frame before playback starts, which can improve startup speed.

Note
  1. This feature is disabled by default.

  2. You must set the View before calling Prepare to ensure the frame is rendered to the View as soon as it is ready.

  3. Enabling this feature affects the triggering order of preparation success and first-frame rendering events: without it, preparation success is triggered before first-frame rendering; with it, due to differences in decoding and rendering speed, first-frame rendering may be triggered before preparation success, but this does not affect playback.

    Example:

aliPlayer.setOption(ALLOW_PRE_RENDER, 1);

Local cache

Note

For detailed code examples, refer to the API-Example Video preloading (Preload) module. This Java-based example project for the ApsaraVideo Player SDK for Android helps developers quickly master core SDK integration features.

Local cache improves startup speed, seek speed, and reduces stuttering for repeated playback while saving bandwidth.

Enable local cache

Local cache is disabled by default. To use it, enable it manually using AliPlayerGlobalSettings and enableLocalCache. Example:

Expand to view code

// Enable local cache (default path).
AliPlayerGlobalSettings.enableLocalCache(true, this);

/**
 * You can also use the following code for cache settings.
 * Enable local cache. After enabling, content is cached to local files.
 * @param enable: Local cache feature switch. true: enable, false: disable. Disabled by default.
 * @param maxBufferMemoryKB: Deprecated since version 5.4.7.1, currently has no effect.
 * @param localCacheDir: Must be set. Local cache directory as an absolute path.
 * AliPlayerGlobalSettings.enableLocalCache(enable, maxBufferMemoryKB, localCacheDir);
 */

/**
 * Local cache file cleanup configuration.
 * @param expireMin - Deprecated since version 5.4.7.1, currently has no effect.
 * @param maxCapacityMB - Maximum cache capacity in MB. Default is 20 GB. During cleanup, if total cache size exceeds this value, cache items are deleted one by one from oldest to newest until size is ≤ maxCapacityMB.
 * @param freeStorageMB - Minimum free disk space in MB. Default is 0. During cleanup, if current disk space is less than this value, cache items are deleted one by one until free space ≥ this value or all cache is cleared.
 * public static void setCacheFileClearConfig(long expireMin,
 *         long maxCapacityMB,
 *         long freeStorageMB)
 */

 /**
  * Set callback for loading URL hash value. If not set, SDK uses MD5 algorithm.
  * public static void setCacheUrlHashCallback(AliPlayerGlobalSettings.OnGetUrlHashCallback cb)
  */
Note
  • If video playback URLs include authentication parameters, the parameters change between caching and playback. To improve cache hit rate for the same URL under different authentications, remove authentication parameters before calculating the hash value (e.g., MD5) via setCacheUrlHashCallback. For example, for a URL like http://****.mp4?aaa, calculate the hash using http://****.mp4. However, for encrypted m3u8 videos, if you remove authentication parameters from keyURLs before hashing, different videos might hit the same key, causing playback failure. Solution: In the setCacheUrlHashCallback callback, check the domain and only remove authentication parameters for playback domains (http(s)://xxxxx.m3u8?aaaa), not for keyURL domains (http(s)://yyyyy?bbbb). Use curl to get the HLS encrypted video M3U8 playlist, where playURL is the M3U8 address and keyURL is the AES-128 decryption key address. Example terminal output:

    # playURL: M3U8 playlist request
    C:\Users\futan>curl "https://videxxxv.cc/a003xxx2a-hd-encrypt-stream.m3u8?MtsHlsUriToken=uheAz07oi-jlo9CeIU6LxxxAr4a3WtzrJXnCn4ClS44dTYHCQGmXBlo7TyuPLE0a&auth_key=17xxxrmonwFHJ"
    
    #EXTM3U
    #EXT-X-VERSION:3
    #EXT-X-ALLOW-CACHE:YES
    #EXT-X-TARGETDURATION:10
    #EXT-X-MEDIA-SEQUENCE:0
    # keyURL: AES-128 encryption key address
    #EXT-X-KEY:METHOD=AES-128,URI="https://apxxx.cc/decrypt?Ciphertext=NWNiNDQyN2MtNjV1ZS00ZWIwLTk0YTAtNTJhOWIyZWV1OTY2MzdoRTJ6TjVxcXkweFY2xxxNCt4OGNFRGNReHRG&MtsHlsUriToken=uheAz07oi-jlo9CeIU6LxxxAr4a3WtzrJXnCn4ClS44dTYHCQGmXBlo7TyuPLE0a"
    #EXTINF:10.000000,
    e9012989ecd8e987eb7349d84d3b06d8-hd-encrypt-stream-00001.ts?auth_key=1706560316-65b7xxx39f1d6c77
    #EXTINF:10.000000,
    e9012989ecd8e987eb7349d84d3b06d8-hd-encrypt-stream-00002.ts?auth_key=1706560316-65b7xxxe8eca2faf
    #EXTINF:10.000000,
    e9012989ecd8e987eb7349d84d3b06d8-hd-encrypt-stream-00003.ts?auth_key=1706560316-65b7xxx50c6981b3
    #EXTINF:10.000000,
    e9012989ecd8e987eb7349d84d3b06d8-hd-encrypt-stream-00004.ts?auth_key=1706560316-65b7xxxf7228c594
    #EXTINF:10.000000,
    e9012989ecd8e987eb7349d84d3b06d8-hd-encrypt-stream-00005.ts?auth_key=1706560316-65b7xxx6dc68c35d
  • If the server supports both HTTP and HTTPS protocols pointing to the same media file, remove or standardize the protocol before calculating the hash. For example:

    • For URLs https://****.mp4 and http://****.mp4, calculate the hash using ****.mp4.

    • For URL https://****.mp4, standardize to http://****.mp4 before calculating the hash.

  • For player SDK version 5.5.4.0 and later, if the video playback URL includes authentication parameters and uses HLS protocol, you can set PlayerConfig.mEnableStrictAuthMode to choose between authentication modes (default is false for older versions; true for version 7.13.0 and later):

    • Non-strict authentication (false): Authentication is cached. If only part of the media was cached previously, the player uses the cached authentication for subsequent requests. If URL authentication has a short validity period or playback resumes after a long pause, authentication may expire. Integrate with auto-refresh playback sources to handle authentication expiration.

    • Strict authentication (true): Authentication is not cached. Authentication occurs on every startup, causing startup failure without network.

Enable or disable local cache for a single URL

To enable or disable local cache for a specific URL, set it in the player config.

// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Whether to enable local cache for the playback URL. Default is true. When global local cache is enabled and this is set to true, local cache takes effect for this URL. If set to false, local cache is disabled for this URL.
config.mEnableLocalCache = false;
....// Other settings.

// Set configuration for the player.
aliPlayer.setConfig(config);

Preloading

Preloading is an upgrade to local cache that improves video startup speed by setting memory usage for video caching.

Preloading limitations:

  • Currently supports loading single media files such as MP4, MP3, FLV, and HLS.

Note

The Android player SDK provides automatic network resource scheduling during preloading by default to reduce the impact of preloading network requests on ongoing video playback. The automatic scheduling strategy allows preloading requests only after the buffer of the currently playing video reaches a certain threshold. To control real-time preloading requests yourself, disable this strategy using the following method:

AliPlayerGlobalSettings.enableNetworkBalance(false);
  1. Enable local cache. For detailed steps, see Local cache.

  2. Set data source.

    VidAuth (recommended)

    VidAuth vidAuth = new VidAuth();
    vidAuth.setVid("Vid info");// Required parameter: Video ID.
    vidAuth.setPlayAuth("<yourPlayAuth>");// Required parameter: Playback credential, generated by calling the GetVideoPlayAuth API of VOD.
    vidAuth.setRegion("Access region");// For player SDK version 5.5.5.0 and later, this parameter is deprecated and not required; the player automatically parses the region. For versions before 5.5.5.0, this parameter is required; the default VOD access region is cn-shanghai.
    vidAuth.setQuality("Selected definition") //"AUTO" represents adaptive bitrate.

    VidSts

    VidSts vidSts = new VidSts();
    vidSts.setVid("Vid info");// Required parameter: Video ID. vidSts.setAccessKeyId("<yourAccessKeyId>");// Required parameter: Access key ID of the STS temporary AK pair, generated by calling the AssumeRole API of STS.  vidSts.setAccessKeySecret("<yourAccessKeySecret>");// Required parameter: Access key of the STS temporary AK pair, generated by calling the AssumeRole API of STS.  vidSts.setSecurityToken("<yourSecurityToken>");// Required parameter: STS security token, generated by calling the AssumeRole API of STS.  vidSts.setRegion("Access region");// Required parameter: VOD access region; default is cn-shanghai.
    vidSts.setQuality("Selected definition") //"AUTO" represents adaptive bitrate.

    UrlSource

    UrlSource urlSource = new UrlSource();
    urlSource.setUri("Playback address");// Required parameter: Playback address, which can be a third-party VOD address or an Alibaba Cloud VOD playback address.
  3. Set task parameters.

    Note

    Applies only to multi-bitrate videos. Choose one of setDefaultBandWidth, setDefaultResolution, or setDefaultQuality.

    PreloadConfig preloadConfig = new PreloadConfig();
    // Set preloading bitrate for multi-bitrate streams.
    preloadConfig.setDefaultBandWidth(400000);
    // Set preloading resolution for multi-bitrate streams.
    preloadConfig.setDefaultResolution(640 * 480);
    // Set preloading quality for multi-bitrate streams.
    preloadConfig.setDefaultQuality("FD");
    // Set preloading duration.
    preloadConfig.setDuration(1000);
  4. Add task listener.

    Expand to view code

    /**
     * Preloading listener implementation.
     */
    private static class PreloadListenerImpl extends OnPreloadListener {
    
        @Override
        public void onError(@NonNull String taskId, @NonNull String urlOrVid, @NonNull ErrorInfo errorInfo) {
            // Loading error.
        }
    
        @Override
        public void onCompleted(@NonNull String taskId, @NonNull String urlOrVid) {
            // Loading completed.
        }
    
        @Override
        public void onCanceled(@NonNull String taskId, @NonNull String urlOrVid) {
           // Loading canceled.
        }
    }
  5. Build task and add to MediaLoaderV2 instance to start preloading.

    VidAuth (recommended)

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

    VidSts

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

    UrlSource

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

    mediaLoaderV2.cancelTask(taskId);// Cancel preloading task with specified task ID.
    mediaLoaderV2.pauseTask(taskId);// Pause preloading task with specified task ID.
    mediaLoaderV2.resumeTask(taskId);// Resume preloading task with specified task ID.
  7. Optional: Delete loaded files.

    Delete loaded files as needed to save space. The Android player SDK does not provide a delete interface; delete files from the loading directory in your app.

Dynamic preloading

Dynamic preloading strategy allows integrators to control both the cache of the currently playing video and the number and cache of preloaded items, balancing playback experience and cost overhead.

Expand to view code

// Enable recommended configuration and dynamic preloading.
aliListPlayer.setPreloadScene(IListPlayer.SceneType.SCENE_SHORT);

// Configure baseline preloading duration.
// Set preloading duration to 1000ms.
PreloadConfig config = new PreloadConfig();
config.mPreloadDuration = 1000;
aliListPlayer.updatePreloadConfig(config);

// Configure number of preloads, supporting bidirectional.
// 1 for forward preloads, 3 for backward preloads.
aliListPlayer.setPreloadCount(1, 3);

// Configure dynamic preloading decrement offset.
aliListPlayer.enablePreloadStrategy(IListPlayer.StrategyType.STRATEGY_DYNAMIC_PRELOAD_DURATION, true);
aliListPlayer.setPreloadStrategy(IListPlayer.StrategyType.STRATEGY_DYNAMIC_PRELOAD_DURATION, "{\"algorithm\": \"sub\",\"offset\": \"200\"}");

Multi-bitrate HLS video preloading

In listPlayer + multi-bitrate HLS video playback scenarios, integrators can preload streams matching the current playback definition and choose preloading modes based on business needs.

Expand to view supported preloading modes

  /**
   * Default configuration, play and preload default bitrate.
   */
  MultiBitratesMode_Default(0),

  /**
   * First frame priority configuration, decrease first frame cost. Only play bitrate of the HLS stream which has been preloaded.
   */
  MultiBitratesMode_FCPrio(1),

  /**
   * Balance first frame and playback smoothness, play the same bitrate before and after moveToNext, and prioritize first frame performance.
   */
  MultiBitratesMode_FC_AND_SMOOTH(2),

  /**
   * Playback smoothness priority configuration, play the same bitrate before and after moveToNext.
   */
  MultiBitratesMode_SmoothPrio(3);

Expand to view integration code

// Select multi-bitrate loading mode.
aliListPlayer.SetMultiBitratesMode(preLoadMode);

// (Optional) Select startup bitrate.
aliListPlayer.setDefaultBandWidth(defaultBandWidth)

// (Optional) In onPrepared callback, select ABR mode.
aliListPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
    @Override
    public void onPrepared() {
        // ABR only affects multi-bitrate m3u8.
        aliListPlayer.selectTrack(-1);
    }
});

Get download speed

Get the current video download speed through the onInfo callback, implemented by the getExtraValue interface. Example:

aliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
    @Override
    public void onInfo(InfoBean infoBean) {
        if(infoBean.getCode() == InfoCode.CurrentDownloadSpeed){
            // Current download speed.
            long extraValue = infoBean.getExtraValue();
        }
    }
});

Network features

HTTPDNS

HTTPDNS resolves domain names via HTTP to specific servers, reducing DNS hijacking risks and providing faster, more stable resolution.

The ApsaraVideo Player SDK provides enhanced HTTPDNS for Alibaba Cloud CDN domains, supporting precise CDN scheduling and real-time resolution.

Enhanced HTTPDNS usage example

Enhanced HTTPDNS provides services only for Alibaba Cloud CDN domains. Ensure your domain is an Alibaba Cloud CDN domain and is properly configured. For adding CDN domains in VOD, see Add accelerated domain. Alibaba Cloud CDN.

// Enable enhanced HTTPDNS.
AliPlayerGlobalSettings.enableEnhancedHttpDns(true);
// Optional: Add HTTPDNS pre-resolution domains.
DomainProcessor.getInstance().addPreResolveDomain("player.***alicdn.com");

HTTP/2

Note

The Android player SDK enables HTTP/2 by default starting from version 5.5.0.0.

The Android player SDK supports the HTTP/2 protocol, which uses multiplexing to avoid head-of-line blocking and improve playback performance. Example:

AliPlayerGlobalSettings.setUseHttp2(true);

HTTP pre-connect TCP

For HTTP video playback requests (non-HTTPS), establishing TCP connections in advance significantly improves user experience, reduces network connection time, ensures immediate and continuous playback, and optimizes network and system resource usage. Usage:

// Domain format is host[:port]; port is optional. Separate multiple domains with semicolons (;).
// Global setting.
// Full interface uses the current string each time it's set (more - add, less - remove). Empty string stops pre-connection.
AliPlayerGlobalSettings.setOption(AliPlayerGlobalSettings.SET_PRE_CONNECT_DOMAIN, "domain1;domain2");

Video download

Note

For detailed code examples, refer to the API-Example Video download and offline playback (Download) module. This Java-based example project for the ApsaraVideo Player SDK for Android helps developers quickly master core SDK integration features.

The Android player SDK provides a video download feature for VOD services, allowing users to cache videos locally using the ApsaraVideo Player. It offers two download methods: standard download and secure download.

  • Standard download

    Downloaded video data is not encrypted by Alibaba Cloud and can be played by third-party players.

  • Secure download

    Downloaded video data is encrypted by Alibaba Cloud. Third-party players cannot play it. Only the ApsaraVideo Player can play it.

Usage instructions

  • Only VidSts and VidAuth methods support video download.

  • To use the player's video download feature, enable and configure download mode in the VOD console. For detailed steps, see Offline download.

  • Video download supports resumable downloads.

Procedure

  1. Optional: Configure the encryption verification file for secure download. Required only for secure download; not needed for standard download.

    Note

    Ensure the configured encryption verification file matches your app information; otherwise, video download fails.

    For secure download, configure the key file generated in the VOD console in the player SDK for decryption verification during video download and playback. For key file generation, see Enable secure download.

    We recommend configuring this once in Application. Example:

    PrivateService.initService(getApplicationContext(),  "Path to encryptedApp.dat file"); // We recommend storing the encryptedApp.dat verification file on the phone and setting its local file path here.
  2. Create and set downloader.

    Create a downloader using AliDownloaderFactory. Example:

    AliMediaDownloader mAliDownloader = null;
    ......
    // Create downloader.
    mAliDownloader = AliDownloaderFactory.create(getApplicationContext());
    // Configure download save path.
    mAliDownloader.setSaveDir("Save folder path");
  3. Set event listeners.

    The downloader provides multiple event listeners. Example:

    Expand to view code

    mAliDownloader.setOnPreparedListener(new AliMediaDownloader.OnPreparedListener() {
       @Override
       public void onPrepared(MediaInfo mediaInfo) {
           // Download item prepared successfully.
       }
    });
    mAliDownloader.setOnProgressListener(new AliMediaDownloader.OnProgressListener() {
       @Override
       public void onDownloadingProgress(int percent) {
           // Download progress percentage.
       }
       @Override
       public void onProcessingProgress(int percent) {
           // Processing progress percentage.
       }
    });
    mAliDownloader.setOnErrorListener(new AliMediaDownloader.OnErrorListener() {
       @Override
       public void onError(ErrorInfo errorInfo) {
           // Download error.
       }
    });
    mAliDownloader.setOnCompletionListener(new AliMediaDownloader.OnCompletionListener() {
       @Override
       public void onCompletion() {
           // Download successful.
       }
    });
  4. Prepare download source.

    Prepare the download source using the prepare method. Download sources support VidSts and VidAuth methods. Examples:

    • VidSts

      // Create VidSts
      VidSts aliyunVidSts = new VidSts();
      aliyunVidSts.setVid("Vid information"); // Video ID (VideoId).
      aliyunVidSts.setAccessKeyId("<yourAccessKeyId>"); // AccessKey ID of the temporary STS AccessKey pair, generated by calling the AssumeRole operation of the Security Token Service (STS).
      aliyunVidSts.setAccessKeySecret("<yourAccessKeySecret>"); // AccessKey secret of the temporary STS AccessKey pair, generated by calling the AssumeRole operation of the Security Token Service (STS).
      aliyunVidSts.setSecurityToken("<yourSecurityToken>"); // Security Token Service (STS) token, generated by calling the AssumeRole operation of the Security Token Service (STS).
      aliyunVidSts.setRegion("region"); // The region of the video-on-demand (VOD) service. Default value: cn-shanghai.
      // If you have enabled HLS encryption parameter pass-through in the VOD console and the default parameter name is MtsHlsUriToken,
      // you must set the config and pass it into the vid, as shown below.
      // If you have not enabled HLS encryption parameter pass-through in the VOD console, skip the following code.
      VidPlayerConfigGen vidConfig = new VidPlayerConfigGen();
      vidConfig.setMtsHlsUriToken("<yourMtsHlsUriToken>");
      aliyunVidSts.setPlayerConfig(vidConfig);
              
      
      // Prepare the download source
      mAliDownloader.prepare(aliyunVidSts)
    • VidAuth

      // Create VidAuth.
      VidAuth vidAuth = new VidAuth();
      vidAuth.setVid("Vid info");// Video ID.
      vidAuth.setPlayAuth("<yourPlayAuth>");// Playback credential, generated by calling VOD GetVideoPlayAuth API.
      vidAuth.setRegion("Access region");// For player SDK version 5.5.5.0 and later, this parameter is deprecated and not required; the player automatically parses the region. For versions before 5.5.5.0, this parameter is required; VOD access region default is cn-shanghai.
      // If you enabled HLS standard encryption parameter pass-through in VOD console with default parameter name MtsHlsUriToken, set config and pass it to vid as follows.
      VidPlayerConfigGen vidConfig = new VidPlayerConfigGen();
      vidConfig.setMtsHlsUriToken("<yourMtsHlsUriToken>");
      vidAuth.setPlayerConfig(config);
      // Prepare download source.
      mAliDownloader.prepare(vidAuth);
    Note
    • Source file format matches the downloaded file format; changing it is not supported.

    • If you enabled HLS standard encryption parameter pass-through in VOD console with default parameter name MtsHlsUriToken, see HLS standard encryption parameter pass-through, then set the MtsHlsUriToken value in the VOD source as shown above.

  5. After successful preparation, select download item and start download.

    After successful preparation, the OnPreparedListener method is called. The returned TrackInfo contains information such as video stream definition. Select one Track for download. Example:

    public void onPrepared(MediaInfo mediaInfo) {
        // Download item prepared successfully.
        List<TrackInfo> trackInfos = mediaInfo.getTrackInfos();
        // For example: download the first TrackInfo.
        mAliDownloader.selectItem(trackInfos.get(0).getIndex());
        // Start download.
        mAliDownloader.start();
    }
  6. (Optional) Update download source.

    To prevent VidSts and VidAuth expiration, you can update the download source information and start downloading. Example:

    // Update download source.
    mAliDownloader.updateSource(VidSts);
    // Start download.
    mAliDownloader.start();
  7. After download success or failure, release downloader.

    After download success, call release in the onCompletion or onError callback to release the downloader. Example:

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

    You can delete downloaded files during or after download. Example:

    // Delete file via object.
    mAliDownloader.deleteFile();
    // Delete via static method; returns 0 if successful.
    AliDownloaderFactory.deleteFile("Path to download folder","Video ID","Video format","Downloaded video index");

What to do next

Downloaded videos can be played using the ApsaraVideo Player. Steps:

  1. After download completion, get the absolute path of the video file.

    String path = mAliDownloader.getFilePath();
  2. Set the absolute path via VOD UrlSource for playback.

     UrlSource urlSource = new UrlSource();
            urlSource.setUri("Playback address");// Set absolute path of downloaded video.
            aliPlayer.setDataSource(urlSource);

Encrypted playback

VOD videos support HLS standard encryption, Alibaba Cloud proprietary cryptography, and DRM encryption. Live videos support only DRM encryption. For encrypted playback, see Encrypted playback.

Native RTS playback

The Android Player SDK integrates the Native RTS SDK for ultra-low latency live streaming. Implement RTS stream pulling on Android.

References