All Products
Search
Document Center

ApsaraVideo VOD:Advanced features

Last Updated:Mar 12, 2026

This topic describes the advanced features of ApsaraVideo Player SDK for Android and provides sample code. For more information about other features, see API operations for ApsaraVideo Player SDK for Android.

Important

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

Confirm professional capabilities

Note

Some player features require a Professional Edition license. For details, see ApsaraVideo Player SDK feature overview. To use these features, obtain a license as described in Get a Player SDK license.

Set a listener when your app starts or before you call any player interface:

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 this code, PremiumBizType is an enumeration that represents professional capabilities. The player verifies these capabilities and returns the result through this callback when you use related features. 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 trace ID is the unique identifier of the device or the user. In most cases, the value is the International Mobile Equipment Identity (IMEI) or the Identifier for Advertisers (IDFA) of the device.

  2. Optional. Configure listeners.

    Listeners are optional when you create a short video list player. However, if you do not configure listeners, you cannot receive notifications of events related to the player, such as playback failure or progress. We recommend that you configure the following listeners: OnPreparedListener, OnErrorListener, OnCompletionListener, OnLoadingStatusListener, and OnInfoListener.

    Show code

    aliListPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
        @Override
        public void onCompletion() {
            // Listen for the end of playback.
        }
    });
    aliListPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
        @Override
        public void onError(ErrorInfo errorInfo) {
            // Listen for the occurrence of errors.
        }
    });
    aliListPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
        @Override
        public void onPrepared() {
            // Listen for successful preparation.
        }
    });
    aliListPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(int width, int height) {
            // Listen for the change of video resolution.
        }
    });
    aliListPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() {
        @Override
        public void onRenderingStart() {
            // Listen for the display of the first frame.
        }
    });
    aliListPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
        @Override
        public void onInfo(int type, long extra) {
            // Listen for other events. The type parameter contains multiple values that indicate various events, such as the start of loop playback, buffer position, current playback position, and the start of autoplay.
        }
    });
    aliListPlayer.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
        @Override
        public void onLoadingBegin() {
            // Listen for the start of buffering. 
        }
        @Override
        public void onLoadingProgress(int percent, float kbps) {
            // Listen for the buffering progress.
        }
        @Override
        public void onLoadingEnd() {
            // Listen for the end of buffering.
        }
    });
    aliListPlayer.setOnSeekCompleteListener(new IPlayer.OnSeekCompleteListener() {
        @Override
        public void onSeekComplete() {
            // Listen for the end of seeking.
        }
    });
    aliListPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
        @Override
        public void onSubtitleShow(long id, String data) {
            // Listen for the display of subtitles.
        }
        @Override
        public void onSubtitleHide(long id) {
            // Listen for the hiding of subtitles.
        }
    });
    aliListPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
        @Override
        public void onChangedSuccess(TrackInfo trackInfo) {
            // Listen for the successful switching between audio and video streams or between resolutions.
        }
        @Override
        public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
            // Listen for the failed switching between audio and video streams or between resolutions.
        }
    });
    aliListPlayer.setOnStateChangedListener(new IPlayer.OnStateChangedListener() {
        @Override
        public void onStateChanged(int newState) {
            // Listen for the change of player status.
        }
    });
    aliListPlayer.setOnSnapShotListener(new IPlayer.OnSnapShotListener() {
        @Override
        public void onSnapShot(Bitmap bm, int with, int height) {
            // Listen for the capture of snapshots.
        }
    });
  3. Specify the number of videos to preload.

    You can set the number of videos to be preloaded as needed to reduce startup loading duration. Sample code:

    // Specify the number of videos to preload. The total number of loaded videos is equal to one plus twice the specified number. 
    aliListPlayer.setPreloadCount(int count);
  4. Add or remove multiple playback sources.

    List playback supports video playback based on Vid and UrlSource. You can use VidSts or VidPlayAuth to play videos based on Vid. Url is the playback URL of the video. Sample code:

    • Url: The playback URL can be the URL of an audio or video file in ApsaraVideo VOD or on a third-party video-on-demand (VOD) platform. You can call the GetPlayInfo operation to obtain the playback URL of an audio or video file in ApsaraVideo VOD. We recommend that you use ApsaraVideo VOD SDK to call this operation to avoid complex signature calculation. For more information about the GetPlayInfo operation, visit OpenAPI Explorer.

    • Vid: The audio or video ID. To obtain the ID, log on to the ApsaraVideo VOD console and choose Media Files > Audio/Video in the left navigation pane. Alternatively, you can call 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 playback source.
    aliListPlayer.removeSource(String uid);
    Note

    The uid parameter indicates the unique ID of a video. You can use the unique ID to identify videos. Videos with the same unique ID are considered identical. If the player plays a video that you did not specify, check whether you have assigned the same ID to multiple videos. You can set the unique ID to any string of your choice.

  5. Configure the view.

    SurfaceView and TextureView are supported. Set the UI view to SurfaceView or TextureView.

    • The following sample code describes how to use SurfaceView to configure the view:

      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);
          }
      });
    • The following sample code describes how to use TextureView to configure the view:

      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 play the content from the specified playback source. Sample code:

    Show code

    // Enable autoplay.
    aliListPlayer.setAutoPlay(true);
    
    // Call the following method for URL-based playback.
    aliPlayer.moveTo(String uid);
    // Call the following method for Vid-based playback. You must obtain the Security Token Service (STS) token and AccessKey pair before you call this method. For more information, see Create a RAM role and grant temporary access permissions to the role using STS. 
    aliPlayer.moveTo(String uid, StsInfo info);
  7. Play the previous or next video in the list.

    • After you call moveTo to play a video, you can call moveToPrev to play the previous video or call moveToNext to play the next video. The moveTo video source serves as the anchor point. Sample code:

      Note

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

      Show code

      // Enable autoplay.
      aliListPlayer.setAutoPlay(true);
      
      // Play the next video. You can call this method only for URL-based playback. The method is invalid for Vid-based playback. 
      aliListPlayer.moveToNext();
      // Play the previous video. You can call this method only for URL-based playback. The method is invalid for Vid-based playback. 
      aliListPlayer.moveToPrev();
      // Play the next video. You can call this method only for Vid-based playback. 
      aliListPlayer.moveToNext(StsInfo info);
      // Play the previous video. You can call this method only for Vid-based playback. 
      aliListPlayer.moveToPrev(StsInfo info);
Note

If you want a better experience for list playback, we recommend that you use the mini drama solution. For more information, see Mini drama client development.

Play videos that have transparency configurations

Overview

ApsaraVideo Player SDK supports rendering of videos with alpha channels to play dynamic gift videos with a transparent background. This allows viewers to see dynamic gift effects without blocking live video content during streaming, significantly improving viewing and interactive experience.

