All Products
Search
Document Center

ApsaraVideo VOD:Advanced features

Last Updated:Feb 11, 2026

This topic describes how to use the advanced features of ApsaraVideo Player SDK for Android and provides code examples. For more information about other features, see API reference.

Important

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

Confirm professional capabilities

Note

Some features of ApsaraVideo Player require a Professional Edition license. For more information, see Features of ApsaraVideo Player SDK. To use these features, obtain a license for the Professional Edition. For more information, see Obtain a license for ApsaraVideo Player SDK.

Set the listener at application startup or before you call 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);
    }
});

In the code, PremiumBizType is an enumeration of professional capabilities. 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 specific reason.

Playback

List playback

ApsaraVideo Player SDK for Android provides a full-fledged list playback feature for videos. The SDK leverages technologies such as preloading to minimize the loading time of short videos.

Procedure

  1. Create a player.

    Create an AliListPlayer instance using the AliPlayerFactory class. Sample code:

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

  2. Optional: Set listeners.

    Listeners are optional when you create a list player. However, if you do not set listeners, you cannot receive notifications of events related to the player, such as playback failures and progress. We recommend that you set listeners. The OnPreparedListener, OnErrorListener, OnCompletionListener, OnLoadingStatusListener, and OnInfoListener listeners are important. We recommend that you set them.

    Show code

    aliListPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
        @Override
        public void onCompletion() {
            // The playback completion event.
        }
    });
    aliListPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
        @Override
        public void onError(ErrorInfo errorInfo) {
            // The error event.
        }
    });
    aliListPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
        @Override
        public void onPrepared() {
            // The preparation success event.
        }
    });
    aliListPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(int width, int height) {
            // The callback for video resolution changes.
        }
    });
    aliListPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() {
        @Override
        public void onRenderingStart() {
            // The event for rendering and displaying the first frame.
        }
    });
    aliListPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
        @Override
        public void onInfo(int type, long extra) {
            // The event for other information. The type includes loop playback start, buffer position, current playback position, and autoplay start.
        }
    });
    aliListPlayer.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
        @Override
        public void onLoadingBegin() {
            // Buffering starts.
        }
        @Override
        public void onLoadingProgress(int percent, float kbps) {
            // The buffering progress.
        }
        @Override
        public void onLoadingEnd() {
            // Buffering ends.
        }
    });
    aliListPlayer.setOnSeekCompleteListener(new IPlayer.OnSeekCompleteListener() {
        @Override
        public void onSeekComplete() {
            // Seeking ends.
        }
    });
    aliListPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
        @Override
        public void onSubtitleShow(long id, String data) {
            // Display subtitles.
        }
        @Override
        public void onSubtitleHide(long id) {
            // Hide subtitles.
        }
    });
    aliListPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
        @Override
        public void onChangedSuccess(TrackInfo trackInfo) {
            // The audio or video stream or the definition is switched.
        }
        @Override
        public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
            // Failed to switch the audio or video stream or the definition.
        }
    });
    aliListPlayer.setOnStateChangedListener(new IPlayer.OnStateChangedListener() {
        @Override
        public void onStateChanged(int newState) {
            // The player state change event.
        }
    });
    aliListPlayer.setOnSnapShotListener(new IPlayer.OnSnapShotListener() {
        @Override
        public void onSnapShot(Bitmap bm, int with, int height) {
            // The snapshot event.
        }
    });
  3. Set the number of videos to preload.

    Set a reasonable number of videos to preload to effectively improve the startup speed. Sample code:

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

    List playback supports two types of playback sources: Vid (including VidSts and VidPlayAuth) and UrlSource. Url is the playback URL of the video. Sample code:

    • Url: The playback URL can be a third-party VOD URL or a playback URL in ApsaraVideo VOD. You can call the GetPlayInfo operation to obtain the playback URL from ApsaraVideo VOD. We recommend that you integrate the ApsaraVideo VOD server-side SDK to obtain playback URLs. This saves you the trouble of signing URLs. For an example of calling the API to obtain a playback URL, see OpenAPI Explorer.

    • Vid: The audio or video ID. You can obtain it after uploading the audio or video file using the ApsaraVideo VOD console (path: Media Files > Audio/Video) or by calling the SearchMedia operation.

    // 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 is the unique identifier of a video. It is used to distinguish between videos. If the uids are the same, the videos are considered the same. If stream mixing occurs during playback, check whether the same uid is set on different interfaces. The uid has no format restrictions and can be any string.

  5. Set the display view.

    The player supports SurfaceView and TextureView. You can choose either one.

    • Set SurfaceView. Sample code:

      Show 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. Sample code:

      Show 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 the video source.

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

    Show code

    // Enable autoplay.
    aliListPlayer.setAutoPlay(true);
    
    // Use this API for URLs.
    aliPlayer.moveTo(String uid);
    // Use this API for VIDs. You need to pass stsInfo, which is the temporary STS credential and AccessKey pair. Obtain it in advance. For more information, see Create a RAM role and grant temporary access permissions using STS.
    aliPlayer.moveTo(String uid, StsInfo info);
  7. Play the previous or next video.

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

      Note

      When you call moveto or moveToNext to switch video sources based on the same view, a flickering black screen may appear. In this case, we recommend that you set the mClearFrameWhenStop field of PlayerConfig to false during listPlayer initialization and call setConfig to apply the setting.

      Show code

      // Enable autoplay.
      aliListPlayer.setAutoPlay(true);
      
      // Move to the next video. Note: This method can only be used for URL sources. It is not applicable for VID playback.
      aliListPlayer.moveToNext();
      // Move to the previous video. Note: This method can only be used for URL sources. It is not applicable for VID playback.
      aliListPlayer.moveToPrev();
      // Move to the next video. Note: This method can only be used for VID playback.
      aliListPlayer.moveToNext(StsInfo info);
      // Move to the previous video. Note: This method can only be used for VID playback.
      aliListPlayer.moveToPrev(StsInfo info);
Note

For a better list playback experience, we recommend using our mini-drama solution. For more information, see Client-side development for mini-dramas.

Play videos with transparency

Feature overview

ApsaraVideo Player SDK supports rendering the alpha channel to play dynamic gift effects with transparency. In scenarios such as live channels, playing dynamic gift effects with transparency does not block the live content, which significantly improves the user's viewing and interactive experience.

