All Products
Search
Document Center

ApsaraVideo VOD:Advanced features

Last Updated:Dec 16, 2025

This topic provides usage examples for the advanced features of ApsaraVideo Player SDK for Android. For more information about supported features and their usage, see API reference.

Important

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

Professional Competence Verification

Note

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

You can set a listener when the application starts or before you call any player API operations.

import com.aliyun.private_service.PrivateService;


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

PremiumBizType is an enumeration of Professional Edition features. When you use a related feature, the player verifies the license and returns the result through this callback. If isValid is false, errorMsg contains the reason for the failure.

Playback

List playback

The ApsaraVideo Player SDK for Android provides a comprehensive list playback feature that is ideal for short video feeds. When combined with features such as preloading, it significantly improves the startup speed of short videos.

Procedure

  1. Create the player.

    Create an AliListPlayer instance using the AliPlayerFactory class. The following code is an example:

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

  2. Optional: Set listeners.

    Setting listeners is optional when you create a list player. However, without listeners, you cannot receive event notifications from the player, such as playback failures or playback progress. We recommend that you set listeners, especially important ones such as OnPreparedListener, OnErrorListener, OnCompletionListener, OnLoadingStatusListener, and OnInfoListener.

    Click to view the code

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

    You can set the number of items to preload to improve startup speed. The following code is an example:

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

    List playback supports two types of playback sources: Vid (including VidSts and VidPlayAuth) and UrlSource. The following code is an example:

    • Url: The playback URL can be a third-party VOD URL or a playback URL in ApsaraVideo VOD. You can call the GetPlayInfo operation to obtain the playback URL of a video in ApsaraVideo VOD. We recommend that you integrate the ApsaraVideo VOD server-side SDK to obtain video playback URLs. This method eliminates the need to sign URLs. For more information about how to call the API to obtain a video playback URL, see Developer Portal.

    • Vid: The audio or video ID. You can obtain the ID in the ApsaraVideo VOD console by choosing Media > Audio/Video or by calling a server-side API operation such as SearchMedia after the audio or video is uploaded.

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

    The uid is the unique identifier for a video. If stream crosstalk occurs during playback, check whether the same uid is used for different videos. The uid can be any string.

  5. Set the display view.

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

    • Set SurfaceView. The following code is an example:

      Click to view the code

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

      Click to view the code

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

    After you add one or more playback sources and enable autoplay, you can call moveTo to play a video source. The following code is an example:

    Click to view the code

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

    • After you call moveTo to play a video source, call the moveToPrev and moveToNext API operations to play the previous and next videos, using the video source from the moveTo call as a reference. The following code provides an example:

      Note

      When you use the same view, calling moveto or moveToNext to switch video sources may cause the screen to flicker or go black. In this case, we recommend that you set the mClearFrameWhenStop field of PlayerConfig to false when you initialize listPlayer and call setConfig to apply the setting.

      Click to view the code

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

For a better list playback experience, we recommend that you use our mini-series solution. For more information, see Client-side development for mini-series.

Play videos with transparency

Feature description

The ApsaraVideo Player SDK supports rendering the alpha channel to achieve dynamic effects for transparent gift animations. In scenarios such as live channels, playing transparent gift animations without obscuring the live content significantly enhances the user's viewing and interactive experience.

Limits

The transparent rendering feature is available in All-in-One SDK V6.8.0 and later or ApsaraVideo Player SDK V6.9.0 and later.

Advantages

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

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

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

  3. Higher compatibility: MP4 is a universal video format that is widely supported on various devices and browsers. This ensures that gift effects can be played and viewed on mainstream devices.

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

Code example

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

Note
  • The position of the alpha channel in the video source must be consistent with the parameter set for setAlphaRenderMode.

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

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

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

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

External subtitles

Note

For detailed code examples, see the ExternalSubtitle module in API-Example. This project is a Java-based example project for the ApsaraVideo Player SDK for Android to help you quickly integrate the core features of the SDK.

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

The following code is an example:

  1. Create a view to display subtitles.

    You can create different views for different subtitle formats.

    Click to view the code

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

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

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

    Important

    The subtitle file must be set in onPrepared.

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

    Click to view the 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) {
                }
            }
        );

Audio-only playback

You can disable video playback to play only the audio. You must configure PlayerConfig before you prepare the player.

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

Switch between software and hardware decoding

Note

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

The ApsaraVideo Player SDK for Android provides hardware decoding capabilities for H.264 and H.265. It also provides the enableHardwareDecoder switch. This switch is enabled by default. If hardware decoding fails to initialize, the player automatically switches to software decoding to ensure normal video playback. The following code is an example:

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