Limits

You can use ApsaraVideo MediaBox SDK V6.8.0 or later and ApsaraVideo Player SDK V6.9.0 or later to render videos with transparency.

Benefits

You can use MP4 videos with transparency to play dynamic gift videos with a transparent background. This improves performance, video compatibility, reduces video size, and simplifies development, thereby optimizing the viewing experience of gift effects and enhancing user experience. Using MP4 videos with transparency to play dynamic gift videos offers the following benefits:

  1. Higher video quality: MP4 videos display dynamic gift effects in original quality, including image details and colors. Compared with other formats such as APNG or IXD, MP4 preserves the original quality intended by designers.

  2. Smaller video size: Compared with other formats such as APNG or IXD, MP4 achieves more efficient file size reduction, accelerating loading and reducing network bandwidth consumption.

  3. Better compatibility: MP4 is a widely supported general video format across various devices and browsers, enabling playback of MP4-based gift effects on mainstream devices.

  4. Higher development efficiency: Using MP4 videos as dynamic gifts requires simple development. Developers can focus on implementing other features instead of developing complex parsing and rendering logic, improving development efficiency.

Sample code

The setAlphaRenderMode operation is added. You can call this operation to specify the alpha channel position of the video material—for example, at the top, bottom, left, or right side of the video material. By default, the value is set to None.

Note
  • The alpha channel position of the material must match the position specified when you call the setAlphaRenderMode operation.

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

/**
 * Set the alpha render mode
 *
 * @param alphaRenderMode The alpha render mode. See {@link AlphaRenderMode}.
 */
abstract public void setAlphaRenderMode(AlphaRenderMode alphaRenderMode);
//--------------Configure the view-------------
// Configure a transparent view.
//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); // Display SurfaceView at the top of the window.

//-----------Configure AliPlayer-----------
// Set the alpha mode.
aliPlayer.setAlphaRenderMode(IPlayer.AlphaRenderMode.RENDER_MODE_ALPHA_AT_RIGHT);
// Specify the material that corresponds 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 a connection error occurs when the playback of videos in a player instance is complete, you can clear the view.
        aliPlayer.clearScreen();
    }
}
aliPlayer.setAutoPlay(true);
aliPlayer.prepare();

Configure external subtitles

Note

For detailed code examples, see the API-Example External subtitle playback and switching (ExternalSubtitle) module. This project is an Android example project for ApsaraVideo Player SDK written in Java. It helps developers quickly master core SDK integration.

ApsaraVideo Player SDK for Android lets you add or switch external subtitles in SRT, SSA, ASS, or VTT format for videos.