Limits

ApsaraVideo MediaBox SDK V6.8.0 or later and ApsaraVideo Player SDK V6.9.0 or later support transparency rendering.

Benefits

Using MP4 videos with transparency information for gift effects provides better animation quality, smaller file sizes, higher compatibility, and higher development efficiency. This allows gift effects to be better displayed to users, improving the user experience.

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

  2. Smaller file size: MP4 video files can be compressed more effectively than other formats such as APNG or IXD. This improves loading speed and reduces network bandwidth consumption.

  3. Higher compatibility: MP4 is a universal video format that is widely supported on various devices and browsers. It supports playing and viewing gift effects on mainstream devices.

  4. Higher development efficiency: The technical solution of using MP4 videos as gift effects is relatively simple. Developers do not need to research and implement complex parsing and rendering logic. They can focus on implementing other features to improve development efficiency.

Sample code

The following API is added: Set the alpha mode (the position of the alpha channel in the video material: top, bottom, left, or right). The default value is None.

Note
  • The position of the alpha channel in the material must be consistent with the setting of the setAlphaRenderMode parameter.

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

/**
 * Sets the alpha rendering mode.
 *
 * @param alphaRenderMode The specified alpha render mode. See {@link AlphaRenderMode}.
 */
abstract public void setAlphaRenderMode(AlphaRenderMode alphaRenderMode);
//--------------View usage-------------
// The View needs to be set to transparent.
//TextureView
TextureView aliplayerView; // The view used for playback.
aliplayerView.setOpaque(false);

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

//-----------AliPlayer usage-----------
// Set the alpha mode.
aliPlayer.setAlphaRenderMode(IPlayer.AlphaRenderMode.RENDER_MODE_ALPHA_AT_RIGHT);
// Set the material corresponding to the alpha mode.
UrlSource urlSource = new UrlSource();
urlSource.setUri("https://alivc-player.oss-cn-shanghai.aliyuncs.com/video/business_requirement_sample/alpha_channel/alpha_right.mp4");
aliPlayer.setDataSource(urlSource);
aliPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
    @Override
    public void onCompletion() {
        // Optional: If there is a connection issue after a single instance playback is complete, you can clear the screen.
        aliPlayer.clearScreen();
    }
}
aliPlayer.setAutoPlay(true);
aliPlayer.prepare();

External subtitles

Note

For detailed code examples, see the External Subtitle Demo and Switching (ExternalSubtitle) module in the API-Example. This Java-based sample project for ApsaraVideo Player SDK for Android helps you quickly integrate the core features of the SDK.

ApsaraVideo Player SDK for Android supports adding and switching external subtitles. It currently supports subtitles in SRT, SSA, ASS, and VTT formats.

The following is an example:

  1. Create a view to display subtitles.

    Create different views for different subtitle formats.

    Show code

    // Used to display 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());
    // Used to display ASS and SSA subtitles.
    AssSubtitleView assSubtitleView = new AssSubtitleView(getContext());
    // Add the subtitle view to the layout view.
    viewGroup.addView(assSubtitleView);

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

    // Required for player V7.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

    The subtitle file needs to be set in onPrepared.

    mAliPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
        @Override
        public void onPrepared() {
            // Subtitle settings (need to be set in onPrepared).
            mAliPlayer.addExtSubtitle(EXT_SUBTITLE_URL);
        }
    });
  3. Set subtitle-related listeners.

    Show code

    mAliPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
                @Override
                public void onSubtitleExtAdded(int trackIndex, String url) {
                    // trackIndex: the subtitle index to pass in; true: display the passed-in subtitle; false: hide the passed-in 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;
                    // Display the subtitle.
                    mSubtitleView.show(subtitle);
                }
    
                @Override
                public void onSubtitleHide(int trackIndex, long id) {
                    // Remove the subtitle.
                    mSubtitleView.dismiss(String.valueOf(id));
                }
    
                @Override
                public void onSubtitleHeader(int trackIndex, String header) {
                }
            }
        );

External subtitles (custom rendering based on rendering components)

Based on VttSubtitleView and WebVttResolver, full support for WebVTT external subtitles is implemented, with flexible customization of font size, color, and specific fonts.

Note

Scenarios:

  • You need to customize WebVTT subtitle styles.

  • You have integrated ApsaraVideo Player SDK V7.11.0 or later.

Important