If the player automatically switches from hardware to software decoding, a callback is triggered through onInfo. The following code is an example:

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

H.265 adaptive playback

If the current device model is on the cloud-based H.265 blacklist or if hardware decoding of an H.265 stream fails, adaptive fallback occurs. The fallback process is as follows: If an H.264 backup stream is set, the backup stream is automatically played. If no H.264 backup stream is set, the player automatically falls back to H.265 software decoding.

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

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

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

The following code shows how to set a backup stream:

// The application layer maintains a Map that stores all key-value pairs of original URL-backup URL. When switching, the backup URL is queried in the Map based on the original URL.
 AliPlayerGlobalSettings.setAdaptiveDecoderGetBackupURLCallback(new AliPlayerGlobalSettings.OnGetBackupUrlCallback() {
    @Override
    public String getBackupUrlCallback(int oriBizScene, int oriCodecType, String original_url) {
        String kurl = original_url;
        if (!H265toH264Map.get(kurl).isEmpty()) {
            return H265toH264Map.get(kurl);
        } else {
            return "";
        }
    }
});

Adaptively switch video definition based on network conditions

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

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

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

The ApsaraVideo Player SDK for Android supports adaptive bitrate streaming for HLS and DASH video streams. After prepare succeeds, you can call getMediaInfo to obtain information about each bitrate stream in a TrackInfo object. The following code is an example:

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

During playback, you can call the player's selectTrack method to switch the playback bitrate stream. Set the value to AUTO_SELECT_INDEX to enable adaptive bitrate streaming. The following code is an example:

int index = trackInfo.getIndex();
// Switch bitrates.
aliPlayer.selectTrack(index);
// Switch bitrates and adapt.
aliPlayer.selectTrack(TrackInfo.AUTO_SELECT_INDEX);

The result of the switch is returned in a callback after you set the OnTrackChangedListener (before calling selectTrack). The following code is an example:

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

Optional: Before you call the player's selectTrack method to switch the playback stream to adaptive bitrate streaming, you can set a maximum definition for adaptive bitrate (ABR) switching in the configuration. This prevents automatic switching to an unexpected bitrate. The following code is an example: For the setting to take effect, we recommend that you call this code before the player calls the prepare method or the list player calls the moveTo method.

PlayerConfig config = aliPlayer.getConfig();
config.mMaxAllowedAbrVideoPixelNumber = 921600; // Set the upper limit of the pixel count for ABR definition to 921600 (width × height = 1280 × 720), so that the pixel count of the definition that ABR can switch to is less than or equal to this value.
aliPlayer.setConfig(config);

Take snapshots

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

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

Preview

The ApsaraVideo Player SDK for Android, together with ApsaraVideo VOD configurations, implements a preview feature. It supports VidSts and VidAuth (recommended for ApsaraVideo VOD) playback methods. For more information about how to configure and use the preview feature, see Preview videos.

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

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

When the preview duration is set, the server does not return the full video content when playing the video through the ApsaraVideo Player SDK for Android. Instead, it returns only the content for the specified preview duration.

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

  • The preview feature is not currently supported for FLV and MP3 format videos.

Set a blacklist

The ApsaraVideo Player SDK for Android provides a hardware decoding blacklist mechanism. For devices that cannot use hardware decoding for playback, you can directly use software decoding to prevent errors. The following code is an example:

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

The blacklist is automatically cleared after you exit the app.

Set a Referer

The ApsaraVideo Player SDK for Android supports setting a Referer. Together with the blacklist and whitelist Referer settings in the console, this lets you control access permissions. You can use the PlayerConfig method to set the request Referer. The following code shows an example of the player SDK settings:

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

Set a User-Agent

The ApsaraVideo Player SDK for Android lets you use PlayerConfig to set the request User-Agent (UA). After you set it, the player includes the UA information in its requests. The following code is an example:

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

Configure network retry time and count

You can use the PlayerConfig class to set the network timeout and retry count for the ApsaraVideo Player SDK for Android. The following code provides an example:

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

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

  • If NetworkRetryCount is set to 0 and the network connection times out, the player calls the onInfo event. For this event, InfoBean.getCode() returns InfoCode.NetworkRetry. At this point, you can call the player's reload method to reload the network or perform other processing.

Configure cache and latency control

The ApsaraVideo Player SDK for Android provides interfaces for setting cache and latency control through PlayerConfig. The following code is an example:

Click to view the code

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

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

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

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

Set HTTP headers

Using the PlayerConfig method, you can add HTTP header parameters to the player's requests. The following code is an example:

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