The following is an example:

  1. Create a view that displays the subtitles.

    You must create different views for subtitles in different formats.

    Show code

    // Create a view that displays subtitles in the SRT or VTT format.
    SubtitleView subtitleView = new SubtitleView(getContext());
    // For Player SDK V7.6.0 or later, we recommend that you use VttSubtitleView to display subtitles in the SRT or VTT format.
    VttSubtitleView vttSubtitleView = new VttSubtitleView(getContext());
    // Create a view that displays subtitles in the ASS or SSA format.
    AssSubtitleView assSubtitleView = new AssSubtitleView(getContext());
    // Add the view that displays subtitles to the layout view.
    viewGroup.addView(assSubtitleView);

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

    // Required for Player SDK 7.6.0 or 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

    You must configure subtitle files in onPrepared.

    mAliPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
        @Override
        public void onPrepared() {
            // Configure subtitles (must be configured in onPrepared)
            mAliPlayer.addExtSubtitle(EXT_SUBTITLE_URL);
        }
    });
  3. Configure listeners for subtitles.

    Show code

    mAliPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
                @Override
                public void onSubtitleExtAdded(int trackIndex, String url) {
                    // trackIndex: the subtitle index; true: display the specified subtitle; false: hide the specified 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 with rendering components)

Based on VttSubtitleView and WebVttResolver, ApsaraVideo Player SDK fully supports WebVTT external subtitles and allows flexible customization of font size, color, and specific fonts.

Note

Use cases:

  • You need to customize WebVTT subtitle styles.

  • You integrate ApsaraVideo Player SDK V7.11.0 or later.

Important

Prerequisites:

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

  • Your project's minSdk is 21 or later (recommended).

  • You have added subtitle listeners and can obtain WebVTT content.

  1. Create CustomStyleWebVttResolver and implement WebVttResolver.

    public class CustomStyleWebVttResolver extends WebVttResolver {
    
        // Implement the constructor
        public CustomStyleWebVttResolver(Context context) {
            super(context);
            // Initialize fonts and other resources here
        }
    }
  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 achieve custom styling effects.
       * This method is called after the parent class parses basic styles, allowing secondary processing of properties such as font size and color.
       *
       * @param spannableStringBuilder Used to build styled text
       * @param vttContentAttribute Style attributes of the current text segment (including font, color, size, etc.)
       * @param start Start position of style application (inclusive)
       * @param end End position of style application (exclusive)
       */
      @Override
      protected void applyTextSpans(SpannableStringBuilder spannableStringBuilder, VttContentAttribute vttContentAttribute, int start, int end) {
          // Save original font size (unit: px) for subsequent adjustment
          // Default font size is 0.0533f times the 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 the parent class method to apply text styles
          super.applyTextSpans(spannableStringBuilder, vttContentAttribute, start, end);
      }
    • Directly manipulate SpannableStringBuilder to modify WebVTT styles directly.

      Important

      This method may cause loss of native WebVTT styles.

      /**
       * Override text style application logic to achieve custom styling effects.
       * This method is called after the parent class parses basic styles, allowing secondary processing of properties such as font size and color.
       *
       * @param spannableStringBuilder Used to build styled text
       * @param vttContentAttribute Style attributes of the current text segment (including font, color, size, etc.)
       * @param start Start position of style application (inclusive)
       * @param end End position of 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 font size
          spannableStringBuilder.setSpan(
              new AbsoluteSizeSpan(20), // Unit: px
              start, end,
              Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
          );
          
          // Set relative font size
          // spannableStringBuilder.setSpan(
          //     new RelativeSizeSpan(2.0f), // Multiple of TextView default font size
          //     start, end,
          //     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
          // );
      }
  3. Configure a custom font (Typeface).

    1. Load the custom font from the asset/fonts/ directory of your project.

      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 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.
          // 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);
          }
      }

      Support for older Android versions: Because TypefaceSpan in Android P (API 28) and earlier does not support direct Typeface objects, you must implement 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 Typeface objects.
      */
      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 font.
            *
            * @param tp TextPaint object used to draw text
            */
          @Override
          public void updateDrawState(TextPaint tp) {
              tp.setTypeface(typeface);
          }
      
          /**
            * Update text measurement state
            * Called during text layout calculation (such as width, line breaks) to ensure measurements match actual drawing.
            *
            * @param p TextPaint object used to measure 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 CustomStyleWebVttResolver
          VttSubtitleView mVttSubtitleView = new VttSubtitleView(context, mResolver);
      
          // Add to video container
          rootView.addView(mVttSubtitleView);
      }
    2. Bind external subtitle callbacks.

      // Configure 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);
              }
          }
      });

Enable audio-only playback

You can disable the display capability for video images to enable audio-only playback. Before you call the prepare method, configure the PlayerConfig class.

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

Switch between software decoding and hardware decoding

Note

You must change the decoding method before playback starts. Changes made during playback do not take effect.

ApsaraVideo Player SDK for Android supports hardware decoding based on the H.264 and H.265 standards. You can call enableHardwareDecoder to enable or disable hardware decoding. By default, hardware decoding is enabled. If hardware decoding fails to initialize, it switches to software decoding to ensure normal playback. Sample code:

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

If hardware decoding switches to software decoding, the onInfo callback is invoked. Sample code:

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 model is in the H.265 model blacklist in the cloud or H.265 streams fail to decode, adaptive streaming is triggered. If you have configured a secondary H.264 stream, the system automatically plays the secondary H.264 stream. If you do not configure a secondary stream, software decoding is automatically used for H.265 playback.

Note
  • This feature is available only after you enable adaptive playback. Adaptive playback is a value-added service. To activate value-added services, submit a request on Yida.

  • The Client-Cloud Integrated Adaptive Decoding value-added service provides the following capabilities: dynamic delivery of compatibility data for cloud-side hardware decoding and adaptive downgrade of H.265 streams to H.264 streams.

  • If you do not activate the adaptive playback service, the player SDK can still automatically use software decoding when hardware decoding fails.

The following sample code describes how to configure a secondary stream:

// Create a map on the application layer to store the primary stream URLs and secondary stream URLs as key-value pairs. The system queries the corresponding secondary URL based on the primary stream URL during switching.
 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

Note
  • You can transcode videos to HTTP Live Streaming (HLS) adaptive bitrate streams using ApsaraVideo VOD transcoding template groups. For more information, see Adaptive bitrate streaming configuration for video on demand.

  • If you use Vid-based playback for adaptive bitrate streams transcoded by ApsaraVideo VOD, you must specify DEFINITION_AUTO as the default playback definition. This allows the player to obtain and play adaptive bitrate streams. If you do not specify AUTO as the default playback definition, the player automatically plays video streams in low definition. For more information about the playback order based on video definitions, see Which video definition does the Player SDK play by default when multiple definitions are available?. The following sample code provides an example on how to specify the default playback definition for VidAuth-based 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 streaming of HLS or DASH video streams. After the prepare method is called, call getMediaInfo to obtain the bitrate information indicated by TrackInfo. Sample code:

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

During playback, you can call the selectTrack method to switch the bitrate. If you specify AUTO_SELECT_INDEX, adaptive bitrate streaming is enabled. Sample code:

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

The switching result is returned in the OnTrackChangedListener callback. You must configure the OnTrackChangedListener callback before you call selectTrack. Sample code:

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 you call the selectTrack method to switch the playback code stream to an adaptive bitrate, you can specify the config parameter to set the maximum definition of adaptive bitrate to avoid automatic switching to an unexpected bitrate. We recommend that you execute the following code before the player calls the prepare method or the list player calls the moveTo method to make it take effect:

PlayerConfig config = aliPlayer.getConfig();
config.mMaxAllowedAbrVideoPixelNumber = 921600; //Set the number of pixels that corresponds to the upper limit of adaptive bitrate to 921,600 (length × width= 1280 × 720). This way, the number of pixels that corresponds to the definition is equal to or smaller than this value.
aliPlayer.setConfig(config);

Capture snapshots

ApsaraVideo Player SDK for Android provides the snapshot method for capturing video snapshots. When you capture a snapshot, the player saves the source data of the video image and converts it to a bitmap. You can then invoke OnSnapShotListener to obtain the bitmap. Sample code:

// Set the callback for snapshot capture.
aliPlayer.setOnSnapShotListener(new OnSnapShotListener(){
    @Override
    public void onSnapShot(Bitmap bm, int with, int height){
        // Obtain the bitmap and the width and height of the video image. 
    }
});
// Capture a snapshot of the current video image.
aliPlayer.snapshot();

Preview

ApsaraVideo Player SDK for Android integrates specific configurations of ApsaraVideo VOD to support video preview. Only VidSts and VidAuth sources can be previewed. We recommend that you preview only VidAuth sources in ApsaraVideo VOD. For more information about how to configure and use the preview feature, see Preview videos.

After you enable the preview feature, you can call the VidPlayerConfigGen.setPreviewTime() method to specify the preview duration. The following sample code provides an example on how to specify the preview duration for VidSts-based playback:

VidSts vidSts = new VidSts;
....
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
configGen.setPreviewTime(20);// Set the preview duration to 20 seconds.
vidSts.setPlayConfig(configGen);// Specify the video source.
...

When you set the trial playback duration and play videos using the Android player SDK, the server returns the trial segment content instead of the complete video content.

Note
  • You can call VidPlayerConfigGen to configure the request parameters supported by the server. For more information, see Request parameter descriptions.

  • The preview feature is not supported for Flash Video (FLV) and MP3 files.

Configure a blacklist

ApsaraVideo Player SDK for Android lets you configure a blacklist for hardware decoding. If hardware decoding is not allowed for a device, you can use software decoding to prevent decoding failures. Sample code:

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

The blacklist becomes invalid after the application exits.

Set the Referer

ApsaraVideo Player SDK for Android provides the PlayerConfig class for setting the request Referer. You can use the Referer together with a Referer whitelist or blacklist configured in the ApsaraVideo VOD console to implement access control. The following sample code provides an example:

// Obtain the configuration information.
PlayerConfig config = aliPlayer.getConfig();
// Set the Referer. Example: http://example.aliyundoc.com. You must add the protocol header when you set the Referer.
config.mReferrer = referrer;
....// Configure other settings.
  // Configure the settings for the player.
aliPlayer.setConfig(config);

Specify the User-Agent header

ApsaraVideo Player SDK for Android provides the PlayerConfig class for specifying the request user agent. After you specify the User-Agent header, the player includes the user agent information in its requests. Sample code:

// Obtain the configuration information.
PlayerConfig config = aliPlayer.getConfig();
// Set the user agent.
config.mUserAgent = "Required user agent";
....// Configure other settings.
  // Configure the settings for the player.
aliPlayer.setConfig(config);

Set the network timeout period and number of retries

ApsaraVideo Player SDK for Android provides the PlayerConfig class for setting the network timeout period and number of retries. Sample code:

// Obtain the configuration information.
PlayerConfig config = aliPlayer.getConfig();
// Specify the network timeout period. Unit: millisecond.
config.mNetworkTimeout = 5000;
// Specify the maximum number of retries upon a network timeout. The retry interval equals the timeout period specified by the NetworkTimeout parameter. The NetworkRetryCount parameter specifies the number of retries. A value of 0 indicates zero retry. The application determines the number of retries. Default value: 2.
config.mNetworkRetryCount=2;
....// Configure other settings.
  // Configure the settings for the player.
aliPlayer.setConfig(config);
Note
  • If you set the NetworkRetryCount parameter to a value other than 0, the player retries playback when it starts to load data due to a network error. The maximum number of retries equals the value of the NetworkRetryCount parameter. The retry interval equals the value of the NetworkTimeout parameter.

  • If loading persists after the maximum number of retries is reached, the onError method invokes a callback. In this case, the ErrorInfo.getCode() method returns ErrorCode.ERROR_LOADING_TIMEOUT.

  • If you set the NetworkRetryCount parameter to 0, the onInfo method invokes a callback when a network timeout occurs. In this case, InfoBean.getCode() returns InfoCode.NetworkRetry. To resolve the issue, you can call the reload method of ApsaraVideo Player SDK for Android to reload network packets or perform other required operations.

Control the buffer and latency

ApsaraVideo Player SDK for Android provides the PlayerConfig class for configuring buffer and latency settings. Sample code:

Show code

// Obtain the configuration information.
PlayerConfig config = aliPlayer.getConfig();
// Set the maximum latency. This parameter is valid only for live streaming. If the latency is excessively high, Player SDK synchronizes frames to ensure that the latency does not exceed the limit. 
config.mMaxDelayTime = 5000;
// Set the maximum buffer duration. Unit: millisecond. This parameter specifies the maximum buffer duration for the player to load data at a time. 
config.mMaxBufferDuration = 50000;
// Set the peak buffer duration. Unit: millisecond. When the network conditions are poor, the player stops loading data after the peak buffer duration elapses. 
config.mHighBufferDuration = 3000;
// Set the startup buffer duration. Unit: millisecond. A smaller value indicates a shorter startup duration. In this case, the player starts to load data soon after the playback starts. 
config.mStartBufferDuration = 500;
....// Configure other settings.
// Set the maximum cache duration. Unit: millisecond. Default value: 0. 
config.mMaxBackwardBufferDurationMs = 0;

// Configure the settings for the player.
aliPlayer.setConfig(config);

Important
  • Ensure that the buffer durations meet the following conditions: mStartBufferDuration ≤ mHighBufferDuration ≤ mMaxBufferDuration.

  • If you set the maximum buffer duration (mMaxBufferDuration) to a value greater than 5 minutes, the system defaults to 5 minutes to prevent memory exceptions caused by an excessive buffer size.

Configure HTTP headers

ApsaraVideo Player SDK for Android provides the PlayerConfig class for adding HTTP headers to requests. Sample code:

// Obtain the configuration information.
PlayerConfig config = aliPlayer.getConfig();
// Define a header.
String[] headers = new String[1];
headers[0]="Host:example.com"; // For example, add the host information to the header. 
// Configure the headers.
config.setCustomHeaders(headers);
....// Configure other settings.
  // Configure the settings for the player.
aliPlayer.setConfig(config);

Picture-in-Picture (PiP)

Note

For detailed code examples, see the API-Example PiP playback (PictureInPicture) module. This project is an Android example project for ApsaraVideo Player SDK written in Java. It helps developers quickly master core SDK integration.

Procedure:

  1. In the AndroidManifest.xml file, declare the PiP permission.

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

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

    You can trigger PiP mode from an OnClick event, when leaving the app, or when returning to the app. Implementation methods are as follows:

    OnClick (click event) trigger

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Rational aspectRatio = new Rational(16, 9); // Aspect ratio for PiP
            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 PiP
        PictureInPictureParams.Builder pipBuilder = new PictureInPictureParams.Builder();
        pipBuilder.setAspectRatio(aspectRatio);
        enterPictureInPictureMode(pipBuilder.build());
    
        Log.e(TAG, "PiP onUserLeaveHint");
    }

    Trigger when returning to the app

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        // Trigger from back press
        enterPictureInPictureMode();
    }
  3. Handle UI for PiP show/hide.

    @Override
    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
        super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
        if (isInPictureInPictureMode) {
            // Handle entering PiP mode
            // Hide UI
            Log.e(TAG, "Entered PiP mode");
        } else {
            // Handle exiting PiP mode
            // Show UI 
            Log.e(TAG, "Exited PiP mode");
        }
    }

Live Streaming RTS Degradation

Note

For detailed code examples, see the API-Example Ultra-low-latency RTS live streaming (RtsLiveStream) module. This project is an Android example project for ApsaraVideo Player SDK written in Java. It helps developers quickly master core SDK integration.

For more information, see RTS live streaming.

Switch between left and right audio channels

ApsaraVideo Player SDK for Android uses the setOutputAudioChannel method to specify the output audio channel. If the input source contains two audio channels, you can switch between the left and right audio channels. If the input source contains only one audio channel, the outputAudioChannel configuration is invalid.

Note

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

/*
Specify OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_LEFT to use the left audio channel for playback.
Specify OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_RIGHT to use the right audio channel for playback.
Specify OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_NONE to use the audio channel settings of the input file.
*/
aliPlayer.setOutputAudioChannel();

Parse audio streams

You can configure a listener to obtain information about audio and video streams. Encrypted audio and video streams cannot be parsed.

Show code

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

// Optional. Return texture_oes_id for RenderFrame after hardware decoding and return the source data for RenderFrame after software decoding.
aliPlayer.enableHardwareDecoder(true);
// Configure a listener to obtain information about audio and video streams.
aliPlayer.setOnRenderFrameCallback(frameInfo -> {
    if (frameInfo.frameType == FrameInfo.FrameType_video) {
        // The video data.
    } else {
        // The audio data.
    }
    return false;
});

Set Video Background Color

You can set the background color of the player when you use ApsaraVideo Player SDK for Android. The following sample code provides examples on how to declare and call the method:

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 Notes

// The parameter value is an eight-digit hexadecimal ARGB color value. The first two digits of an eight-digit ARGB color value represent alpha, the next two represent red, the next two represent green, and the last two represent blue.
// For example, a value of 0x0000ff00 specifies green.
aliPlayer.setVideoBackgroundColor(0x0000ff00);

Specify a domain name for vidAuth-based playback

The vidAuth method lets you specify fields such as the domain name associated with the vid. For details about the supported fields, see GetPlayInfo request parameters. The API and its usage are described below:

API Example

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

Usage notes

Specify the playDomain parameter when you call addPlayerConfig in VidPlayerConfigGen.

vidAuth = new VidAuth();
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
// Add the playDomain field. For more information about configurable fields, see:
// 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 plug-in

H.266 (VVC/Versatile Video Coding), as the latest video coding standard, significantly reduces bitrates while maintaining the same visual quality. To optimize performance and control the main SDK size, the H.266 decoding capability is packaged as a separate plug-in for on-demand integration.

Prerequisites

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

  2. You have obtained a Professional Edition license. For details, see Get a Player SDK license.

  3. ApsaraVideo Player with the H.266 decoding plug-in supports playback of H.266 videos encoded by ApsaraVideo VOD transcoding only.

Integrate the plug-in

Player SDK

Maven integration (recommended)

Add the dependency for the specified plug-in version to the build.gradle file of your app:

Note

For the latest version of ApsaraVideo Player SDK, see Android SDK release history.

// x.x.x must match the Player SDK version number
com.aliyun.sdk.android:AlivcVVCCodec:x.x.x

Local integration

Download the latest version of ApsaraVideo Player SDK and copy the AlivcVVCCodec package to the libs directory of your project (create the libs directory manually if it does not exist). For more information, see Local integration.

All-in-one SDK

Maven integration

Add the dependency for the specified plug-in version to the build.gradle file of your app:

// x.x.x must match the all-in-one SDK version number
com.aliyun.sdk.android:AlivcVVCCodec:x.x.x-aio

Activate the plug-in

Note

Starting from ApsaraVideo Player SDK V7.7.0, the plug-in is enabled by default after integration. No manual activation is required.

AliPlayerGlobalSettings.enableCodecPlugin("vvc", true);

Related error codes

For error codes related to the H.266 decoding plug-in, see Common issues across platforms.

Automatically refresh playback sources

Enabling automatic playback source refresh prevents playback interruptions caused by expired authentication. This feature triggers a listener when a source expires and retrieves a new URL to ensure continuous and smooth video playback.

Prerequisites

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

  2. You use VidAuth sources for playback or have configured URL signing for your business.

VidAuth source

Interface example

/**
 * Set the VidAuth source expiration listener.
 *
 * 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}.
 */
/****
 * 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 composition

Feature composition

/**
 * VidAuth source expiration notification listener, used to handle VidAuth source expiration events.
 */
/****
 * 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}.
     */
    /****
     * 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);
}

/**
 * Playback source refresh callback interface, used to handle 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.
 */
/****
 * 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.
     */
    /****
     * 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.
     */
    /****
     * 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 notes

You can obtain video playback credentials by calling the GetVideoPlayAuth operation. We recommend that you integrate ApsaraVideo VOD server SDK to obtain credentials and avoid self-signing. For more information, see OpenAPI portal.

// 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 starts -------------------
        // Call your own function to obtain a new PlayAuth from your app server.
        // clinetGetPlayAuthFunction is a sample function name. Replace it with your own implementation.
        clinetGetPlayAuthFunction(vid, new PlayAuthCallback() {
            
            /**
             * Callback for successfully obtaining a new credential.
             * @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 for failing to obtain a new credential.
             * @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 URL source expiration listener.
 *
 * 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>
 */
/****
 * 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 composition

Feature composition

/**
 * Playback source refresh callback interface, used to handle 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.
 */
/****
 * 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.
     */
    /****
     * 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.
     */
    /****
     * 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);
}

/**
 * URL source expiration notification listener, used to process expired sources and prevent playback interruptions.
 */
/****
 * 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}.
     */
    /****
     * 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 notes

// Set the URL expiration listener for the player
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)
        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 expiration time for the playback URL (validity period)
        // Use the class member validTime if valid, 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 signing method A as an example)
        // Restore the original resource URL by removing the parameter part (e.g., "?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. Generate a new authenticated URL using the utility class
        String newAuthUrl = CdnAuthUtil.aAuth(originalUrl, authenticationKey, newExpireTime);

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

Utility function supplement

Take signing method A as an example.

Utility function supplement

// Function to generate an authenticated URL
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);
    }
}

// Utility function to calculate MD5
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 network interface controllers (NICs)

ApsaraVideo Player SDK for Android provides the AliPlayerGlobalSettings.enableSwitchNIC method to automatically switch NICs during network anomalies, ensuring stable resource playback. Sample code:

Note

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

AliPlayerGlobalSettings.enableSwitchNIC(true);

Performance

Set the playback scene

Setting the playback scene automatically configures optimal parameters (including buffer settings and feature switches) based on the scene. Custom parameters set through the setConfig interface remain effective (custom settings take precedence).

Note
  • You can view the parameter configuration by calling the getConfig interface after setting the playback scene.

Interface example

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

Playback scenes

public enum PlayerScene {
    /**
     * Scene: none
     */
    /****
     * scene none
     */
    NONE,
    /**
     * Long video scene: applies to videos longer than 30 minutes
     */
    /****
     * long scene: apply to more than 30min
     */
    LONG,
    /**
     * Medium video scene: applies to videos 5 to 30 minutes long
     */
    /****
     * middle scene: apply to 5min-30min
     */
    MEDIUM,
    /**
     * Short video scene: applies to videos up to 5 minutes long
     */
    /****
     * short scene: apply to 0s-5min
     */
    SHORT,
    /**
     * Live streaming scene
     */
    /****
     * live scene
     */
    LIVE,
    /**
     * Ultra-low-latency live streaming scene
     */
    /****
     * RTS live scene
     */
    RTS_LIVE
}