Prerequisites:

  • The font file (.ttf) has been placed in the assets/fonts/ directory of the project.

  • The project's minSdk is 21 or higher (recommended).

  • A subtitle listener has been added and can retrieve WebVTT content.

  1. Create CustomStyleWebVttResolver and implement WebVttResolver.

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

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

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

      /**
       * Overrides the text style application logic to achieve custom style effects.
       * This method is called after the parent class parses the basic styles, allowing for secondary processing of properties like font size and color.
       *
       * @param spannableStringBuilder Used to build text with styles.
       * @param vttContentAttribute    The style attribute object for the current text segment (contains font, color, size, etc.).
       * @param start                  The starting position for style application (inclusive).
       * @param end                    The ending position for style application (exclusive).
       */
      @Override
      protected void applyTextSpans(SpannableStringBuilder spannableStringBuilder, VttContentAttribute vttContentAttribute, int start, int end) {
          // Settings
          // Save the original font size (in px) for later adjustments.
          // The font size defaults to 0.0533 times the video height.
          double originalFontSizePx = vttContentAttribute.fontSizePx;
      
          // Enlarge the font by 2 times.
          vttContentAttribute.fontSizePx = originalFontSizePx * 2;
          
          // Change the font color to red.
          vttContentAttribute.mPrimaryColour = Color.argb(255, 255, 0, 0);
      
          // Call the parent class's method to apply the text.
          super.applyTextSpans(spannableStringBuilder, vttContentAttribute, start, end);
      }
    • Directly manipulate SpannableStringBuilder to directly modify WebVTT styles.

      Important

      This method may cause the loss of native WebVtt styles.

      /**
       * Overrides the text style application logic to achieve custom style effects.
       * This method is called after the parent class parses the basic styles, allowing for secondary processing of properties like font size and color.
       *
       * @param spannableStringBuilder Used to build text with styles.
       * @param vttContentAttribute    The style attribute object for the current text segment (contains font, color, size, etc.).
       * @param start                  The starting position for style application (inclusive).
       * @param end                    The ending 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), // Multiplier of the TextView's default font size.
          //     start, end,
          //     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
          // );
      }
  3. Set a custom font (Typeface).

    1. Load the custom font from the project's 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 the custom font to the subtitles.

      @Override
      protected void applyTextSpans(SpannableStringBuilder builder, VttContentAttribute attr, int start, int end) {
          // Apply custom font.
          // Must be placed after super.applyTextSpans() to override any font set by the parent class.
          // super.applyTextSpans() does not need to be called.
          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: Because TypefaceSpan on versions below Android P (API 28) does not support directly passing a Typeface object, you need to define a custom MetricAffectingSpan.

      /**
        * Custom Typeface Span class.
        * Inherits from MetricAffectingSpan, correctly applying the Typeface during text drawing and measurement.
        * Solves the issue where the standard TypefaceSpan cannot directly use a Typeface object.
      */
      private static class CustomTypefaceSpan extends MetricAffectingSpan {
      
          // The custom font to apply.
          private final Typeface typeface;
      
          /**
            * Constructor.
            *
            * @param typeface The Typeface object to apply (cannot be null).
            */
          public CustomTypefaceSpan(Typeface typeface) {
              this.typeface = typeface;
          }
      
          /**
            * Updates the text drawing state.
            * Called when the text is actually drawn, setting the paint's font.
            *
            * @param tp The TextPaint object used for drawing text.
            */
          @Override
          public void updateDrawState(TextPaint tp) {
              tp.setTypeface(typeface);
          }
      
          /**
            * Updates the text measurement state.
            * Called when calculating text layout (like width, line breaks), ensuring measurement results match the actual drawing.
            *
            * @param p The TextPaint object used for measuring text.
            */
          @Override
          public void updateMeasureState(TextPaint p) {
              p.setTypeface(typeface);
          }
      }
  4. Integrate into 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 in CustomStyleWebVttResolver.
          VttSubtitleView mVttSubtitleView = new VttSubtitleView(context, mResolver);
      
          // Add to the video container.
          rootView.addView(mVttSubtitleView);
      }
    2. Bind the external subtitle callback.

      // 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

You can disable video playback to achieve an audio-only effect. Configure PlayerConfig before preparing the player.

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

Switch between software and hardware decoding

Note

The decoding method must be switched before playback starts. Switching the decoding method during playback will not take effect.

ApsaraVideo Player SDK for Android provides hardware decoding capabilities for H.264 and H.265, along with a switch provided by enableHardwareDecoder. It is enabled by default. If hardware decoding fails to initialize, it automatically switches to software decoding to ensure normal video playback. Sample code:

// Enable hardware decoding. It is enabled by default.
aliPlayer.enableHardwareDecoder(true);

If the system automatically switches from hardware decoding to software decoding, it triggers the onInfo callback, as shown in the following example.

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

H.265 adaptive playback

If the current device model is in the cloud-based H.265 blacklist or if hardware decoding of an H.265 stream fails, adaptive degradation is triggered. The degradation process is as follows: If an H.264 backup stream is set, it is automatically played. If no H.264 backup stream is set, the player automatically degrades to H.265 software decoding.

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

  • The value-added service for adaptive decoding combined with cloud and client mainly includes: 1. Dynamic delivery of cloud-based hardware decoding compatibility data. 2. Adaptive degradation from H.265 streams to H.264 streams.

  • The SDK still has the ability to automatically switch to software decoding if hardware decoding fails, even if the value-added service is not enabled.

Set a backup stream. Sample code:

// The application layer maintains a Map to store all original URL-backup URL key-value pairs. During a switch, the backup URL is queried 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 "";
        }
    }
});

Adaptive bitrate streaming based on network conditions

Note
  • HLS adaptive bitrate video streams can be generated in ApsaraVideo VOD by transcoding with a video packaging transcoding template group. For more information, see Adaptive bitrate streaming configuration for video on demand.

  • 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 video stream. Otherwise, the player will select a low-definition video stream for playback according to the default logic. For the default playback order of definitions, see If a video is transcoded into multiple definitions, which definition does the player SDK play by default?. The following is an 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);

ApsaraVideo Player SDK for Android supports adaptive bitrate HLS and DASH video streams. After prepare succeeds, you can use getMediaInfo to get information about each bitrate stream, which is TrackInfo. Sample code:

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

During playback, you can switch streams by calling the player's selectTrack method. Setting the track to AUTO_SELECT_INDEX enables adaptive bitrate streaming. For example:

int index = trackInfo.getIndex();
// Switch the bitrate.
aliPlayer.selectTrack(index);
// Enable adaptive bitrate streaming.
aliPlayer.selectTrack(TrackInfo.AUTO_SELECT_INDEX);

The switch result is returned in a callback to OnTrackChangedListener, which you must set before you call selectTrack. The following is an example:

aliPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
    @Override
    public void onChangedSuccess(TrackInfo trackInfo) {
        // The bitrate switching is successful.
    }
    @Override
    public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
        // The bitrate switching fails. You can call the errorInfo.getMsg() method to find the cause of the failure.
    }
});

Optional: Before calling the player's selectTrack method to switch the playback bitrate to adaptive, you can set the upper limit for the ABR switching definition through config to avoid automatically switching to an unexpected bitrate. Sample code: (We recommend calling the following code before the player calls the prepare method or the list player calls the moveTo method for it to take effect.)

PlayerConfig config = aliPlayer.getConfig();
config.mMaxAllowedAbrVideoPixelNumber = 921600; // Set the number of pixels corresponding to the ABR definition upper limit to 921600 (length × width = 1280 × 720), so that the number of pixels for the definition allowed by ABR is less than or equal to this value.
aliPlayer.setConfig(config);

Take a snapshot

ApsaraVideo Player SDK for Android provides a feature to take a snapshot of the current video, implemented by the snapshot API. It captures the raw data and returns it as a bitmap. The callback interface is OnSnapShotListener. Sample code:

// Set the snapshot callback.
aliPlayer.setOnSnapShotListener(new OnSnapShotListener(){
    @Override
    public void onSnapShot(Bitmap bm, int with, int height){
        // The obtained bitmap and the width and height of the image.
    }
});
// Take a snapshot of the current playback frame.
aliPlayer.snapshot();

Preview

ApsaraVideo Player SDK for Android, in conjunction with ApsaraVideo VOD service configurations, can implement a preview feature. It supports both VidSts and VidAuth (recommended for ApsaraVideo VOD) playback methods. For information on how to configure and use the preview feature, see Preview videos.

After configuring the preview feature, use the VidPlayerConfigGen.setPreviewTime() method to set the preview duration for the player. The following is an example for the VidSts playback method:

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

When the preview duration is set, the server will not return the full video content when playing the video through the ApsaraVideo Player SDK for Android. Instead, it will return the content for the preview time period.

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

  • FLV and MP3 format videos do not currently support preview.

Set a blacklist

ApsaraVideo Player SDK for Android provides a hardware decoding blacklist mechanism. For devices that are known to be unable to use hardware decoding for playback, you can directly use software decoding to avoid invalid operations. Sample code:

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

The blacklist automatically becomes invalid after the app is closed.

Set the Referer

ApsaraVideo Player SDK for Android supports setting the Referer. In conjunction with the Referer blacklists and whitelists in the console, you can control access permissions. Use the PlayerConfig method to set the request Referer. The following is an example of the player SDK settings:

// First, get the configuration.
PlayerConfig config = aliPlayer.getConfig();
// Set the referer, for example: http://example.aliyundoc.com. (Note: When setting the referer, you need to include the protocol part at the beginning.)
config.mReferrer = referrer;
....// Other settings
  // Set the configuration for the player.
aliPlayer.setConfig(config);

Set the User-Agent

ApsaraVideo Player SDK for Android provides PlayerConfig to set the request UA. After setting it, the player's requests will include the UA information. Sample code:

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

Configure network retry time and count

You can set the network timeout and retry count for the ApsaraVideo Player SDK for Android using the PlayerConfig method. Sample code:

// First, get the configuration.
PlayerConfig config = aliPlayer.getConfig();
// Set the network timeout, in milliseconds.
config.mNetworkTimeout = 5000;
// Set the number of timeout retries. The interval for each retry is networkTimeout. networkRetryCount=0 means no retries, and the retry policy is determined by the app. The default value is 2.
config.mNetworkRetryCount=2;
....// Other settings
  // Set the configuration for the player.
aliPlayer.setConfig(config);
Note
  • If NetworkRetryCount is set and a network problem occurs, causing a loading state, it will retry NetworkRetryCount times, with each interval being mNetworkTimeout.

  • If it is still in a loading state after multiple retries, the onError event will be called back. At this time, ErrorInfo.getCode()=ErrorCode.ERROR_LOADING_TIMEOUT.

  • If NetworkRetryCount is set to 0, when a network retry times out, the player will call back the onInfo event, and the event's InfoBean.getCode()=InfoCode.NetworkRetry. At this time, you can call the player's reload method to reload the network or perform other actions.

Configure cache and latency control

ApsaraVideo Player SDK for Android provides interfaces to control caching and latency through PlayerConfig. Sample code:

Show code

// First, get the configuration.
PlayerConfig config = aliPlayer.getConfig();
// Maximum delay. Note: This is effective for live streaming. When the delay is large, the player SDK will perform frame synchronization to ensure the player's delay is within this range.
config.mMaxDelayTime = 5000;
// Maximum buffer duration. Unit: ms. The player loads at most this much buffered data at a time.
config.mMaxBufferDuration = 50000;
// High buffer duration. Unit: ms. When data is loading due to a poor network, if the loaded buffer duration reaches this value, the loading state ends.
config.mHighBufferDuration = 3000;
// Start buffer duration. Unit: ms. The shorter this time is set, the faster the playback starts. It may also cause the player to enter a loading state soon after playback begins.
config.mStartBufferDuration = 500;
....// Other settings
// Maximum backward buffer duration. Unit: ms. Default is 0.
config.mMaxBackwardBufferDurationMs = 0;

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

Important
  • The relationship between the three buffer durations must be: mStartBufferDuration ≤ mHighBufferDuration ≤ mMaxBufferDuration.

  • When the maximum buffer duration (mMaxBufferDuration) is greater than 5 minutes, to prevent memory exceptions caused by an overly large buffer, the system will default to 5 minutes.

Set HTTP Header

Using the PlayerConfig method, you can add HTTP header parameters to the player's requests. Sample code:

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

Picture-in-Picture (PiP)

Note

For detailed code examples, see the Picture-in-Picture Playback (PictureInPicture) module in the API-Example. This Java-based sample project for ApsaraVideo Player SDK for Android helps you quickly integrate the core features of the SDK.

The procedure is as follows:

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

    <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); // The aspect ratio of the PiP window, which can be adjusted based on your business needs.
    PictureInPictureParams.Builder pipBuilder = new PictureInPictureParams.Builder();
    pipBuilder.setAspectRatio(aspectRatio);
    enterPictureInPictureMode(pipBuilder.build());

    You can choose to trigger Picture-in-Picture mode from an OnClick event, when leaving the app, or when returning to the app. The implementation is as follows:

    Triggered by OnClick (click event)

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Rational aspectRatio = new Rational(16, 9); // The aspect ratio of the PiP window.
            PictureInPictureParams.Builder pipBuilder = new PictureInPictureParams.Builder();
            pipBuilder.setAspectRatio(aspectRatio);
            enterPictureInPictureMode(pipBuilder.build());
        }
    });

    Triggered when leaving the app

    @Override
    protected void onUserLeaveHint() {
        super.onUserLeaveHint();
        Rational aspectRatio = new Rational(16, 9); // The aspect ratio of the PiP window.
        PictureInPictureParams.Builder pipBuilder = new PictureInPictureParams.Builder();
        pipBuilder.setAspectRatio(aspectRatio);
        enterPictureInPictureMode(pipBuilder.build());
    
        Log.e(TAG, "PiP onUserLeaveHint");
    }

    Triggered when returning to the app

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

    @Override
    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
        super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
        if (isInPictureInPictureMode) {
            // Handling when entering PiP mode.
            // hide UI
            Log.e(TAG, "Entering PiP mode");
        } else {
            // Handling when exiting PiP mode.
            // show UI 
            Log.e(TAG, "Exiting PiP mode");
        }
    }

