Advanced features
Use advanced features of the Android Player SDK, including playlist playback, subtitles, video download, and encrypted playback. API reference.
To run the demo, download it and follow the instructions in Run the demo to compile and run the demo.
Professional Edition license verification
Some player features require a Professional Edition license. Check supported features in Player SDK feature details. To use these features, complete authorization as described in Obtain a player SDK license.
Set a listener before the app starts or before calling any player API:
import com.aliyun.private_service.PrivateService;
PrivateService.setOnPremiumLicenseVerifyCallback(new PrivateService.OnPremiumLicenseVerifyCallback() {
@Override
public void onPremiumLicenseVerifyCallback(PrivateService.PremiumBizType type, boolean isValid, String errorMsg) {
Log.d(TAG, "onPremiumLicenseVerifyCallback: " + type + " isValid: " + isValid + " errorMsg: " + errorMsg);
}
});
PremiumBizType enumerates professional features. When you use a related feature, the player verifies the license and returns the result through this callback. If isValid is false, errorMsg contains the reason.
Playback
Playlist playback
The Android Player SDK provides playlist playback with preloading to significantly improve startup speed for short videos.
For a better playlist playback experience, use the short drama solution. Short drama client development.
Playback of videos with transparency
Feature overview
The ApsaraVideo Player SDK supports alpha channel rendering for transparent gift animations. In live streaming scenarios, these animations play without obscuring the live content.
Limits
Integrated SDK version 6.8.0 or later, or Player SDK version 6.9.0 or later, supports transparent rendering.
Benefits
MP4 videos with transparency offer better animation quality, smaller file sizes, higher compatibility, and improved development efficiency compared to APNG or IXD.
-
Better animation quality: MP4 retains original details and colors more accurately than APNG or IXD.
-
Smaller file size: MP4 compresses more efficiently, improving loading speed and reducing bandwidth consumption.
-
Higher compatibility: MP4 is universally supported across devices and browsers.
-
Higher development efficiency: Developers do not need to implement complex parsing and rendering logic.
External subtitles
For detailed code examples, refer to the API-Example External subtitle demonstration and switching (ExternalSubtitle) module. This Java-based example project for the ApsaraVideo Player SDK for Android helps developers quickly master core SDK integration features.
The Android Player SDK supports adding and switching external subtitles in SRT, SSA, ASS, and VTT formats.
-
Create a view to display subtitles.
Create different views based on the subtitle format.
When integrating player V7.6.0 or later and using
VttSubtitleViewto display SRT and VTT subtitles, set the following listener:// Required for player 7.6.0 and later. mAliPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() { @Override public void onVideoSizeChanged(int width, int height) { int viewWidth = getWidth(); int viewHeight = getHeight(); IPlayer.ScaleMode mode = mVideoListPlayer.getScaleMode(); SubTitleBase.VideoDimensions videoDimensions = SubTitleBase.getVideoDimensionsWhenRenderChanged(width, height, viewWidth, viewHeight, mode); vttSubtitleView.setVideoRenderSize(videoDimensions.videoDisplayWidth, videoDimensions.videoDisplayHeight); } }); -
Add subtitles.
ImportantSet subtitle files in the
onPreparedcallback.mAliPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() { @Override public void onPrepared() { // Set subtitles (must be done in onPrepared). mAliPlayer.addExtSubtitle(EXT_SUBTITLE_URL); } }); -
Set subtitle-related listeners.
External subtitles (custom rendering based on rendering components)
Full support for WebVTT external subtitles is implemented using VttSubtitleView and WebVttResolver, allowing flexible customization of subtitle font size, color, and specific fonts.
Applicable scenarios:
-
Customizing WebVTT subtitle styles.
-
Integrating ApsaraVideo Player SDK version 7.11.0 or later.
Prerequisites:
-
Font files (.ttf) are placed in the
assets/fonts/directory of your project. -
Project minSdk ≥ 21 (recommended).
-
Subtitle listeners are added and WebVTT content can be obtained.
-
Create
CustomStyleWebVttResolverand implementWebVttResolver.public class CustomStyleWebVttResolver extends WebVttResolver { // Implement creation method. public CustomStyleWebVttResolver(Context context) { super(context); // Initialize fonts and other resources here later. } } -
Override
applyTextSpansto customize styles.This method is called after the parent class parses basic styles, allowing secondary processing of subtitles.
-
Method 1: Modify
VttContentAttributeand call the parent class method./** * Override text style application logic to implement custom style effects. * This method is called after the parent class parses basic styles, allowing secondary processing of font size, color, and other attributes. * * @param spannableStringBuilder Used to build styled text. * @param vttContentAttribute Style attribute object for the current text segment (includes font, color, size, etc.). * @param start Start position for style application (inclusive). * @param end End position for style application (exclusive). */ @Override protected void applyTextSpans(SpannableStringBuilder spannableStringBuilder, VttContentAttribute vttContentAttribute, int start, int end) { // Set. // Save original font size (in px) for later adjustment. // Default font size is 0.0533f times video height. double originalFontSizePx = vttContentAttribute.fontSizePx; // Double the font size. vttContentAttribute.fontSizePx = originalFontSizePx * 2; // Change font color to red. vttContentAttribute.mPrimaryColour = Color.argb(255, 255, 0, 0); // Call parent class method to apply text. super.applyTextSpans(spannableStringBuilder, vttContentAttribute, start, end); } -
Directly operate
SpannableStringBuilderto modify WebVTT styles directly.ImportantThis method may cause loss of native WebVTT styles.
/** * Override text style application logic to implement custom style effects. * This method is called after the parent class parses basic styles, allowing secondary processing of font size, color, and other attributes. * * @param spannableStringBuilder Used to build styled text. * @param vttContentAttribute Style attribute object for the current text segment (includes font, color, size, etc.). * @param start Start position for style application (inclusive). * @param end End position for style application (exclusive). */ @Override protected void applyTextSpans(SpannableStringBuilder spannableStringBuilder, VttContentAttribute vttContentAttribute, int start, int end) { // Set font color. spannableStringBuilder.setSpan( new ForegroundColorSpan(Color.RED), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); // Set absolute size. spannableStringBuilder.setSpan( new AbsoluteSizeSpan(20), // Unit: px. start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); // Set relative size. // spannableStringBuilder.setSpan( // new RelativeSizeSpan(2.0f), // Multiple of TextView default font size. // start, end, // Spanned.SPAN_EXCLUSIVE_EXCLUSIVE // ); }
-
-
Set custom fonts (Typeface).
-
Load custom fonts from the
asset/fonts/directory.private Typeface mTypeface; public CustomStyleWebVttResolver(Context context) { super(context); initializeFonts(context); } private void initializeFonts(Context context) { try { // Load font from assets/fonts/. mTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/LongCang.ttf"); } catch (Exception e) { Log.e("Font", "Failed to load font", e); mTypeface = Typeface.DEFAULT; // Safe fallback. } } -
Apply custom fonts to subtitles.
@Override protected void applyTextSpans(SpannableStringBuilder builder, VttContentAttribute attr, int start, int end) { // Apply custom font. // Must be placed after super.applyTextSpans() to override fonts possibly set by the parent class. // Calling super.applyTextSpans() is optional. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { builder.setSpan(new TypefaceSpan(mTypeface), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } else { builder.setSpan(new CustomTypefaceSpan(mTypeface), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } }Compatibility with older Android versions: Since
TypefaceSpanin Android P (API 28) and earlier does not support directly passing aTypefaceobject, you need to create a customMetricAffectingSpan./** * Custom Typeface Span class. * Inherits from MetricAffectingSpan to correctly apply Typeface during text drawing and measurement. * Solves the issue where standard TypefaceSpan cannot directly use a Typeface object. */ private static class CustomTypefaceSpan extends MetricAffectingSpan { // Custom font to apply. private final Typeface typeface; /** * Constructor. * * @param typeface Typeface object to apply (must not be null). */ public CustomTypefaceSpan(Typeface typeface) { this.typeface = typeface; } /** * Update text drawing state. * Called during actual text drawing to set the paint's font. * * @param tp TextPaint object used for drawing text. */ @Override public void updateDrawState(TextPaint tp) { tp.setTypeface(typeface); } /** * Update text measurement state. * Called during text layout calculation (e.g., width, line breaks) to ensure measurement matches actual drawing. * * @param p TextPaint object used for measuring text. */ @Override public void updateMeasureState(TextPaint p) { p.setTypeface(typeface); } }
-
-
Integrate with the player.
-
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); } -
Bind external subtitle callbacks.
// Set subtitle listener. mAliPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() { @Override public void onSubtitleExtAdded(int trackIndex, String url) { mAliPlayer.selectExtSubtitle(trackIndex, true); } @Override public void onSubtitleShow(int trackIndex, long id, String data) { if (mVttSubtitleView != null) { // Show subtitle. mVttSubtitleView.show(id, data); } } @Override public void onSubtitleHide(int trackIndex, long id) { // Hide subtitle. mVttSubtitleView.dismiss(id); } @Override public void onSubtitleHeader(int i, String header) { if (!TextUtils.isEmpty(header)) { // Apply WebVTT header styles. mVttSubtitleView.setVttHeader(header); } } });
-
Audio-only playback
Disable video playback to achieve audio-only playback. Configure PlayerConfig before calling prepare.
PlayerConfig config = aliPlayer.getConfig();
config.mDisableVideo = true; // Enable audio-only playback.
aliPlayer.setConfig(config);
Software/hardware decoder switching
Switch the decoding method before playback starts. Switching during playback has no effect.
The Android Player SDK provides H.264 and H.265 hardware decoding with the enableHardwareDecoder switch. Hardware decoding is enabled by default and automatically falls back to software decoding if initialization fails. Example:
// Enable hardware decoding. Enabled by default.
aliPlayer.enableHardwareDecoder(true);
If the player automatically switches from hardware to software decoding, it triggers the onInfo callback. Example:
mApsaraPlayerActivity.setOnInfoListener(new IPlayer.OnInfoListener() {
@Override
public void onInfo(InfoBean infoBean) {
if (infoBean.getCode() == InfoCode.SwitchToSoftwareVideoDecoder) {
// Switched to software decoding.
}
}
});
H.265 adaptive playback
If the device is on the cloud-based H.265 hardware decoding blacklist or H.265 hardware decoding fails, adaptive degradation triggers: if an H.264 backup stream exists, the player uses it; otherwise, it degrades to H.265 software decoding.
-
This feature is enabled only after you activate the client-cloud integrated adaptive decoding value-added service. You need to submit a Yida form to apply for license authorization.
-
The client-cloud integrated adaptive decoding value-added service includes: 1. Dynamic delivery of cloud-based hardware decoding compatibility data; 2. Adaptive degradation of H.265 streams to H.264 streams.
-
The SDK still has the capability to automatically switch to software decoding upon hardware decoding failure, even without activating the value-added service.
Example of setting a backup stream:
// Maintain a Map at the application layer to store key-value pairs of original URLs and backup URLs. When switching, query the backup URL in the Map based on the original URL.
AliPlayerGlobalSettings.setAdaptiveDecoderGetBackupURLCallback(new AliPlayerGlobalSettings.OnGetBackupUrlCallback() {
@Override
public String getBackupUrlCallback(int oriBizScene, int oriCodecType, String original_url) {
String kurl = original_url;
if (!H265toH264Map.get(kurl).isEmpty()) {
return H265toH264Map.get(kurl);
} else {
return "";
}
}
});
Network-adaptive video definition switching
-
HLS adaptive bitrate video streams can be generated through the video packaging and transcoding template group in ApsaraVideo VOD. For detailed operations, see Configure adaptive bitrate for VOD.
-
For adaptive streams generated by ApsaraVideo VOD transcoding, if you use Vid playback, you must specify the default playback definition list as
DEFINITION_AUTOto obtain and play the adaptive video stream. Otherwise, the player selects a low-definition video stream according to the default logic. For the default definition playback order, see Which definition does the player SDK play by default when multiple definitions are transcoded?. Example of specifying the definition list for VidAuth playback:VidAuth vidAuth = new VidAuth(); List<Definition> list = new ArrayList<>(); list.add(Definition.DEFINITION_AUTO); vidAuth.setDefinition(list);
The Android player SDK supports adaptive bitrate HLS and DASH video streams. After prepare succeeds, you can obtain information about each bitrate stream, namely TrackInfo, by calling getMediaInfo. Example:
List<TrackInfo> trackInfos = aliPlayer.getMediaInfo().getTrackInfos();
During playback, you can switch the playing bitrate stream by calling the player's selectTrack method. When the value is AUTO_SELECT_INDEX, it enables adaptive bitrate switching. Example:
int index = trackInfo.getIndex();
// Switch bitrate.
aliPlayer.selectTrack(index);
// Switch bitrate and enable adaptive switching.
aliPlayer.selectTrack(TrackInfo.AUTO_SELECT_INDEX);
The switching result is returned through the OnTrackChangedListener callback (set before calling selectTrack). Example:
aliPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
@Override
public void onChangedSuccess(TrackInfo trackInfo) {
// Switch succeeded.
}
@Override
public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
// Switch failed. Obtain the failure reason from errorInfo.getMsg().
}
});
Optional: Before calling the player's selectTrack method to switch to adaptive bitrate, you can set the upper limit for adaptive bitrate (ABR) switching in config to avoid automatic switching to unexpected bitrates. Example: (We recommend calling the following code before the player calls the prepare method or before the playlist player calls the moveTo method to make it effective.)
PlayerConfig config = aliPlayer.getConfig();
config.mMaxAllowedAbrVideoPixelNumber = 921600; // Set the pixel count upper limit for ABR definition to 921600 (width × height = 1280 × 720), so ABR allows switching to definitions with pixel counts ≤ this value.
aliPlayer.setConfig(config);
Screenshot
The Android player SDK provides a screenshot feature for the current video, implemented by the snapshot interface. It captures the original data and returns it as a bitmap. The callback interface is OnSnapShotListener. Example:
// Set screenshot callback.
aliPlayer.setOnSnapShotListener(new OnSnapShotListener(){
@Override
public void onSnapShot(Bitmap bm, int with, int height){
// Obtain the bitmap and image dimensions.
}
});
// Capture the current playback frame.
aliPlayer.snapshot();
Preview playback
By configuring ApsaraVideo VOD, the Android player SDK can implement preview playback, supporting both VidSts and VidAuth playback methods (VidAuth is recommended for VOD). For configuration and usage instructions, see Preview videos.
After configuring preview playback, set the preview duration for the player using the VidPlayerConfigGen.setPreviewTime() method. Example for VidSts playback:
VidSts vidSts = new VidSts;
....
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
configGen.setPreviewTime(20);// 20-second preview.
vidSts.setPlayConfig(configGen);// Set for playback source.
...
When the preview duration is set, the server returns only the content within the preview period instead of the full video when playing through the Android player SDK.
-
VidPlayerConfigGen supports server request parameters. Request parameter description.
-
FLV and MP3 video formats do not support preview playback.
Set blacklist
The Android player SDK provides a hardware decoding blacklist mechanism. For devices that explicitly cannot use hardware decoding, software decoding is used directly to avoid ineffective operations. Example:
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.model="Lenovo K320t";
AliPlayerFactory.addBlackDevice(BlackType.HW_Decode_H264 ,deviceInfo );
The blacklist is automatically invalidated after the app exits.
Set Referer
Set the request Referer using PlayerConfig. Combined with the Referer blacklist/whitelist in the console, this controls access permissions. Example:
// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Set referer, for example: http://example.aliyundoc.com. (Note: Include the protocol part when setting the referer.)
config.mReferrer = referrer;
....// Other settings.
// Set configuration for the player.
aliPlayer.setConfig(config);
Set UserAgent
Set the request UserAgent using PlayerConfig. The player includes the UA in requests. Example:
// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Set UA.
config.mUserAgent = "UserAgent to set";
....// Other settings.
// Set configuration for the player.
aliPlayer.setConfig(config);
Configure network retry time and count
Set the network timeout and retry count using PlayerConfig. Example:
// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Set network timeout duration, in milliseconds.
config.mNetworkTimeout = 5000;
// Set timeout retry count. The interval between retries is networkTimeout. networkRetryCount=0 means no retry; the retry policy is determined by the app. Default value is 2.
config.mNetworkRetryCount=2;
....// Other settings.
// Set configuration for the player.
aliPlayer.setConfig(config);
-
If NetworkRetryCount is set and a network issue causes loading, the player retries NetworkRetryCount times, with each interval being mNetworkTimeout.
-
If loading status persists after multiple retries, the
onErrorevent is triggered, with ErrorInfo.getCode()=ErrorCode.ERROR_LOADING_TIMEOUT. -
If NetworkRetryCount is set to 0, when network retry times out, the player triggers the
onInfoevent, with InfoBean.getCode()=InfoCode.NetworkRetry. At this point, you can call the player'sreloadmethod to reload the network or handle it otherwise.
Configure cache and latency control
The Android player SDK provides interfaces to control cache and latency through PlayerConfig. Example:
Set HTTP headers
Using the PlayerConfig method, you can add HTTP header parameters to requests in the player. Example:
// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Define headers.
String[] headers = new String[1];
headers[0]="Host:example.com";// For example, set Host in the header.
// Set headers.
config.setCustomHeaders(headers);
....// Other settings.
// Set configuration for the player.
aliPlayer.setConfig(config);
Picture-in-Picture
For detailed code examples, refer to the API-Example Picture-in-Picture playback (PictureInPicture) module. This Java-based example project for the ApsaraVideo Player SDK for Android helps developers quickly master core SDK integration features.
Procedure:
-
In the
AndroidManifest.xmlfile, declare Picture-in-Picture permissions.<activity android:name=".PictureInPictureActivity" android:exported="true" android:supportsPictureInPicture="true" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" /> -
Switch the target
Activityto Picture-in-Picture mode.Rational aspectRatio = new Rational(16, 9); // Aspect ratio for Picture-in-Picture; adjust based on your business needs. PictureInPictureParams.Builder pipBuilder = new PictureInPictureParams.Builder(); pipBuilder.setAspectRatio(aspectRatio); enterPictureInPictureMode(pipBuilder.build());You can trigger Picture-in-Picture mode from OnClick (click event), when leaving the app, or when returning to the app. Implementation methods:
OnClick (click event) trigger
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Rational aspectRatio = new Rational(16, 9); // Aspect ratio for Picture-in-Picture. PictureInPictureParams.Builder pipBuilder = new PictureInPictureParams.Builder(); pipBuilder.setAspectRatio(aspectRatio); enterPictureInPictureMode(pipBuilder.build()); } });Trigger when leaving the app
@Override protected void onUserLeaveHint() { super.onUserLeaveHint(); Rational aspectRatio = new Rational(16, 9); // Aspect ratio for Picture-in-Picture. PictureInPictureParams.Builder pipBuilder = new PictureInPictureParams.Builder(); pipBuilder.setAspectRatio(aspectRatio); enterPictureInPictureMode(pipBuilder.build()); Log.e(TAG, "Picture-in-Picture onUserLeaveHint"); }Trigger when returning to the app
@Override public void onBackPressed() { super.onBackPressed(); // Trigger from back press. enterPictureInPictureMode(); } -
Handle UI for Picture-in-Picture display/disappearance.
@Override public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) { super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig); if (isInPictureInPictureMode) { // Handle entering Picture-in-Picture mode. // hide UI Log.e(TAG, "Entered Picture-in-Picture mode"); } else { // Handle exiting Picture-in-Picture mode. // show UI Log.e(TAG, "Exited Picture-in-Picture mode"); } }
Live RTS degradation
For detailed code examples, refer to the API-Example RTS ultra-low latency live playback (RtsLiveStream) module. This Java-based example project for the ApsaraVideo Player SDK for Android helps developers quickly master core SDK integration features.
Switch left/right audio channels
The Android player SDK provides the setOutputAudioChannel method to set the output audio channel. If the input source is stereo, you can switch to the left or right channel using this method. If the input source is mono, the setting has no effect.
The output audio channel setting affects both audio rendering and PCM data callbacks.
/*
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_LEFT switches to left channel playback,
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_RIGHT switches to right channel playback,
OutputAudioChannel.OUTPUT_AUDIO_CHANNEL_NONE does not switch channels, maintaining the input source channels.
*/
aliPlayer.setOutputAudioChannel();
Parse audio streams
Set a listener to obtain audio and video stream data. The streams must not be encrypted, as encrypted streams cannot be parsed.
Set video background color
The Android player SDK supports setting the background color for player rendering. Interface and usage instructions:
Interface example
/**
* Set video background color.
*
* @param color ARGB
*/
abstract public void setVideoBackgroundColor(int color);
Usage instructions
// Parameter is an 8-digit hexadecimal value. Each pair of digits represents A (alpha transparency), R (red), G (green), B (blue) in order.
// For example, 0x0000ff00 represents green.
aliPlayer.setVideoBackgroundColor(0x0000ff00);
vidAuthSet specified playback domain
Using vidAuth, you can specify fields such as the domain for the vid. For supported fields, see GetPlayInfo request parameters. Interface and usage instructions:
Interface example
/**
* Set playback parameters.
*
* @param playConfig Playback parameters.
*/
public void setPlayConfig(VidPlayerConfigGen playConfig);
Usage instructions
Use the addPlayerConfig method of VidPlayerConfigGen to add the playDomain field.
vidAuth = new VidAuth();
VidPlayerConfigGen configGen = new VidPlayerConfigGen();
// Add playDomain field. For other fields you can add, refer to
//https://www.alibabacloud.com/help/zh/vod/developer-reference/api-vod-2017-03-21-getplayinfo
configGen.addPlayerConfig("playDomain", "com.xxx.xxx");
vidAuth.setPlayConfig(configGen);
H.266 decoding plugin
H.266 (VVC/Versatile Video Coding) is a next-generation video coding standard that significantly reduces bitrate at equivalent quality. The H.266 decoding capability is independently packaged as a plugin for on-demand integration.
Prerequisites
-
Player/integrated SDK version V7.6.0 or later.
-
Professional Edition license authorization completed. Obtain a player SDK license.
-
ApsaraVideo Player with the H.266 decoding plugin supports only H.266 videos transcoded by ApsaraVideo VOD audio and video transcoding.
Integrate plugin
Activate plugin
Starting from Android player SDK 7.7.0, the plugin is enabled by default after integration and does not require manual activation.
AliPlayerGlobalSettings.enableCodecPlugin("vvc", true);
Related error codes
For H.266 decoding plugin error codes, see Common issues for players on all platforms.
Auto-refresh playback sources
Enabling auto-refresh for playback sources prevents playback interruptions caused by source expiration under authentication mechanisms.
Prerequisites
-
Player/integrated SDK version V7.9.0 or later.
-
Using VidAuth source for playback or your business has configured URL signing.
VidAuth source
Interface example
/**
* Set the listener for VidAuth source expiration events.
*
* This feature enables automated VidAuth source refresh to avoid playback interruptions
* caused by expiration. When the listener is triggered, you can refresh the VidAuth source
* and return the updated VidAuth using {@link SourceRefreshCallback#onSuccess}.
*
* @param listener The interface for listening to VidAuth source expiration events. See {@link OnVidAuthExpiredListener}.
*/
abstract public void setOnVidAuthExpiredListener(OnVidAuthExpiredListener listener);
Feature components
UrlSource source
Interface example
/**
* Set the listener for URL source expiration events.
*
* This feature enables URL refresh to avoid playback interruptions caused by
* URL expiration due to authentication. When the listener is triggered,
* you can refresh the URL source and return the updated URL source using {@link SourceRefreshCallback#onSuccess}.
*
* @param listener Listener for handling URL source expiration events. See {@link OnURLSourceExpiredListener}.
*
* <p>For more information on configuring URL authentication, see
* <a href="https://www.alibabacloud.com/help/zh/vod/user-guide/configure-url-signing?spm=a2c4g.11186623.0.0.560c4140fGh8MW">URL authentication documentation</a>.</p>
*/
abstract public void setOnURLSourceExpiredListener(OnURLSourceExpiredListener listener);
Feature components
Supplementary utility functions
Using authentication type A as an example.
Switch bound NIC
The Android player SDK provides the AliPlayerGlobalSettings.enableSwitchNIC method to automatically switch NICs during network anomalies, ensuring stable resource playback. Example:
This takes effect only when the switch is enabled and multiple NICs exist.
AliPlayerGlobalSettings.enableSwitchNIC(true);
Audio enhancement
The Android player SDK provides an audio enhancement plugin to improve audio playback experience, featuring volume normalization, voice enhancement, and surround sound.
Feature introduction
-
Volume normalization: Automatically adjusts all audio content to a consistent volume level, significantly improving playback experience for videos with excessively low or high original volume.
-
Supported channels: Mono / Stereo / 5.1 / 7.1.
-
Supported sample rates: 16kHz / 44.1kHz / 48kHz.
-
-
Voice enhancement: Intelligently enhances dialogue while preserving original timbre, making voices clearer and brighter in noisy scenes.
-
Supported channels: Stereo.
-
Supported sample rates: 44.1kHz / 48kHz.
-
-
Surround sound: Applies virtual surround rendering to multi-channel and stereo videos, providing an immersive experience on headphones or standard devices. Includes 3DSurround (stereo surround) and MegaBass (super bass) modes.
-
Supported channels: Mono / Stereo / 5.1 / 7.1.
-
Supported sample rates: 44.1kHz / 48kHz.
-
Prerequisites
-
Player/integrated SDK version V7.13.0 or later.
-
Professional Edition License authorization obtained. Obtain a player SDK license.
Audio source support for audio enhancement:
-
VOD streams: Must use ApsaraVideo VOD audio and video transcoding.
-
Live streams: Supports any source.
Integrate plugin
Maven integration (recommended)
Add the dependency for the specified plugin version in your app's build.gradle file:
For the latest Android player SDK versions, see Android SDK release history.
// x.x.x matches the player SDK version number.
implementation 'com.aliyun.sdk.android:AlivcAudioEnhanceFilter:x.x.x'
Local integration
Download the latest Android player SDK and copy the AlivcAudioEnhanceFilter package to your project's libs directory (create it manually if it doesn't exist). For details, see Local integration.
Feature interfaces
setFilterValid
Controls the master switch for audio enhancement. The target name for the audio enhancement filter is audioEnhance. When disabled, all three sub-features are inactive (disabled by default).
player.setFilterValid("audioEnhance", true); // Enable.
player.setFilterValid("audioEnhance", false); // Disable.
setFilterConfig
Set FilterConfig before prepare. It takes effect after playback starts.
FilterConfig filterConfig = new FilterConfig();
FilterConfig.Filter filterItem = new FilterConfig.Filter("audioEnhance");
FilterConfig.FilterOptions opts = new FilterConfig.FilterOptions();
// Surround sound.
opts.setOption("enable_surround", true);
opts.setOption("surround_effect_type", "3DSurround"); // Type must be set together with enable_surround on first use.
// Voice enhancement.
opts.setOption("enable_dialoguenhance", true);
opts.setOption("dialoguenhance_voice", 1.0f); // 1.0 ~ 10.0. Voice must be set together with enable_dialoguenhance on first use.
// Volume normalization.
opts.setOption("enable_normalizer", true);
filterItem.setOptions(opts);
filterConfig.addFilter(filterItem);
player.setFilterConfig(filterConfig);
|
Parameter |
Type |
Description |
|
|
Boolean |
Surround sound feature switch. |
|
|
String |
Surround sound type: |
|
|
Boolean |
Voice enhancement feature switch. |
|
|
Float |
Voice enhancement strength, range 1.0 ~ 10.0. |
|
|
Boolean |
Volume normalization feature switch. |
updateFilterConfig
During or after player preparation, to dynamically adjust parameters, call this interface to update them.
Calling updateFilterConfig before prepare has no effect. Use setFilterConfig for initial configuration.
AVPFilterOptions *opts = [[AVPFilterOptions alloc] init];
[opts setOptions:@"enable_surround" value:@YES];
[opts setOptions:@"surround_effect_type" value:@"3DSurround"]; // If not the first time enabling surround, this Type setting is invalid because initialization is already complete.
[player updateFilterConfig:@"audioEnhance" options:opts];
Surround sound type ("3DSurround" / "MegaBass") and voice enhancement strength (dialoguenhance_voice) must be set together with the enable attribute on first use. Otherwise, default values are used for initialization (surround sound defaults to "3DSurround", voice strength defaults to 1.0), and they cannot be modified during playback.
Performance
Set playback scenario
Setting the playback scenario automatically configures optimal parameters (including buffer settings and feature switches). It is compatible with custom parameter settings via the setConfig interface (custom settings take precedence).
-
After setting the playback scenario, you can view the parameter configuration using the
getConfiginterface.
Interface example
/**
* Set the player scenario.
*
* @param scene
*/
abstract public void setPlayerScene(PlayerScene scene);
Playback scenarios
public enum PlayerScene {
/**
* Scenario: none.
*/
NONE,
/**
* Long video scenario: applies to videos longer than 30 minutes.
*/
LONG,
/**
* Medium video scenario: applies to videos between 5 and 30 minutes.
*/
MEDIUM,
/**
* Short video scenario: applies to videos up to 5 minutes.
*/
SHORT,
/**
* Live scenario.
*/
LIVE,
/**
* Ultra-low latency live scenario.
*/
RTS_LIVE
}
Usage instructions
// Set short video scenario.
aliPlayer.setPlayerScene(PlayerScene.SHORT)
// Set medium video scenario.
aliPlayer.setPlayerScene(PlayerScene.MEDIUM)
// Set long video scenario.
aliPlayer.setPlayerScene(PlayerScene.LONG)
// Set live scenario.
aliPlayer.setPlayerScene(PlayerScene.LIVE)
Pre-rendering
The Android player SDK supports quickly rendering the first frame before playback starts, which can improve startup speed.
-
This feature is disabled by default.
-
You must set the
Viewbefore callingPrepareto ensure the frame is rendered to theViewas soon as it is ready. -
Enabling this feature affects the triggering order of preparation success and first-frame rendering events: without it, preparation success is triggered before first-frame rendering; with it, due to differences in decoding and rendering speed, first-frame rendering may be triggered before preparation success, but this does not affect playback.
Example:
aliPlayer.setOption(ALLOW_PRE_RENDER, 1);
Local cache
For detailed code examples, refer to the API-Example Video preloading (Preload) module. This Java-based example project for the ApsaraVideo Player SDK for Android helps developers quickly master core SDK integration features.
Local cache improves startup speed, seek speed, and reduces stuttering for repeated playback while saving bandwidth.
Enable local cache
Local cache is disabled by default. To use it, enable it manually using AliPlayerGlobalSettings and enableLocalCache. Example:
-
If video playback URLs include authentication parameters, the parameters change between caching and playback. To improve cache hit rate for the same URL under different authentications, remove authentication parameters before calculating the hash value (e.g., MD5) via
setCacheUrlHashCallback. For example, for a URL likehttp://****.mp4?aaa, calculate the hash usinghttp://****.mp4. However, for encrypted m3u8 videos, if you remove authentication parameters from keyURLs before hashing, different videos might hit the same key, causing playback failure. Solution: In thesetCacheUrlHashCallbackcallback, check the domain and only remove authentication parameters for playback domains (http(s)://xxxxx.m3u8?aaaa), not for keyURL domains (http(s)://yyyyy?bbbb). Use curl to get the HLS encrypted video M3U8 playlist, where playURL is the M3U8 address and keyURL is the AES-128 decryption key address. Example terminal output:# playURL: M3U8 playlist request C:\Users\futan>curl "https://videxxxv.cc/a003xxx2a-hd-encrypt-stream.m3u8?MtsHlsUriToken=uheAz07oi-jlo9CeIU6LxxxAr4a3WtzrJXnCn4ClS44dTYHCQGmXBlo7TyuPLE0a&auth_key=17xxxrmonwFHJ" #EXTM3U #EXT-X-VERSION:3 #EXT-X-ALLOW-CACHE:YES #EXT-X-TARGETDURATION:10 #EXT-X-MEDIA-SEQUENCE:0 # keyURL: AES-128 encryption key address #EXT-X-KEY:METHOD=AES-128,URI="https://apxxx.cc/decrypt?Ciphertext=NWNiNDQyN2MtNjV1ZS00ZWIwLTk0YTAtNTJhOWIyZWV1OTY2MzdoRTJ6TjVxcXkweFY2xxxNCt4OGNFRGNReHRG&MtsHlsUriToken=uheAz07oi-jlo9CeIU6LxxxAr4a3WtzrJXnCn4ClS44dTYHCQGmXBlo7TyuPLE0a" #EXTINF:10.000000, e9012989ecd8e987eb7349d84d3b06d8-hd-encrypt-stream-00001.ts?auth_key=1706560316-65b7xxx39f1d6c77 #EXTINF:10.000000, e9012989ecd8e987eb7349d84d3b06d8-hd-encrypt-stream-00002.ts?auth_key=1706560316-65b7xxxe8eca2faf #EXTINF:10.000000, e9012989ecd8e987eb7349d84d3b06d8-hd-encrypt-stream-00003.ts?auth_key=1706560316-65b7xxx50c6981b3 #EXTINF:10.000000, e9012989ecd8e987eb7349d84d3b06d8-hd-encrypt-stream-00004.ts?auth_key=1706560316-65b7xxxf7228c594 #EXTINF:10.000000, e9012989ecd8e987eb7349d84d3b06d8-hd-encrypt-stream-00005.ts?auth_key=1706560316-65b7xxx6dc68c35d -
If the server supports both HTTP and HTTPS protocols pointing to the same media file, remove or standardize the protocol before calculating the hash. For example:
-
For URLs
https://****.mp4andhttp://****.mp4, calculate the hash using****.mp4. -
For URL
https://****.mp4, standardize tohttp://****.mp4before calculating the hash.
-
-
For player SDK version 5.5.4.0 and later, if the video playback URL includes authentication parameters and uses HLS protocol, you can set
PlayerConfig.mEnableStrictAuthModeto choose between authentication modes (default is false for older versions; true for version 7.13.0 and later):-
Non-strict authentication (false): Authentication is cached. If only part of the media was cached previously, the player uses the cached authentication for subsequent requests. If URL authentication has a short validity period or playback resumes after a long pause, authentication may expire. Integrate with auto-refresh playback sources to handle authentication expiration.
-
Strict authentication (true): Authentication is not cached. Authentication occurs on every startup, causing startup failure without network.
-
Enable or disable local cache for a single URL
To enable or disable local cache for a specific URL, set it in the player config.
// Get configuration first.
PlayerConfig config = aliPlayer.getConfig();
// Whether to enable local cache for the playback URL. Default is true. When global local cache is enabled and this is set to true, local cache takes effect for this URL. If set to false, local cache is disabled for this URL.
config.mEnableLocalCache = false;
....// Other settings.
// Set configuration for the player.
aliPlayer.setConfig(config);
Preloading
Preloading is an upgrade to local cache that improves video startup speed by setting memory usage for video caching.
Preloading limitations:
-
Currently supports loading single media files such as MP4, MP3, FLV, and HLS.
The Android player SDK provides automatic network resource scheduling during preloading by default to reduce the impact of preloading network requests on ongoing video playback. The automatic scheduling strategy allows preloading requests only after the buffer of the currently playing video reaches a certain threshold. To control real-time preloading requests yourself, disable this strategy using the following method:
AliPlayerGlobalSettings.enableNetworkBalance(false);
-
Enable local cache. For detailed steps, see Local cache.
-
Set data source.
VidAuth (recommended)
VidAuth vidAuth = new VidAuth(); vidAuth.setVid("Vid info");// Required parameter: Video ID. vidAuth.setPlayAuth("<yourPlayAuth>");// Required parameter: Playback credential, generated by calling the GetVideoPlayAuth API of VOD. vidAuth.setRegion("Access region");// For player SDK version 5.5.5.0 and later, this parameter is deprecated and not required; the player automatically parses the region. For versions before 5.5.5.0, this parameter is required; the default VOD access region is cn-shanghai. vidAuth.setQuality("Selected definition") //"AUTO" represents adaptive bitrate.VidSts
VidSts vidSts = new VidSts(); vidSts.setVid("Vid info");// Required parameter: Video ID. vidSts.setAccessKeyId("<yourAccessKeyId>");// Required parameter: Access key ID of the STS temporary AK pair, generated by calling the AssumeRole API of STS. vidSts.setAccessKeySecret("<yourAccessKeySecret>");// Required parameter: Access key of the STS temporary AK pair, generated by calling the AssumeRole API of STS. vidSts.setSecurityToken("<yourSecurityToken>");// Required parameter: STS security token, generated by calling the AssumeRole API of STS. vidSts.setRegion("Access region");// Required parameter: VOD access region; default is cn-shanghai. vidSts.setQuality("Selected definition") //"AUTO" represents adaptive bitrate.UrlSource
UrlSource urlSource = new UrlSource(); urlSource.setUri("Playback address");// Required parameter: Playback address, which can be a third-party VOD address or an Alibaba Cloud VOD playback address. -
Set task parameters.
NoteApplies only to multi-bitrate videos. Choose one of
setDefaultBandWidth,setDefaultResolution, orsetDefaultQuality.PreloadConfig preloadConfig = new PreloadConfig(); // Set preloading bitrate for multi-bitrate streams. preloadConfig.setDefaultBandWidth(400000); // Set preloading resolution for multi-bitrate streams. preloadConfig.setDefaultResolution(640 * 480); // Set preloading quality for multi-bitrate streams. preloadConfig.setDefaultQuality("FD"); // Set preloading duration. preloadConfig.setDuration(1000); -
Add task listener.
-
Build task and add to
MediaLoaderV2instance to start preloading.VidAuth (recommended)
// Build preloading. PreloadTask mPreloadTask = new PreloadTask(vidAuth, preloadConfig); // Get MediaLoaderV2 instance. MediaLoaderV2 mediaLoaderV2 = MediaLoaderV2.getInstance(); // Add task and start preloading. String taskId = mediaLoaderV2.addTask(mPreloadTask, PreloadListenerImpl)VidSts
// Build preloading. PreloadTask mPreloadTask = new PreloadTask(vidSts, preloadConfig); // Get MediaLoaderV2 instance. MediaLoaderV2 mediaLoaderV2 = MediaLoaderV2.getInstance(); // Add task and start preloading. String taskId = mediaLoaderV2.addTask(mPreloadTask, PreloadListenerImpl);UrlSource
// Build preloading. PreloadTask mPreloadTask = new PreloadTask(urlSource, preloadConfig); // Get MediaLoaderV2 instance. MediaLoaderV2 mediaLoaderV2 = MediaLoaderV2.getInstance(); // Add task and start preloading. String taskId = mediaLoaderV2.addTask(mPreloadTask, PreloadListenerImpl) -
Optional: Manage tasks.
mediaLoaderV2.cancelTask(taskId);// Cancel preloading task with specified task ID. mediaLoaderV2.pauseTask(taskId);// Pause preloading task with specified task ID. mediaLoaderV2.resumeTask(taskId);// Resume preloading task with specified task ID. -
Optional: Delete loaded files.
Delete loaded files as needed to save space. The Android player SDK does not provide a delete interface; delete files from the loading directory in your app.
Dynamic preloading
Dynamic preloading strategy allows integrators to control both the cache of the currently playing video and the number and cache of preloaded items, balancing playback experience and cost overhead.
Multi-bitrate HLS video preloading
In listPlayer + multi-bitrate HLS video playback scenarios, integrators can preload streams matching the current playback definition and choose preloading modes based on business needs.
Get download speed
Get the current video download speed through the onInfo callback, implemented by the getExtraValue interface. Example:
aliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
@Override
public void onInfo(InfoBean infoBean) {
if(infoBean.getCode() == InfoCode.CurrentDownloadSpeed){
// Current download speed.
long extraValue = infoBean.getExtraValue();
}
}
});
Network features
HTTPDNS
HTTPDNS resolves domain names via HTTP to specific servers, reducing DNS hijacking risks and providing faster, more stable resolution.
The ApsaraVideo Player SDK provides enhanced HTTPDNS for Alibaba Cloud CDN domains, supporting precise CDN scheduling and real-time resolution.
Enhanced HTTPDNS usage example
Enhanced HTTPDNS provides services only for Alibaba Cloud CDN domains. Ensure your domain is an Alibaba Cloud CDN domain and is properly configured. For adding CDN domains in VOD, see Add accelerated domain. Alibaba Cloud CDN.
// Enable enhanced HTTPDNS.
AliPlayerGlobalSettings.enableEnhancedHttpDns(true);
// Optional: Add HTTPDNS pre-resolution domains.
DomainProcessor.getInstance().addPreResolveDomain("player.***alicdn.com");
HTTP/2
The Android player SDK enables HTTP/2 by default starting from version 5.5.0.0.
The Android player SDK supports the HTTP/2 protocol, which uses multiplexing to avoid head-of-line blocking and improve playback performance. Example:
AliPlayerGlobalSettings.setUseHttp2(true);
HTTP pre-connect TCP
For HTTP video playback requests (non-HTTPS), establishing TCP connections in advance significantly improves user experience, reduces network connection time, ensures immediate and continuous playback, and optimizes network and system resource usage. Usage:
// Domain format is host[:port]; port is optional. Separate multiple domains with semicolons (;).
// Global setting.
// Full interface uses the current string each time it's set (more - add, less - remove). Empty string stops pre-connection.
AliPlayerGlobalSettings.setOption(AliPlayerGlobalSettings.SET_PRE_CONNECT_DOMAIN, "domain1;domain2");
Video download
For detailed code examples, refer to the API-Example Video download and offline playback (Download) module. This Java-based example project for the ApsaraVideo Player SDK for Android helps developers quickly master core SDK integration features.
The Android player SDK provides a video download feature for VOD services, allowing users to cache videos locally using the ApsaraVideo Player. It offers two download methods: standard download and secure download.
-
Standard download
Downloaded video data is not encrypted by Alibaba Cloud and can be played by third-party players.
-
Secure download
Downloaded video data is encrypted by Alibaba Cloud. Third-party players cannot play it. Only the ApsaraVideo Player can play it.
Usage instructions
-
Only VidSts and VidAuth methods support video download.
-
To use the player's video download feature, enable and configure download mode in the VOD console. For detailed steps, see Offline download.
-
Video download supports resumable downloads.
Procedure
-
Optional: Configure the encryption verification file for secure download. Required only for secure download; not needed for standard download.
NoteEnsure the configured encryption verification file matches your app information; otherwise, video download fails.
For secure download, configure the key file generated in the VOD console in the player SDK for decryption verification during video download and playback. For key file generation, see Enable secure download.
We recommend configuring this once in Application. Example:
PrivateService.initService(getApplicationContext(), "Path to encryptedApp.dat file"); // We recommend storing the encryptedApp.dat verification file on the phone and setting its local file path here. -
Create and set downloader.
Create a downloader using AliDownloaderFactory. Example:
AliMediaDownloader mAliDownloader = null; ...... // Create downloader. mAliDownloader = AliDownloaderFactory.create(getApplicationContext()); // Configure download save path. mAliDownloader.setSaveDir("Save folder path"); -
Set event listeners.
The downloader provides multiple event listeners. Example:
-
Prepare download source.
Prepare the download source using the
preparemethod. Download sources support VidSts and VidAuth methods. Examples:-
VidSts
// Create VidSts VidSts aliyunVidSts = new VidSts(); aliyunVidSts.setVid("Vid information"); // Video ID (VideoId). aliyunVidSts.setAccessKeyId("<yourAccessKeyId>"); // AccessKey ID of the temporary STS AccessKey pair, generated by calling the AssumeRole operation of the Security Token Service (STS). aliyunVidSts.setAccessKeySecret("<yourAccessKeySecret>"); // AccessKey secret of the temporary STS AccessKey pair, generated by calling the AssumeRole operation of the Security Token Service (STS). aliyunVidSts.setSecurityToken("<yourSecurityToken>"); // Security Token Service (STS) token, generated by calling the AssumeRole operation of the Security Token Service (STS). aliyunVidSts.setRegion("region"); // The region of the video-on-demand (VOD) service. Default value: cn-shanghai. // If you have enabled HLS encryption parameter pass-through in the VOD console and the default parameter name is MtsHlsUriToken, // you must set the config and pass it into the vid, as shown below. // If you have not enabled HLS encryption parameter pass-through in the VOD console, skip the following code. VidPlayerConfigGen vidConfig = new VidPlayerConfigGen(); vidConfig.setMtsHlsUriToken("<yourMtsHlsUriToken>"); aliyunVidSts.setPlayerConfig(vidConfig); // Prepare the download source mAliDownloader.prepare(aliyunVidSts) -
VidAuth
// Create VidAuth. VidAuth vidAuth = new VidAuth(); vidAuth.setVid("Vid info");// Video ID. vidAuth.setPlayAuth("<yourPlayAuth>");// Playback credential, generated by calling VOD GetVideoPlayAuth API. vidAuth.setRegion("Access region");// For player SDK version 5.5.5.0 and later, this parameter is deprecated and not required; the player automatically parses the region. For versions before 5.5.5.0, this parameter is required; VOD access region default is cn-shanghai. // If you enabled HLS standard encryption parameter pass-through in VOD console with default parameter name MtsHlsUriToken, set config and pass it to vid as follows. VidPlayerConfigGen vidConfig = new VidPlayerConfigGen(); vidConfig.setMtsHlsUriToken("<yourMtsHlsUriToken>"); vidAuth.setPlayerConfig(config); // Prepare download source. mAliDownloader.prepare(vidAuth);
Note-
Source file format matches the downloaded file format; changing it is not supported.
-
If you enabled HLS standard encryption parameter pass-through in VOD console with default parameter name MtsHlsUriToken, see HLS standard encryption parameter pass-through, then set the MtsHlsUriToken value in the VOD source as shown above.
-
-
After successful preparation, select download item and start download.
After successful preparation, the
OnPreparedListenermethod is called. The returned TrackInfo contains information such as video stream definition. Select one Track for download. Example:public void onPrepared(MediaInfo mediaInfo) { // Download item prepared successfully. List<TrackInfo> trackInfos = mediaInfo.getTrackInfos(); // For example: download the first TrackInfo. mAliDownloader.selectItem(trackInfos.get(0).getIndex()); // Start download. mAliDownloader.start(); } -
(Optional) Update download source.
To prevent VidSts and VidAuth expiration, you can update the download source information and start downloading. Example:
// Update download source. mAliDownloader.updateSource(VidSts); // Start download. mAliDownloader.start(); -
After download success or failure, release downloader.
After download success, call
releasein theonCompletionoronErrorcallback to release the downloader. Example:mAliDownloader.stop(); mAliDownloader.release(); -
Optional: Delete downloaded files.
You can delete downloaded files during or after download. Example:
// Delete file via object. mAliDownloader.deleteFile(); // Delete via static method; returns 0 if successful. AliDownloaderFactory.deleteFile("Path to download folder","Video ID","Video format","Downloaded video index");
What to do next
Downloaded videos can be played using the ApsaraVideo Player. Steps:
-
After download completion, get the absolute path of the video file.
String path = mAliDownloader.getFilePath(); -
Set the absolute path via VOD UrlSource for playback.
UrlSource urlSource = new UrlSource(); urlSource.setUri("Playback address");// Set absolute path of downloaded video. aliPlayer.setDataSource(urlSource);
Encrypted playback
VOD videos support HLS standard encryption, Alibaba Cloud proprietary cryptography, and DRM encryption. Live videos support only DRM encryption. For encrypted playback, see Encrypted playback.
Native RTS playback
The Android Player SDK integrates the Native RTS SDK for ultra-low latency live streaming. Implement RTS stream pulling on Android.