Usage notes

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

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

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

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

Pre-rendering

ApsaraVideo Player SDK for Android supports pre-rendering of the first frame before playback starts. This improves the startup loading duration.

Note
  1. This feature is disabled by default.

  2. You must configure the View before calling Prepare to ensure that the frame is rendered to the View promptly after preparation.

  3. After enabling this feature, the order of triggering the preparation success and first-frame rendering events changes: Without enabling this feature, preparation success is triggered first, followed by first-frame rendering. With this feature enabled, first-frame rendering may be triggered before preparation success due to differences in decoding and rendering speed. This does not affect playback.

The following is an example:

aliPlayer.setOption(ALLOW_PRE_RENDER, 1);

Local cache

Note

For detailed code examples, see the API-Example Video preload (Preload) module. This project is an Android example project for ApsaraVideo Player SDK written in Java. It helps developers quickly master core SDK integration.

ApsaraVideo Player SDK for Android lets you cache videos during playback. This reduces the startup loading time, accelerates the seeking process, reduces playback latency, and reduces traffic consumption during loop playback.

Enable local caching

The local cache feature is disabled by default. To use it, you must manually enable it. This is controlled by enableLocalCache in AliPlayerGlobalSettings. The following is an example:

Show code

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

/**
 *  You can also use the following code to configure caching.
 *  Enable local caching. After this feature is enabled, a media file is cached on your device. 
 *  @param enable: Specifies whether to enable the local caching feature. Valid values: true and false. true indicates that the local caching feature is enabled and false indicates that the local caching feature is disabled. Default value: false. 
 *  @param maxBufferMemoryKB: This parameter is deprecated in V5.4.7.1 or later.
 *  @param localCacheDir: Required. The directory of the cached file, which is an absolute path. 
 *  AliPlayerGlobalSettings.enableLocalCache(enable, maxBufferMemoryKB, localCacheDir);
 */