RTS live streaming degradation

Note

For detailed code examples, see the RTS Ultra-Low Latency Live Streaming (RtsLiveStream) module in the API-Example. This Java-based sample project for ApsaraVideo Player SDK for Android helps you quickly integrate the core features of the SDK.

For more information, see RTS live streaming.

Switch between left and right audio channels

ApsaraVideo Player SDK for Android uses the setOutputAudioChannel method to set the output audio channel. If the input source is dual-channel, you can use the following method to switch to the left or right channel. If the input source is single-channel, the setting is invalid.

Note

The following output audio channel settings affect both audio rendering and PCM data callbacks.

/*
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_LEFT switches to the left channel for playback.
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_RIGHT switches to the right channel for playback.
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_NONE does not switch channels and maintains the input source's channel for playback.
*/
aliPlayer.setOutputAudioChannel();

Parse audio streams

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

Show code

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

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

Set the video background color

ApsaraVideo Player SDK for Android supports setting the background color for player rendering. The API and usage instructions are as follows:

API example

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

Usage instructions

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

Set a specific playback domain name for vidAuth

With the vidAuth method, you can specify fields such as the domain name corresponding to the vid. For details on supported fields, see GetPlayInfo request parameters. The API and usage instructions are as follows:

API example

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

Usage instructions

Add the playDomain field through the addPlayerConfig method of the VidPlayerConfigGen interface.

vidAuth = new VidAuth();
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
// Add the playDomain field. For reference on fields that can be added, see
// https://www.alibabacloud.com/help/en/vod/developer-reference/api-vod-2017-03-21-getplayinfo
configGen.addPlayerConfig("playDomain", "com.xxx.xxx");
vidAuth.setPlayConfig(configGen);

H.266 decoding plug-in

H.266 (VVC/Versatile Video Coding), as the next-generation video encoding standard, can significantly save bitrate at the same image quality. To optimize performance and control the size of the main SDK, the H.266 value-added decoding capability is independently packaged as a plug-in, supporting on-demand integration.

Prerequisites

  1. The player or all-in-one SDK is V7.6.0 or later.

  2. A Professional Edition license has been authorized. For more information, see Obtain a license for ApsaraVideo Player SDK.

  3. ApsaraVideo Player with the H.266 decoding plug-in only supports playing H.266 videos transcoded by Alibaba Cloud Transcoding.

Integrate the plug-in

Player SDK

Maven integration (recommended)

In the app's build.gradle file, add the dependency for the specified version of the plug-in:

Note

For the latest version of ApsaraVideo Player SDK for Android, see Release notes of ApsaraVideo Player SDK for Android.

// x.x.x should be consistent with the player SDK version number.
com.aliyun.sdk.android:AlivcVVCCodec:x.x.x

Local integration

Download the latest version of ApsaraVideo Player SDK for Android, and copy the AlivcVVCCodec package to the project's libs directory (if the libs folder does not exist, create it manually). For details, see Local integration.

All-in-one SDK

Maven integration

In the app's build.gradle file, add the dependency for the specified version of the plug-in:

// x.x.x should be consistent with the all-in-one SDK version number you are using.
com.aliyun.sdk.android:AlivcVVCCodec:x.x.x-aio

Activate the plug-in

Note

Starting from ApsaraVideo Player SDK V7.7.0 for Android, the plug-in is enabled by default after integration and does not need to be manually activated.

AliPlayerGlobalSettings.enableCodecPlugin("vvc", true);

Related error codes

For error codes related to the H.266 decoding plug-in, see Common questions for players on each platform.

Auto-refresh the playback source

Enabling the auto-refresh feature for the playback source prevents playback interruptions caused by expiration under an authentication mechanism. This feature triggers a listener when the source becomes invalid and obtains a new address, ensuring continuous and smooth video playback.

Prerequisites

  1. The player or all-in-one SDK is V7.9.0 or later.

  2. You are using a VidAuth source for playback or your service has configured URL signing.

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}.
 *
 */
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.
     * VidAuth source expiration includes both PlayAuth expiration and playback address expiration.
     *
     * 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

The audio and video playback credential can be obtained through the GetVideoPlayAuth API. We recommend integrating the ApsaraVideo VOD server-side SDK to obtain credentials to avoid self-signing. For details, see the OpenAPI Explorer.

// Set the 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 part starts -------------------
        // Call your own implemented function to get a new PlayAuth from the App server.
        // clinetGetPlayAuthFunction is an example function name, you need to replace it with your own implementation.
        clinetGetPlayAuthFunction(vid, new PlayAuthCallback() {
            
            /**
             * Callback for successfully getting a new credential.
             * @param newPlayAuth The 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. Pass the updated object back to the player through the SDK's callback.
                sourceRefreshCallback.onSuccess(vidAuth);
            }

            /**
             * Callback for failing to get a new credential.
             * @param errorMessage Detailed error message.
             */
            @Override
            public void onAuthError(String errorMessage) {                
                // Pass the error message back to the player through the SDK's callback.
                sourceRefreshCallback.onError(errorMessage);
            }
        });
        // ------------------- User implementation part ends -------------------
    }
});