Picture-in-Picture (PiP)

Note

For detailed code examples, see the PictureInPicture module in API-Example. This project is a Java-based example project for the ApsaraVideo Player SDK for Android to help you quickly integrate the core features of the SDK.

The procedure is as follows:

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

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

    Triggered by OnClick

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

    Triggered when leaving the app

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

    Triggered when returning to the app

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        // Triggered from back press.
        enterPictureInPictureMode();
    }
  3. Handle the UI for showing and hiding the PiP window.

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

Live RTS fallback

Note

For detailed code examples, see the RtsLiveStream module in API-Example. This project is a Java-based example project for the ApsaraVideo Player SDK for Android to help you quickly integrate the core features of the SDK.

For more information, see RTS live streaming.

Switch between left and right sound channels

The ApsaraVideo Player SDK for Android uses the setOutputAudioChannel method to set the output sound channel. If the input source is dual-channel, you can use the following method to switch to the left or right channel. If the input source is single-channel, this setting has no effect.

Note

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

/*
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_LEFT: Switch to the left channel for playback.
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_RIGHT: Switch to the right channel for playback.
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_NONE: Do not switch channels, keep the input source channel for playback.
*/
aliPlayer.setOutputAudioChannel();

Parse audio streams

You can set a listener to obtain audio and video stream data. The audio and video cannot be encrypted streams because encrypted streams cannot be parsed.

Click to view the code

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

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

Set the video background color

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

API operation example

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

Usage instructions

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

Specify a playback domain name for VidAuth

You can use the VidAuth method to specify fields such as the domain name that corresponds to a VID. For more information about the supported fields, see GetPlayInfo request parameters. The API operation and usage instructions are as follows:

API operation example

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

Usage instructions

You can use the addPlayerConfig method of the VidPlayerConfigGen interface to add the playDomain field.

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

H.266 decoding plug-in

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

Prerequisites

  1. The ApsaraVideo Player SDK or All-in-One SDK is V7.6.0 or later.

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

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

Integrate the plug-in

ApsaraVideo Player SDK

Maven integration (recommended)

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

Note

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

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

Local integration

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

All-in-One SDK

Maven integration

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

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

Activate the plug-in

Note

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

AliPlayerGlobalSettings.enableCodecPlugin("vvc", true);

Related error codes

For error codes related to the H.266 decoding plug-in, see Common FAQ for players on different clients.

Auto-refresh the playback source

Enabling the playback source auto-refresh feature prevents playback interruptions that are caused by authentication expiration. This feature triggers a listener when the source becomes invalid and obtains a new playback address, which ensures continuous and smooth video playback.

Prerequisites

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

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

VidAuth source

API operation example

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

Feature components

Feature components

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

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

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

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

Usage instructions

You can obtain a playback credential by calling the GetVideoPlayAuth API operation. We recommend that you integrate the ApsaraVideo VOD server-side SDK to obtain credentials to avoid self-signing. For more information, see OpenAPI Portal.

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

        // ------------------- Start of user implementation -------------------
        // Call your self-implemented function to obtain a new PlayAuth from the app server.
        // clinetGetPlayAuthFunction is an example function name. Replace it with your own implementation.
        clinetGetPlayAuthFunction(vid, new PlayAuthCallback() {
            
            /**
             * Callback for successfully obtaining a new credential.
             * @param newPlayAuth The new playback credential string obtained from your server.
             */
            @Override
            public void onAuthSuccess(String newPlayAuth) {                
                // 1. Update the old vidAuth object with the new PlayAuth.
                vidAuth.setPlayAuth(newPlayAuth);
                
                // 2. Pass the updated object back to the player through the SDK's callback.
                sourceRefreshCallback.onSuccess(vidAuth);
            }

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

UrlSource source

API operation example

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

Feature components

Feature components

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

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

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

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

Usage instructions

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

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

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

        // 3. Extract the original URL from the expired URL (using Type A signing as an example).
        // Restore the original resource address by removing the URL parameter part (such as "?auth_key=").
        int authKeyIndex = expiredUrl.indexOf("?auth_key=");
        if (authKeyIndex == -1) {
            authKeyIndex = expiredUrl.indexOf("&auth_key=");
        }
        // Ensure safe handling even if auth_key is not found.
        String originalUrl = (authKeyIndex != -1) ? expiredUrl.substring(0, authKeyIndex) : expiredUrl;

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

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

Additional utility functions

The following example uses Type A signing.

Additional utility functions

// Function to generate a signed 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);
    }
}

Performance

Set the playback scenario

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