/**
 * Configure settings for clearing cached files. 
 * @param expireMin - This parameter is deprecated in V5.4.7.1 or later. 
 * @param maxCapacityMB - The maximum size of cached data. Unit: MB. By default, the maximum size of cached data is 20 GB. If the specified maximum size is exceeded, the system deletes cached files based on the time when the file is cached until the size of the cached data is less than or equal to the specified maximum size. During this process, the system preferentially deletes the earliest cache files. 
 * @param freeStorageMB - The minimum free space of the disk. Unit: MB. Default value: 0. If the idle space of the disk is less than the specified minimum space, the system deletes cached files based on the time when the file is cached until the idle space of the disk is greater than or equal to the specified minimum space. During this process, the system preferentially deletes the earliest cache files. 
 * public static void setCacheFileClearConfig(long expireMin,
 *         long maxCapacityMB,
 *         long freeStorageMB)
 */

 /**
  * Configure the callback for the URL hash value of a video file. If you do not configure the callback, the SDK calculates the URL hash value using the MD5 algorithm. 
  * public static void setCacheUrlHashCallback(AliPlayerGlobalSettings.OnGetUrlHashCallback cb)
  */
Note
  • If the playback URL of a video file contains authentication parameters, the values of the authentication parameters change during the local caching and playback of the video file. You can call the setCacheUrlHashCallback operation to calculate the MD5 hash value after you remove the authentication parameters. For example, http://****.mp4?aaa is the playback URL of a video file that contains authentication parameters. In this case, the URL http://****.mp4 is used to calculate the MD5 hash value when the video file is loaded. However, if you calculate the MD5 hash value after you remove the authentication parameters in the key URL of an encrypted M3U8 video, the playback fails because different videos are hit by the same key URL. Solution: Remove the authentication parameters only from the playback URL http(s)://xxxxx.m3u8?aaaa but not the key URL http(s)://yyyyy?bbbb in the setCacheUrlHashCallback callback.进阶功能-本地缓存.png

  • If a server serves the same media files over both HTTP and HTTPS, you can remove the request headers or standardize them before calculating the hash value. For example:

    • If the playback URLs of a video file are https://****.mp4 and http://****.mp4, the MD5 hash value is calculated using ****.mp4 when the video file is loaded.

    • If the playback URL of the video file is https://****.mp4, the MD5 hash value is calculated using the URL http://****.mp4 when the video file is loaded.

  • For ApsaraVideo Player SDK V5.5.4.0 or later, if you want to play an HLS stream whose playback URL contains authentication parameters, configure PlayerConfig.mEnableStrictAuthMode to specify the authentication mode. For older versions, the default value is false. For V7.13.0 or later, the default value is true.

    • false: caches the authentication information. If a video is not completely cached, the player sends a URL signing request using the cached authentication information when you play the uncached video content. If the validity period of the signed URL is short, or if you resume playback after a long pause, authentication may expire. In this case, integrate the automatically refresh playback sources feature to handle authentication expiration.

    • Strict authentication (true): Authentication is not cached and is performed each time playback starts. Without a network connection, playback will fail.