UrlSource source

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 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 class member variable).
        if (authenticationKey == null || authenticationKey.trim().isEmpty()) {
            Log.e(TAG, "Refresh failed: Authentication key is empty.");
            sourceRefreshCallback.onError("REFRESH_ERROR: Authentication key is missing.");
            return; // Invalid key, exit early.
        }

        // 2. Calculate the timeout (validity period) of the playback address.
        // 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 Type A signing as an example).
        // Restore the original resource address by removing the URL parameter part (like "?auth_key=").
        int authKeyIndex = expiredUrl.indexOf("?auth_key=");
        if (authKeyIndex == -1) {
            authKeyIndex = expiredUrl.indexOf("&auth_key=");
        }
        // Ensure safe handling even if auth_key is not found.
        String originalUrl = (authKeyIndex != -1) ? expiredUrl.substring(0, authKeyIndex) : expiredUrl;

        // 4. Use a utility class to generate a new signed URL.
        String newAuthUrl = CdnAuthUtil.aAuth(originalUrl, authenticationKey, newExpireTime);

        // 5. Check the generated signed URL and return the result via callback.
        if (newAuthUrl != null && !newAuthUrl.isEmpty()) {
            Log.i(TAG, "Refresh success, new URL: " + newAuthUrl);
            // As required by the SDK, create a UrlSource object 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

Take Type A signing as an example.

Supplementary utility functions

// Signed 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 the bound NIC

ApsaraVideo Player SDK for Android provides the AliPlayerGlobalSettings.enableSwitchNIC method, which can automatically switch network interface controllers (NICs) in case of network abnormalities to ensure the stability of resource playback. Sample code:

Note

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

AliPlayerGlobalSettings.enableSwitchNIC(true);

Performance

Set the playback scene

Setting the playback scene automatically configures the optimal parameters (including buffer settings, feature switches, etc.) for that scene. It is also compatible with custom parameter settings made through the setConfig interface (custom settings take precedence).

Note
  • After setting the playback scene, you can view the parameter configuration through the getConfig interface.

API example

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

Playback scenes

public enum PlayerScene {
    /**
     * scene none
     */
    NONE,
    /**
     * long scene: apply to more than 30min
     */
    LONG,
    /**
     * middle scene: apply to 5min-30min
     */
    MEDIUM,
    /**
     * short scene: apply to 0s-5min
     */
    SHORT,
    /**
     * live scene
     */
    LIVE,
    /**
     * RTS live scene
     */
    RTS_LIVE
}

Usage instructions

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

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

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

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

Pre-rendering

ApsaraVideo Player SDK for Android supports quickly rendering the first frame before playback starts, which can improve the startup speed.

Note
  1. This feature is disabled by default.

  2. Enabling this feature affects the trigger order of the preparation success and first frame rendering events. When disabled, the preparation success event is called back before the first frame rendering event. When enabled, due to different decoding and rendering speeds, the first frame rendering event may be triggered before the preparation success event, but this does not affect playback.

For example:

aliPlayer.setOption(ALLOW_PRE_RENDER, 1);

Local cache

Note

For detailed code examples, see the Video Preload (Preload) module in the API-Example. This Java-based sample project for ApsaraVideo Player SDK for Android helps you quickly integrate the core features of the SDK.

ApsaraVideo Player SDK for Android provides a local caching feature that allows users to improve startup speed, seek speed, and reduce stuttering when replaying videos. It also helps save traffic.

Enable local caching

The local caching feature is disabled by default. To use it, you need to enable it manually. Control it through enableLocalCache in AliPlayerGlobalSettings. Sample code:

Show code

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

/**
 *  You can also use the code below for cache settings.
 *  Enable local cache. After enabling, it will cache to local files.
 *  @param enable: Local cache feature switch. true: enable, false: disable, default is disable.
 *  @param maxBufferMemoryKB: Deprecated since V5.4.7.1, no effect.
 *  @param localCacheDir: Must be set. The directory for local cache files, an absolute path.
 *  AliPlayerGlobalSettings.enableLocalCache(enable, maxBufferMemoryKB, localCacheDir);
 */

/**
 * Configuration for clearing local cache files.
 * @param expireMin - Deprecated since V5.4.7.1, no effect.
 * @param maxCapacityMB - Maximum cache capacity. Unit: MB, default is 20 GB. During cleanup, if the total cache size exceeds this, the oldest cache files will be deleted one by one, sorted by last access time, until the size is less than or equal to the maximum capacity.
 * @param freeStorageMB - Minimum free disk space. Unit: MB, default is 0. During cleanup, similar to maxCapacityMB, if the current disk space is less than this value, cache files will be deleted one by one according to the rules until the freeStorage is greater than or equal to this value or all caches are cleared.
 * public static void setCacheFileClearConfig(long expireMin,
 *         long maxCapacityMB,
 *         long freeStorageMB)
 */

 /**
  * Set the callback for the hash value of the loading URL. If not set, the SDK uses the MD5 algorithm.
  * public static void setCacheUrlHashCallback(AliPlayerGlobalSettings.OnGetUrlHashCallback cb)
  */
Note
  • If the video playback URL has authentication parameters, these parameters will change during local caching and playback. To improve the cache hit rate for the same URL with different authentications, you can remove the authentication parameters from the URL before calculating the hash value (for example, MD5) with the setCacheUrlHashCallback interface. For example, if the playback URL with authentication is http://****.mp4?aaa, use http://****.mp4 to calculate the hash value when loading. However, if the video is an encrypted M3U8 video, processing its keyURL by removing authentication parameters before calculating the hash value will cause different videos to hit the same key in the cache, leading to playback failure. Solution: In the setCacheUrlHashCallback callback, you can perform a domain check and only remove authentication parameters for the playback domain (http(s)://xxxxx.m3u8?aaaa), while not removing them for the keyURL's domain (http(s)://yyyyy?bbbb).进阶功能-本地缓存.png

  • If the server supports both HTTP and HTTPS, but different protocols point to the same media file, you can remove or unify the request headers before calculating the hash value. For example:

    • If the video playback URLs are https://****.mp4 and http://****.mp4, use ****.mp4 to calculate the hash value when loading.

    • If the video playback URL is https://****.mp4, unify it to http://****.mp4 before calculating the hash value.

  • For player SDK versions 5.5.4.0 and later, if the video playback URL has authentication parameters and the playback protocol is HLS, you can set the PlayerConfig.mEnableStrictAuthMode field to choose between different authentication modes (the default value is false for older versions; true for V7.13.0 and later):

    • Non-strict authentication (false): Authentication is also cached. If only part of the media was cached last time, the player will use the cached authentication to make a request when playing the non-cached part. If the URL signing has a short validity period, or if playback is resumed after a long pause, the authentication will expire, requiring integration with the auto-refresh playback source feature to handle expired authentication for continued playback.

    • Strict authentication (true): Authentication is not cached. Authentication is performed at the start of each playback, which will cause playback to fail without a network connection.

Enable or disable local caching for a single URL

If you want to enable or disable the local caching feature for a single URL, you can set it in the player config.

// First, get the configuration.
PlayerConfig config = aliPlayer.getConfig();
// Whether to enable local caching for the playback URL. The default value is true. When local caching is enabled in AliPlayerGlobalSettings, and local caching is also enabled here (set to true), local caching for this URL will take effect. If set to false here, local caching for this URL is disabled.
config.mEnableLocalCache = false;
....// Other settings

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

Preload

ApsaraVideo Player SDK for Android provides a preload feature, which is an upgrade to the local caching feature. By setting the memory size for video caching, it can further improve the video startup speed.

The usage limits for the preload feature are as follows:

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

Note

ApsaraVideo Player SDK for Android provides an automatic network resource scheduling capability during preloading by default, to reduce the impact of preload network requests on the network requests of the video being played. The automatic scheduling strategy is: preloading is allowed to make requests only when the buffer of the video being played reaches a certain threshold. To control real-time preload requests yourself, you can disable this strategy with the following method:

AliPlayerGlobalSettings.enableNetworkBalance(false);
  1. Enable the local caching feature. For more information, see Local cache.

  2. Set the data source.

    VidAuth (recommended)

    VidAuth vidAuth = new VidAuth();
    vidAuth.setVid("Vid info");// Required parameter, the video ID (VideoId).
    vidAuth.setPlayAuth("<yourPlayAuth>");// Required parameter, the playback credential, which needs to be generated by calling the GetVideoPlayAuth API of the ApsaraVideo VOD service.
    vidAuth.setRegion("Access region");// For player SDK V5.5.5.0 and later, this parameter is deprecated. You do not need to set the region, as the player will automatically parse it. For player SDK versions before 5.5.5.0, this parameter is required. It is the access region of the ApsaraVideo VOD service, defaulting to cn-shanghai.
    vidAuth.setQuality("Selected definition") //"AUTO" represents adaptive bitrate.

    VidSts

    VidSts vidSts = new VidSts();
    vidSts.setVid("Vid info");// Required parameter, the video ID (VideoId). vidSts.setAccessKeyId("<yourAccessKeyId>");// Required parameter, the AccessKey ID of the temporary STS token pair, which needs to be generated by calling the AssumeRole API of the STS service.  vidSts.setAccessKeySecret("<yourAccessKeySecret>");// Required parameter, the AccessKey secret of the temporary STS token pair, which needs to be generated by calling the AssumeRole API of the STS service.  vidSts.setSecurityToken("<yourSecurityToken>");// Required parameter, the STS security token, which needs to be generated by calling the AssumeRole API of the STS service.  vidSts.setRegion("Access region");// Required parameter, the access region of the ApsaraVideo VOD service, defaulting to cn-shanghai.
    vidSts.setQuality("Selected definition") //"AUTO" represents adaptive bitrate.

    UrlSource

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

    Note

    This applies only to multi-bitrate videos. You can choose any one of setDefaultBandWidth, setDefaultResolution, or setDefaultQuality.

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

    Show code

    /**
     * Preload 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 complete.
        }
    
        @Override
        public void onCanceled(@NonNull String taskId, @NonNull String urlOrVid) {
           // Loading canceled.
        }
    }
  5. Build the task and add it to the MediaLoaderV2 instance to start preloading.

    VidAuth (recommended)

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

    VidSts

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

    UrlSource

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

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

    You can delete loaded files as needed to save space. ApsaraVideo Player SDK for Android does not provide a deletion interface. You need to delete the files in the loading directory within the app.

Dynamic preloading

The dynamic preloading strategy allows integrators to control both the cache of the currently playing video and the number and cache of preloaded videos, meeting the business need to balance playback experience with cost.

Show code

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

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

// Configure the number of preloads, supporting both directions.
// 1 is the number of forward preloads, 3 is the number of backward preloads.
aliListPlayer.setPreloadCount(1, 3);

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

Preloading of multi-bitrate HLS videos

In a listPlayer + multi-bitrate HLS video playback scenario, integrators can preload a stream consistent with the current playback definition and choose a preload mode based on business needs.

Show supported preload modes

  /**
   * default mode, play and preload default bitrate of a stream
   */
  MultiBitratesMode_Default(0),

  /**
   * First frame cost (FC) priority, decrease first frame cost. only play bitrate of the hls stream which has been preloaded.
   */
  MultiBitratesMode_FCPrio(1),

  /**
   * First frame and play smooth, play the same bitrate before and after moveToNext
   */
  MultiBitratesMode_FC_AND_SMOOTH(2),

  /**
   * Play Smooth priority, play the same bitrate before and after moveToNext.
   */
  MultiBitratesMode_SmoothPrio(3);

Show integration code

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


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


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

Get the download speed

Get the download speed of the currently playing video in the onInfo callback, implemented by the getExtraValue API. Sample code:

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 uses DNS resolution technology to send domain name resolution requests to a specific HTTPDNS server to obtain faster and more stable domain name resolution results, reducing the risk of DNS hijacking.

ApsaraVideo Player SDK provides an enhanced HTTPDNS feature, specifically for Alibaba Cloud CDN domain names, supporting precise scheduling and real-time resolution for the Alibaba Cloud CDN network, effectively improving network performance.

Enhanced HTTPDNS usage example

Enhanced HTTPDNS only provides HTTPDNS services for Alibaba Cloud CDN domain names. Ensure that the domain name you configure is an Alibaba Cloud CDN domain name and that the domain name configuration is complete and can be used normally. To add and configure a CDN domain name in ApsaraVideo VOD, see Add an accelerated domain name. For more information about CDN domain names, see Alibaba Cloud CDN.

// Open enhanced HTTPDNS.
AliPlayerGlobalSettings.enableEnhancedHttpDns(true);
// Optional, add an HTTPDNS pre-resolve domain name.
DomainProcessor.getInstance().addPreResolveDomain("player.***alicdn.com");

HTTP/2

Note

ApsaraVideo Player SDK for Android has enabled HTTP/2 by default since version 5.5.0.0.

ApsaraVideo Player SDK for Android supports the HTTP/2 protocol, which uses multiplexing to avoid head-of-line blocking and improve playback performance. Sample code:

AliPlayerGlobalSettings.setUseHttp2(true);

HTTP pre-connect TCP

For HTTP video playback requests (not HTTPS), establishing a TCP connection in advance can significantly improve the user experience, reduce network connection time, ensure the immediacy and continuity of playback, and optimize the use of network and system resources. The usage is as follows:

// The domain format is host[:port], port is optional. Separate multiple domain names with a semicolon (;).
// Global settings
// The full interface uses the current string for each setting (more - add, less - delete). An empty string stops pre-connection.
AliPlayerGlobalSettings.setOption(AliPlayerGlobalSettings.SET_PRE_CONNECT_DOMAIN, "domain1;domain2");

Video download

Note

For detailed code examples, see the Video Download and Offline Playback (Download) module in the API-Example. This Java-based sample project for ApsaraVideo Player SDK for Android helps you quickly integrate the core features of the SDK.

ApsaraVideo Player SDK for Android provides a download feature for ApsaraVideo VOD videos, allowing users to cache videos locally for viewing with ApsaraVideo Player. It offers two download methods: normal download and secure download.

  • Normal download

    Video data downloaded is not encrypted by Alibaba Cloud, and users can play it with third-party players.

  • Secure download

    Video data downloaded is encrypted by Alibaba Cloud. Third-party players cannot play it. It can only be played using Alibaba Cloud's player.

Usage notes

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

  • To use the player's video download feature, you need to enable and configure the download mode in the ApsaraVideo VOD console. For more information, see Offline download.

  • Video download supports resumable downloads.

Procedure

  1. Optional: Configure the encryption verification file for secure download. This is only required for secure download; it is not needed for normal download.

    Note

    Ensure that the configured encryption verification file is consistent with the app information, otherwise the video download will fail.

    If you set the download method to secure download, you need to configure the key file generated in the ApsaraVideo VOD console into the player SDK. This file is used for decryption and verification during video download and playback. For information on generating the key file, see Enable secure download.

    We recommend configuring this once in the Application. Sample code:

    PrivateService.initService(getApplicationContext(),  "File path where encryptedApp.dat is located"); // We recommend storing the encryptedApp.dat encryption verification file on the phone and setting the local file path of the encryption verification file here.
  2. Create and set up the downloader.

    Create a downloader using AliDownloaderFactory. Sample code:

    AliMediaDownloader mAliDownloader = null;
    ......
    // Create the downloader.
    mAliDownloader = AliDownloaderFactory.create(getApplicationContext());
    // Configure the save path for downloads.
    mAliDownloader.setSaveDir("Save folder address");
  3. Set listener events.

    The downloader provides multiple event listeners. Sample code:

    Show 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 the download source.

    Use the prepare method to prepare the download source. The download source supports both VidSts and VidAuth methods. Sample code:

    • VidSts

      // Create a VidSts instance.
      VidSts aliyunVidSts = new VidSts();
      aliyunVidSts.setVid("video ID (VideoId)"); // The video ID (VideoId).
      aliyunVidSts.setAccessKeyId("<yourAccessKeyId>"); // The AccessKey ID of the temporary Security Token Service (STS) AccessKey pair. You must call the AssumeRole operation of STS to generate this value.
      aliyunVidSts.setAccessKeySecret("<yourAccessKeySecret>"); // The AccessKey secret of the temporary Security Token Service (STS) AccessKey pair. You must call the AssumeRole operation of STS to generate this value.
      aliyunVidSts.setSecurityToken("<yourSecurityToken>"); // The Security Token Service (STS) token. You must call the AssumeRole operation of STS to generate this value.
      aliyunVidSts.setRegion("region where the video-on-demand service is deployed"); // The region where the video-on-demand service is deployed. 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 configure the VidPlayerConfigGen object and pass it to the vid parameter. See the following example.
      // If you have not enabled HLS encryption parameter pass-through in the VOD console, you do not need to include 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>");// The playback credential, which needs to be generated by calling the GetVideoPlayAuth API of the ApsaraVideo VOD service.
      vidAuth.setRegion("Access region");// For player SDK V5.5.5.0 and later, this parameter is deprecated. You do not need to set the region, as the player will automatically parse it. For player SDK versions before 5.5.5.0, this parameter is required. It is the access region of the ApsaraVideo VOD service, defaulting to cn-shanghai.
      // If you have enabled HLS standard encryption parameter pass-through in the VOD console, and the default parameter name is MtsHlsUriToken, you need to set the config and pass it into the vid. See below.
      VidPlayerConfigGen vidConfig = new VidPlayerConfigGen();
      vidConfig.setMtsHlsUriToken("<yourMtsHlsUriToken>");
      vidAuth.setPlayerConfig(config);
      // Prepare the download source.
      mAliDownloader.prepare(vidAuth);
    Note
    • The format of the source file and the output download file must be the same and cannot be changed.

    • If you enable HLS standard encryption parameter pass-through in the VOD console, the default parameter name is MtsHIsUriToken. For details, see HLS standard encryption parameter pass-through. Then, set the MtsHIsUriToken value in the VOD source as shown in the code above.

  5. After preparation is successful, select the download item and start downloading.

    After successful preparation, the OnPreparedListener method will be called back. The returned TrackInfo will contain information about each video stream, such as definition. Select a track to download. Sample code:

    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 downloading.
        mAliDownloader.start();
    }
  6. (Optional) Update the download source.

    To prevent VidSts and VidAuth from expiring, you can also update the download source information before starting the download. Sample code:

    // Update the download source.
    mAliDownloader.updateSource(VidSts);
    // Start downloading.
    mAliDownloader.start();
  7. After the download succeeds or fails, release the downloader.

    After the download is successful, call release in the onCompletion or onError callback to release the downloader. Sample code:

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

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

    // Delete the file through the object.
    mAliDownloader.deleteFile();
    // Delete the file through a static method. If successful, it returns 0.
    AliDownloaderFactory.deleteFile("Path of the download folder to be deleted", "Video ID", "Video format", "Index of the downloaded video");

What to do next

The downloaded video can be played using ApsaraVideo Player. The specific method is as follows:

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

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

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

Encrypted video playback

ApsaraVideo VOD supports HLS encryption, Alibaba Cloud proprietary cryptography, and DRM encryption. Live streaming only supports DRM encryption. For encrypted playback, see Encrypted video playback.

Native RTS playback

ApsaraVideo Player SDK for Android integrates the Native RTS SDK to implement native low-latency live streaming. For details, see Implement RTS stream pulling on Android.

References