Note
  • After you set the playback scenario, you can use the getConfig interface to view the parameter configurations.

API operation example

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

Playback scenarios

public enum PlayerScene {
    /**
     * No scene.
     */
    NONE,
    /**
     * Long video scene: applies to videos longer than 30 minutes.
     */
    LONG,
    /**
     * Medium video scene: applies to videos between 5 and 30 minutes.
     */
    MEDIUM,
    /**
     * Short video scene: applies to videos between 0 seconds and 5 minutes.
     */
    SHORT,
    /**
     * Live streaming scene.
     */
    LIVE,
    /**
     * RTS live scene.
     */
    RTS_LIVE
}

Usage instructions

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

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

Note
  1. This feature is disabled by default.

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

The following code is an example:

aliPlayer.setOption(ALLOW_PRE_RENDER, 1);

Local cache

Note

For detailed code examples, see the Preload module in API-Example. This project is a Java-based example project for the ApsaraVideo Player SDK for Android to help you quickly integrate the core features of the SDK.

The ApsaraVideo Player SDK for Android provides a local cache feature. This feature improves startup speed, seek speed, and reduces stuttering when users replay videos, while it also saves traffic.

Enable local cache

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

Click to view the code

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

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

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

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

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

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

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

  • For player SDK versions 5.5.4.0 and later, if the video playback URL has authentication parameters and the playback protocol is HLS, you can set the PlayerConfig.mEnableStrictAuthMode field to select different authentication modes (the default value is false for versions 5.5.4.0 to 6.21.0. The default value is true for versions 7.0.0 and later):

    • Non-strict authentication (false): Authentication is also cached. If only part of the media was cached last time, the player uses the cached authentication to make a request when playing the non-cached part next time. If the validity period of the URL authentication is very short, it causes playback exceptions.

    • Strict authentication (true): Authentication is not cached. Authentication is performed every time playback starts. This causes playback to fail without a network connection.

Enable or disable local cache for a single URL

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

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

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

Preload

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

The limits of the preload feature are as follows:

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

Note

The ApsaraVideo Player SDK for Android provides an automatic network resource scheduling capability for preloading by default. This reduces the impact of preloading network requests on the network requests of the video being played. The automatic scheduling policy works as follows: preloading is allowed to make requests only after the buffer of the currently playing video reaches a certain threshold. To control the real-time requests for preloading yourself, you can disable this policy using the following method:

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

  2. Set the data source.

    VidAuth (recommended)

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

    VidSts

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

    UrlSource

    UrlSource urlSource = new UrlSource();
    urlSource.setUri("Playback URL"); // Required. The playback URL, which can be a third-party VOD URL or a playback URL in ApsaraVideo VOD.
  3. Set task parameters.

    Note

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

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

    Click to view the code

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

    VidAuth (recommended)

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

    VidSts

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

    UrlSource

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

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

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

Dynamic preload

The dynamic preload strategy allows integrators to control both the cache of the currently playing video and the number and cache of preloaded items. This helps businesses balance playback experience with cost.

Click to view the code

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

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

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

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

Preload multi-bitrate HLS videos

In the listPlayer + multi-bitrate HLS video playback scenario, integrators can preload a stream with the same definition as the currently playing video. They can also choose the preload mode based on their business needs.

Click to view supported preload modes

  /**
   * Default mode, plays and preloads the default bitrate of a stream.
   */
  MultiBitratesMode_Default(0),

  /**
   * First frame cost (FC) priority, decreases first frame cost. Only plays the bitrate of the HLS stream which has been preloaded.
   */
  MultiBitratesMode_FCPrio(1),

  /**
   * Balances first frame and play smoothness. The video bitrate is consistent before and after switching (moveToNext), and first frame performance is also considered.
   */
  MultiBitratesMode_FC_AND_SMOOTH(2),

  /**
   * Play smooth priority. The video starts playing at the bitrate of the previous video by default.
   */
  MultiBitratesMode_SmoothPrio(3);

Click to view integration code

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


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


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

Get the download speed

You can obtain the download speed of the currently playing video in the onInfo callback. This is done using the getExtraValue API operation. The following code is an example:

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

Network features

HTTPDNS

HTTPDNS sends domain name resolution requests to a specific HTTPDNS server to obtain faster and more stable domain name resolution results, which reduces the risk of DNS hijacking.

The ApsaraVideo Player SDK provides an enhanced HTTPDNS feature that offers HTTPDNS services specifically for Alibaba Cloud CDN domain names. It supports precise scheduling and real-time resolution for the Alibaba Cloud CDN network, which effectively improves network performance.