Enable or disable local caching for a single URL

You can enable or disable local caching for a single URL in player config.

// Obtain the configuration information.
PlayerConfig config = aliPlayer.getConfig();
// Configure whether to enable local caching for the playback URL. Default value: true. Local caching for the URL takes effect only when local caching is enabled in AliPlayerGlobalSettings and the value of this parameter is true. If the value of this parameter is false, the local caching for the URL is disabled. 
config.mEnableLocalCache = false;
....// Configure other settings.

// Configure the settings for the player.
aliPlayer.setConfig(config);

Preload

ApsaraVideo Player SDK for Android supports video preload, which is an upgrade of the local caching feature. The video preload feature lets you specify the maximum size of memory that can be occupied by cached videos. This helps reduce the startup loading duration.

It has the following limits:

  • You can preload only one MP4, MP3, FLV, or HLS file at a time.

Note

By default, network resource scheduling is enabled when you use ApsaraVideo Player SDK for Android to preload videos. This ensures the quality of the video that is being played. If network resource scheduling is enabled, the preload request is sent only after the buffered content of the video that is being played reaches a specific limit. You can disable network resource scheduling if you want to manage the real-time preload requests.

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

  2. Configure the data source.

    VidAuth (recommended)

    VidAuth vidAuth = new VidAuth();
    vidAuth.setVid("Vid information");// Required. The ID of the video. 
    vidAuth.setPlayAuth("<yourPlayAuth>");// Required. The playback credential, which is generated by calling GetVideoPlayAuth. 
    vidAuth.setRegion("Access region");// For Player SDK V5.5.5.0 or later, this parameter is deprecated. The player automatically parses the region information. For Player SDK V5.5.5.0 or earlier, this parameter is required. Specify the ID of the region in which ApsaraVideo VOD is activated for this parameter. Default value: cn-shanghai. 
    vidAuth.setQuality("Selected definition") //"AUTO" indicates adaptive bitrate

    VidSts

    VidSts vidSts = new VidSts();
    vidSts.setVid("Vid information");// Required. The ID of the video. vidSts.setAccessKeyId("<yourAccessKeyId>");// Required. The AccessKey ID that is generated when the temporary STS token is issued. To generate the AccessKey ID, call the AssumeRole operation in STS.  vidSts.setAccessKeySecret("<yourAccessKeySecret>");// Required. The AccessKey secret that is generated when the temporary STS token is issued. To generate the AccessKey secret, call the AssumeRole operation in STS.  vidSts.setSecurityToken("<yourSecurityToken>");// Required. The STS token. To obtain the STS token, call the AssumeRole operation in STS.  vidSts.setRegion("Access region");// Required. The region in which ApsaraVideo VOD is activated. Default value: cn-shanghai.
    vidSts.setQuality("Selected definition") //"AUTO" indicates adaptive bitrate

    UrlSource

    UrlSource urlSource = new UrlSource();
    urlSource.setUri("Playback URL");// Required. The playback URL can be the URL of an audio file or video file in ApsaraVideo VOD or on a third-party video-on-demand (VOD) platform.
  3. Configure task parameters.

    Note

    This applies only to multi-bitrate videos. Choose one of setDefaultBandWidth, setDefaultResolution, and setDefaultQuality.

    PreloadConfig preloadConfig = new PreloadConfig();
    // Set the bitrate for multi-bitrate streams
    preloadConfig.setDefaultBandWidth(400000);
    // Set the resolution for multi-bitrate streams
    preloadConfig.setDefaultResolution(640 * 480);
    // Set the quality for multi-bitrate streams
    preloadConfig.setDefaultQuality("FD");
    // Set the 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 failed
        }
    
        @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 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 to save space. ApsaraVideo Player SDK for Android does not provide a method to delete loaded files. You must delete the files in the corresponding directory in your application.

Dynamic preloading

The dynamic preloading feature lets you manage cache of the video that is being played and videos that are preloaded. You can also control the number of videos that are preloaded. This helps maintain a balance between playback experience and cost.

Show code

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

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

// Configure the number of videos to preload. Forward and backward preloading are supported.
// 1 specifies the number of videos to preload forward. 3 specifies the number of videos to preload backward.
aliListPlayer.setPreloadCount(1, 3);

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

You can preload videos in the same definition as the current video stream when you call the listPlayer method during the playback of multi-bitrate HLS videos. You can use different preloading modes as needed.

Expand to view supported preload patterns

  /**
   * The default bitrate for playback and preloading.
   */
  /****
   * default mode, play and preload default bitrate of a stream
   */
  MultiBitratesMode_Default(0),

  /**
   * The preloading mode in which the first frame performance has a higher priority. In this case, the preloaded video is played by default.
   */
  /****
   * First frame cost (FC) priority, decrease first frame cost. only play bitrate of the hls stream which has been preloaded.
   */
  MultiBitratesMode_FCPrio(1),

  /**
   * The preloading mode in which the first frame performance and playback smoothness have the same priority. In this case, the same bitrate is used before and after you call the moveToNext method to switch videos.
   */
  /****
   * First frame and play smooth, play the same bitrate before and after moveToNext
   */
  MultiBitratesMode_FC_AND_SMOOTH(2),

  /**
   * The preloading mode in which the playback smoothness has a higher priority. In this case, the bitrate of the previous video is used by default.
   */
  /****
   * Play Smooth priority, play the same bitrate before and after moveToNext.
   */
  MultiBitratesMode_SmoothPrio(3);

Show integration code

// Specify the multi-bitrate preloading mode.
aliListPlayer.SetMultiBitratesMode(preLoadMode);


// Optional. Set the starting bitrate.
aliListPlayer.setDefaultBandWidth(defaultBandWidth)


// Optional. In the onPrepared callback, specify the abr mode.
aliListPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
    @Override
    public void onPrepared() {
        //abr only effect on multiBitrate m3u8
        aliListPlayer.selectTrack(-1);
    }
});

Obtain the download speed

ApsaraVideo Player SDK for Android provides the getExtraValue method for querying the download speed of specified videos. The onInfo callback is invoked to obtain the query result. Sample code:

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

Network Attributes

HTTPDNS

The HTTPDNS feature uses DNS resolution technology to send domain name resolution requests to a specific HTTPDNS server and obtain resolution results quickly and stably. This prevents DNS hijacking.

ApsaraVideo Player SDK provides HTTPDNS services for domain names accelerated by Alibaba Cloud CDN. You can use the enhanced HTTPDNS feature to implement precise scheduling and ensure that real-time domain resolution results immediately take effect. This improves network performance.

Sample code for using the enhanced HTTPDNS feature

You can use the enhanced HTTPDNS feature only for accelerated domain names. Before you use the feature, make sure that an accelerated domain name is added and configured. For more information about how to add and configure a domain name for CDN in ApsaraVideo VOD, see Add an accelerated domain name. For more information about accelerated domain names, see What is Alibaba Cloud CDN?.

// Enable the enhanced HTTPDNS feature.
AliPlayerGlobalSettings.enableEnhancedHttpDns(true);
// Optional. Add an HTTPDNS pre-resolved domain name.
DomainProcessor.getInstance().addPreResolveDomain("player.***alicdn.com");

HTTP/2

Note

By default, HTTP/2 is enabled for ApsaraVideo Player SDK for Android V5.5.0.0 or later.

ApsaraVideo Player SDK for Android supports HTTP/2. You can enable HTTP/2 to implement request multiplexing. This prevents head-of-line (HOL) blocking and improves playback performance. Sample code:

AliPlayerGlobalSettings.setUseHttp2(true);

Create TCP connections before playback requests are initiated over HTTP

You can create Transmission Control Protocol (TCP) connections before playback requests are initiated over HTTP. This reduces waiting time, ensures the timeliness and consistency of video playback, improves user experience, and optimizes the usage of network and system resources. Sample code:

// Specify the domain parameter in the host[:port] format. Separate multiple domain names with semicolons (;). The port parameter is optional.
// Configure globally.
// Add or delete TCP connections. If you specify an empty string, no TCP connections are created.
AliPlayerGlobalSettings.setOption(AliPlayerGlobalSettings.SET_PRE_CONNECT_DOMAIN, "domain1;domain2");

Video Download

Note

For detailed code examples, see the API-Example Video download and offline playback (Download) module. This project is an Android example project for ApsaraVideo Player SDK written in Java. It helps developers quickly master core SDK integration.

ApsaraVideo Player SDK for Android lets you download videos to local devices for offline playback in ApsaraVideo Player. Normal download mode and secure download mode are supported.

  • Normal download

    Videos downloaded in normal download mode are not encrypted by Alibaba Cloud and can be played using third-party players.

  • Secure download

    Videos downloaded in secure download mode are encrypted by Alibaba Cloud. You cannot use third-party players to play the downloaded videos. You can use only ApsaraVideo Player to play them.

Usage notes

  • You can download only videos played based on VidSts or VidAuth.

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

  • You can resume video downloads.