Enhanced HTTPDNS example

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

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

HTTP/2

Note

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

The ApsaraVideo Player SDK for Android supports using the HTTP/2 protocol. This protocol improves playback performance through multiplexing, which avoids head-of-line blocking. The following code is an example:

AliPlayerGlobalSettings.setUseHttp2(true);

Pre-establish TCP connections for HTTP

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

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

Video download

Note

For detailed code examples, see the Download module in API-Example. This project is a Java-based example project for the ApsaraVideo Player SDK for Android to help you quickly integrate the core features of the SDK.

The ApsaraVideo Player SDK for Android provides a video download feature for ApsaraVideo VOD. This allows users to cache videos locally to be viewed offline using ApsaraVideo Player. It also offers two download methods: normal download and secure download.

  • Normal download

    The downloaded video data is not encrypted by Alibaba Cloud. Users can play it with a third-party player.

  • Secure download

    The downloaded video data is encrypted by Alibaba Cloud. Third-party players cannot play it. It can be played only using the ApsaraVideo Player.

Instructions

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

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

  • Video download supports resumable downloads.

Procedure

  1. Optional: Configure the encryption file for secure download. This is required only for secure download, not for normal download.

    Note

    Ensure that the configured encryption file is consistent with the app information. Otherwise, the video download fails.

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

    We recommend that you configure this once in the Application class. The following code is an example:

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

    You can create a downloader using AliDownloaderFactory. The following code is an example:

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

    The downloader provides multiple event listeners. The following code is an example:

    Click to view the code

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

    You can use the prepare method to prepare the download source. The download source supports VidSts and VidAuth methods. The following code is an example:

    • VidSts

      // Create VidSts.
      VidSts aliyunVidSts = new VidSts();
      aliyunVidSts.setVid("Vid information"); // The video ID (VideoId).
      aliyunVidSts.setAccessKeyId("<yourAccessKeyId>"); // The AccessKey ID of the temporary STS token, which needs to be generated by calling the AssumeRole API operation of STS.
      aliyunVidSts.setAccessKeySecret("<yourAccessKeySecret>"); // The AccessKey secret of the temporary STS token, which needs to be generated by calling the AssumeRole API operation of STS.
      aliyunVidSts.setSecurityToken("<yourSecurityToken>"); // The STS security token, which needs to be generated by calling the AssumeRole API operation of STS.
      aliyunVidSts.setRegion("Access region"); // The access region of ApsaraVideo VOD, which defaults to cn-shanghai.
       // If you have enabled HLS standard encryption parameter pass-through in the VOD console, and the default parameter name is MtsHlsUriToken, you need to set the config and pass it into the vid, as shown below.
       // If you have not enabled HLS standard 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(config);
              
      
      // Prepare the download source.
      mAliDownloader.prepare(aliyunVidSts)
    • VidAuth

      // Create VidAuth.
      VidAuth vidAuth = new VidAuth();
      vidAuth.setVid("Vid information"); // The video ID (VideoId).
      vidAuth.setPlayAuth("<yourPlayAuth>"); // The playback credential, which needs to be generated by calling the GetVideoPlayAuth API operation of ApsaraVideo VOD.
      vidAuth.setRegion("Access region"); // For player SDK V5.5.5.0 and later, this parameter is deprecated. You do not need to set the region, as the player will automatically parse it. For player SDK versions earlier than 5.5.5.0, this parameter is required. It is the access region of ApsaraVideo VOD, which defaults to cn-shanghai.
      // If you have enabled HLS standard encryption parameter pass-through in the VOD console, and the default parameter name is MtsHlsUriToken, you need to set the config and pass it into the vid, as shown below.
      VidPlayerConfigGen vidConfig = new VidPlayerConfigGen();
      vidConfig.setMtsHlsUriToken("<yourMtsHlsUriToken>");
      vidAuth.setPlayerConfig(config);
      // Prepare the download source.
      mAliDownloader.prepare(vidAuth);
    Note
    • The source file format and the output download file format are the same and cannot be changed.

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

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

    After the preparation is successful, the OnPreparedListener method is called back. The returned TrackInfo object contains information such as the definition of each video stream. You can select a Track to download. The following code is an example:

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

    To prevent VidSts and VidAuth from expiring, you can also update the download source information before you start the download. The following code is an example:

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

    After the download is complete, you can call release in the onCompletion or onError callback to release the downloader. The following code is an example:

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

    During or after the download, you can delete the downloaded files. The following code is an example:

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

What to do next

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

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

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

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

Encrypted video playback

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

Native RTS playback

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

References