Procedure

  1. Optional. Configure the security file for encryption verification. You must configure the security file only when you use the secure download mode.

    Note

    Make sure that the information in the security file for encryption verification matches the application information. Otherwise, the video download fails.

    If you use the secure download mode, you must configure the key file generated in the ApsaraVideo VOD console in Player SDK. The key file is used to decrypt and verify the video for download and playback. For more information about how to generate the key file, see the Enable secure download section of the "Configure download settings" topic.

    We recommend that you configure this setting only once in the application. The following example shows how to do so:

    PrivateService.initService(getApplicationContext(),  "The path in which the encryptedApp.dat file is stored"); // We recommend that you store the encryptedApp.dat file on your mobile phone and set this parameter to the path in which the file is stored.
  2. Create and configure a video downloader.

    Create a downloader using AliDownloaderFactory. Sample code:

    AliMediaDownloader mAliDownloader = null;
    ......
    // Create a downloader.
    mAliDownloader = AliDownloaderFactory.create(getApplicationContext());
    // Set the path for storing downloaded files.
    mAliDownloader.setSaveDir("The storage path");
  3. Configure listeners.

    The downloader provides multiple listeners. Sample code:

    Show code

    mAliDownloader.setOnPreparedListener(new AliMediaDownloader.OnPreparedListener() {
       @Override
       public void onPrepared(MediaInfo mediaInfo) {
           // Listen for the preparation of the content to be downloaded.
       }
    });
    mAliDownloader.setOnProgressListener(new AliMediaDownloader.OnProgressListener() {
       @Override
       public void onDownloadingProgress(int percent) {
           // Listen for the percentage of the download progress.
       }
       @Override
       public void onProcessingProgress(int percent) {
           // Listen for the percentage of the processing progress.
       }
    });
    mAliDownloader.setOnErrorListener(new AliMediaDownloader.OnErrorListener() {
       @Override
       public void onError(ErrorInfo errorInfo) {
           // Listen for download errors.
       }
    });
    mAliDownloader.setOnCompletionListener(new AliMediaDownloader.OnCompletionListener() {
       @Override
       public void onCompletion() {
           // Listen for a successful download.
       }
    });
  4. Prepare the download source.

    You can call the prepare method to prepare a download source. VidSts and VidAuth sources are supported. Sample code:

    • VidSts

      // Create a VidSts instance.
      VidSts aliyunVidSts = new VidSts();
      aliyunVidSts.setVid("Vid information"); // The video ID (VideoId).
      aliyunVidSts.setAccessKeyId("<yourAccessKeyId>"); // The AccessKey ID of the temporary STS AccessKey pair. You must generate this by calling the AssumeRole operation of Security Token Service (STS).
      aliyunVidSts.setAccessKeySecret("<yourAccessKeySecret>"); // The AccessKey secret of the temporary STS AccessKey pair. You must generate this by calling the AssumeRole operation of Security Token Service (STS).
      aliyunVidSts.setSecurityToken("<yourSecurityToken>"); // The Security Token Service (STS) token. You must generate this by calling the AssumeRole operation of Security Token Service (STS).
      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 VidPlayerConfigGen and pass it to vid. For more information, see the following example.
      // If you have not enabled HLS encryption parameter pass-through in the VOD console, you do not need to integrate the following code.
      VidPlayerConfigGen vidConfig = new VidPlayerConfigGen();
      vidConfig.setMtsHlsUriToken("<yourMtsHlsUriToken>");
      aliyunVidSts.setPlayerConfig(vidConfig);
      
      // Prepare the download source.
      mAliDownloader.prepare(aliyunVidSts);
    • VidAuth

      // Create the VidAuth download source.
      VidAuth vidAuth = new VidAuth();
      vidAuth.setVid("Video ID"); // The video ID. 
      vidAuth.setPlayAuth("<yourPlayAuth>");// The playback credential, which is generated by calling GetVideoPlayAuth. 
      vidAuth.setRegion("Access region"); // This parameter is deprecated in ApsaraVideo Player SDK V5.5.5.0 or later. If you use ApsaraVideo Player SDK V5.5.5.0 or later, the player automatically parses the region information. If you use ApsaraVideo Player SDK V5.5.5.0 or earlier, this parameter is required. Specify the ID of the region in which ApsaraVideo VOD is activated for this parameter. Default value: cn-shanghai. 
      // If you have enabled parameter pass-through for HLS encryption in the ApsaraVideo VOD console and the default parameter name is MtsHlsUriToken, you need to set the config parameter and pass it to the VID. For more information, see the following code.
      VidPlayerConfigGen vidConfig = new VidPlayerConfigGen();
      vidConfig.setMtsHlsUriToken("<yourMtsHlsUriToken>");
      vidAuth.setPlayerConfig(config);
      // Prepare the download source.
      mAliDownloader.prepare(vidAuth);
    Note
    • The output file and the input file are in the same format and cannot be changed.

    • If you enable parameter pass-through for HLS encryption in the ApsaraVideo VOD console, the default parameter is MtsHIsUriToken. For more information, see Parameter pass-through for HLS encryption. Then, set the MtsHIsUriToken value to the ApsaraVideo VOD source by following the preceding code.

  5. After preparation succeeds, select an item to download and start downloading.

    After preparation succeeds, the OnPreparedListener callback is invoked. The TrackInfo object contains information such as video definitions. Select a track to download. Sample code:

    public void onPrepared(MediaInfo mediaInfo) {
        // Preparation succeeded.
        List<TrackInfo> trackInfos = mediaInfo.getTrackInfos();
        // For example, download the first track.
        mAliDownloader.selectItem(trackInfos.get(0).getIndex());
        // Start downloading.
        mAliDownloader.start();
    }
  6. (Optional) Update the download source.

    VidSts or VidAuth sources may expire before the download. Therefore, we recommend that you update the download source before you start the download. Sample code:

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

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

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

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

    // Delete files through the downloader object.
    mAliDownloader.deleteFile();
    // Delete files through the static method. Returns 0 if successful.
    AliDownloaderFactory.deleteFile("The path of the downloaded folder","Video ID","Video format","Index of the downloaded video");

What to do next

You can play downloaded videos using ApsaraVideo Player. Perform the following steps:

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

    String path = mAliDownloader.getFilePath();
  2. Set the absolute path of the downloaded video file as the URL source for playback.

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

Play encrypted videos

ApsaraVideo Player SDK for Android lets you play on-demand videos encrypted based on HLS encryption, Alibaba Cloud proprietary cryptography, or digital rights management (DRM) encryption. The SDK lets you play live streams encrypted only based on DRM encryption. For more information about how to play encrypted videos, see Play an encrypted video.

Native RTS playback

The Android Player SDK integrates the Native RTS SDK to implement the real-time streaming (RTS) feature natively. For more information, see Implement RTS stream pulling on Android.

References