All Products
Search
Document Center

ApsaraVideo VOD:Basic features of ApsaraVideo Player SDK for Android

Last Updated:Mar 11, 2026

This topic describes how to use the basic features of the ApsaraVideo Player SDK for Android. You will learn how to configure playback sources, adjust volume and playback speed, switch resolutions and audio tracks, and more.

Important

To run and test the demo, Download ApsaraVideo Player SDK and follow the Run the demo to compile and run it.

Configure a video source

The ApsaraVideo Player SDK for Android supports both video-on-demand (VOD) and live streaming playback.

  • VOD playback methods: VidAuth (recommended for ApsaraVideo VOD users), VidSts, UrlSource, and encrypted playback.

  • Live stream playback methods: UrlSource and encrypted playback.

Note
  • UrlSource plays media from a URL. VidSts and VidAuth play media by media ID (Vid).

  • For information about supported regions, see ApsaraVideo VOD region IDs.

VOD playback

VidAuth (Recommended)

To play a VOD video by using VidAuth, set the vid property to the media ID and the playAuth property to the playback credential.

  • Media ID: You can obtain the media ID after you upload a media file. In the ApsaraVideo VOD console, choose Media Files > Audio/Video. You can also call the SearchMedia API.

  • Playback credential: Call the GetVideoPlayAuth operation to obtain the playback credential. We recommend that you integrate the ApsaraVideo VOD server-side SDK to avoid manual signature generation. For examples, see OpenAPI Explorer.

We recommend VidAuth over VidSts for ApsaraVideo VOD users because VidAuth provides better usability and security. For more information, see Credential method vs. STS method.

If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, the default parameter name is MtsHlsUriToken. For more information, see Parameter pass-through for HLS encryption.

Sample code:

VidAuth vidAuth = new VidAuth();
vidAuth.setVid("Vid");                 // Required. The video ID (VideoId).
vidAuth.setPlayAuth("<yourPlayAuth>"); // Required. The playback credential from GetVideoPlayAuth.
vidAuth.setRegion("region-id");        // Deprecated for SDK V5.5.5.0 and later. The player automatically parses the region. For earlier versions, this parameter is required. Default: cn-shanghai.
   // vidAuth.setAuthTimeout(3600);    // Optional. Set the validity period of the playback URL in seconds. This value overwrites the validity period configured in the ApsaraVideo VOD console. Default: 3600. Make sure that the value is greater than the video duration to prevent URL expiration during playback.
        
   // If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, the default parameter is MtsHlsUriToken. Specify config and pass it with your VidAuth data source.
   VidPlayerConfigGen vidConfig = new VidPlayerConfigGen();
   vidConfig.setMtsHlsUriToken("<yourMtsHlsUriToken>");
   vidAuth.setPlayerConfig(config);
   aliPlayer.setDataSource(vidAuth);

VidSts

VidSts playback uses temporary STS credentials instead of VOD playback credentials. Before you play VOD videos by using VidSts, obtain an STS token and an AccessKey pair (AccessKey ID and AccessKey secret). For more information, see Obtain an STS token.

If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, the default parameter name is MtsHlsUriToken. For more information, see Parameter pass-through for HLS encryption.

Sample code

VidSts vidSts = new VidSts();
       vidSts.setVid("Vid");                               // Required. The video ID (VideoId).
       vidSts.setAccessKeyId("<yourAccessKeyId>");         // Required. The temporary AccessKey ID from STS (AssumeRole).
       vidSts.setAccessKeySecret("<yourAccessKeySecret>"); // Required. The temporary AccessKey secret from STS (AssumeRole).
       vidSts.setSecurityToken("<yourSecurityToken>");     // Required. The STS token from AssumeRole.
       vidSts.setRegion("RegionID");                       // Required. The ApsaraVideo VOD region. Default: cn-shanghai.
       // vidSts.setAuthTimeout(3600);                     // Optional. Set the validity period of the playback URL in seconds. This value overwrites the validity period configured in the ApsaraVideo VOD console. Default: 3600. Make sure that the value is greater than the video duration to prevent URL expiration during playback.
        
       // If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, the default parameter is MtsHlsUriToken. Specify config and pass it with your vidSts data source.
       // If it is not enabled, the following configuration is not neccessary.
       VidPlayerConfigGen vidConfig = new VidPlayerConfigGen();
       vidConfig.setMtsHlsUriToken("<yourMtsHlsUriToken>");
       vidSts.setPlayerConfig(config);
       aliPlayer.setDataSource(vidSts);

UrlSource

To play a VOD video by using UrlSource, pass the playback URL directly.

  • You can call the GetPlayInfo operation to obtain playback URLs from ApsaraVideo VOD. We recommend that you integrate the ApsaraVideo VOD server-side SDK. For examples, see OpenAPI Explorer

  • For local files, make sure that you have permission to access the file. Use full paths such as /sdcard/video/sample.mp4 or content://media/video/123.

 UrlSource urlSource = new UrlSource();
        urlSource.setUri("your-playback-url"); // Required. A VOD URL, third-party URL, or local file path.
        aliPlayer.setDataSource(urlSource);

Encrypted playback

VOD videos support HLS encryption, Alibaba Cloud proprietary cryptography, and DRM encryption. For playback, see Play an encrypted video.

Live stream playback

For live stream playback, see Standard live stream playback.

Control playback

The ApsaraVideo Player SDK for Android provides methods to start, pause, stop, and seek playback.

Prepare the player

Call prepare to load and parse the media data.

aliPlayer.prepare();

Start playback

Call start to begin or resume playback.

aliPlayer.start();

Seek to a position

Call seekTo to jump to a specific position. This method is useful when users drag the progress bar or resume playback from a saved position.

// Specify the target time in milliseconds.
aliPlayer.seekTo(long position);

To set the playback start position before calling prepare, use setStartTime. This setting takes effect only once per prepare call and is automatically cleared afterward.

// Set the start position in milliseconds. seekMode specifies accurate or inaccurate seeking.
aliPlayer.setStartTime(time, seekMode);

Pause playback

Call pause to pause playback.

aliPlayer.pause();

Stop playback

Call stop to stop playback.

aliPlayer.stop();

Destroy the player

You can destroy the player synchronously or asynchronously.

// Synchronous destroy. Blocks until player resources are released. Automatically calls stop.
aliPlayer.release();
// Asynchronous destroy. Returns immediately. Automatically calls stop.
aliPlayer.releaseAsync();
Note

If you have high requirements on UI response speed, use releaseAsync. Note the following:

  • Do not perform any operations on the player object during asynchronous destroy.

  • The asynchronous destroy includes an asynchronous stop process. You do not need to manually stop the player before calling releaseAsync.

Monitor player status

The ApsaraVideo Player SDK for Android provides listeners to monitor playback events and status changes.

Set listeners

You can set multiple listeners for the player. We recommend that you set OnErrorListener, OnCompletionListener, OnLoadingStatusListener, and OnInfoListener.

aliPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
    // This callback is triggered if an error occurs when you use the player.

    @Override
    public void onError(ErrorInfo errorInfo) {
        ErrorCode errorCode = errorInfo.getCode(); // The error code.
        String errorMsg = errorInfo.getMsg(); // The error message.
        // errorExtra provides extra error information in a JSON string. For example:
        //{ "Url": "xxx",
   		//	"Module": "NetWork",
    	//	"ModuleCode": "-377",
   		//  "ModuleMessage": "Redirect to a url that is not a media"}
        // Note that the value of ModuleCode is not always the same as the value of errorCode.
        String errorExtra= errorInfo.getExtra();         
        // Stop the player after an error occurs.
        aliPlayer.stop();
    }
});
aliPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
    // After you call the aliPlayer.prepare() method, the player starts to read and parse data. This callback is triggered after the data is parsed.

    @Override
    public void onPrepared() {
        // The player is prepared.
    }
});
aliPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
    // This callback is triggered after the playback is complete.
    @Override
    public void onCompletion() {
        // In most cases, you can call the stop method to stop the playback.
        aliPlayer.stop();
    }
});
aliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
    // The information about the player, such as the current playback position and the buffered position.
    @Override
    public void onInfo(InfoBean infoBean) {
        InfoCode code = infoBean.getCode(); // The information code.
        String msg = infoBean.getExtraMsg();// The information content.
        long value = infoBean.getExtraValue(); // The information value.

        // The current playback position: InfoCode.CurrentPosition.
        // The buffered position: InfoCode.BufferedPosition.
    }
});
aliPlayer.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
    // The loading status of the player. You can use this to display a loading screen when the network connection is poor.

    @Override
    public void onLoadingBegin() {
        // The player starts to load data. The video and audio are not ready for playback.
        // In most cases, you can display a circular loading indicator.
    }

    @Override
    public void onLoadingProgress(int percent, float netSpeed) {
        // The loading progress in percentage and the network speed.
        // The network speed is a reserved field. The value is 0.
    }

    @Override
    public void onLoadingEnd() {
        // The player stops loading data. The video and audio are ready for playback.
        // In most cases, you can hide the circular loading indicator.
    }
});

Monitor playback state changes

Use the onStateChanged callback to monitor player state transitions.

aliPlayer.setOnStateChangedListener(new IPlayer.OnStateChangedListener() {
    @Override
    public void onStateChanged(int newState) {
        /*
          int idle = 0;
          int initalized = 1;
          int prepared = 2;
          int started = 3;
          int paused = 4;
          int stopped = 5;
          int completion = 6;
          int error = 7;
      */
    }
});

Configure video display

Configure how the video is scaled, rotated, and mirrored during playback.

Scaling mode

The SDK supports three scaling modes:

// Scale to fit the view while maintaining the aspect ratio (letterboxing).
aliPlayer.setScaleMode(ScaleMode.SCALE_ASPECT_FIT);
// Scale to fill the view while maintaining the aspect ratio (cropping).
aliPlayer.setScaleMode(ScaleMode.SCALE_ASPECT_FILL);
// Stretch to fill the view. The aspect ratio is not maintained. Image distortion may occur.
aliPlayer.setScaleMode(ScaleMode.SCALE_TO_FILL);

Rotation

Call setRotateMode to rotate the video. You can query the current rotation angle with getRotateMode.

// No rotation.
aliPlayer.setRotateMode(RotateMode.ROTATE_0);
// 90° clockwise.
aliPlayer.setRotateMode(RotateMode.ROTATE_90);
// 180° clockwise.
aliPlayer.setRotateMode(RotateMode.ROTATE_180);
// 270° clockwise.
aliPlayer.setRotateMode(RotateMode.ROTATE_270);
// Query the current rotation angle.
aliPlayer.getRotateMode();

Mirroring

Call setMirrorMode to mirror the video. The SDK supports horizontal and vertical mirroring:

// No mirroring.
aliPlayer.setMirrorMode(MirrorMode.MIRROR_MODE_NONE);
// Horizontal mirroring.
aliPlayer.setMirrorMode(MirrorMode.MIRROR_MODE_HORIZONTAL);
// Vertical mirroring.
aliPlayer.setMirrorMode(MirrorMode.MIRROR_MODE_VERTICAL);

Get playback information

You can obtain the playback progress, duration, and buffering progress during playback.

Playback progress

In the onInfo callback, call getExtraValue to retrieve the current playback position in milliseconds.

aliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
    @Override
    public void onInfo(InfoBean infoBean) {
        if(infoBean.getCode() == InfoCode.CurrentPosition){
            // The current playback position in milliseconds.
            long extraValue = infoBean.getExtraValue();
        }
    }
});

Total duration

The video duration is available only after the media is loaded. Call getDuration after the onPrepared callback is triggered.

long duration = aliPlayer.getDuration();

Actual playback duration

You can retrieve the actual playback duration in real time. This value excludes the time when playback is paused or buffering.

long playedDuration = aliPlayer.getPlayedDuration(); 

Buffering progress

In the onInfo callback, check for InfoCode.BufferedPosition to get the current buffering progress.

aliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
    @Override
    public void onInfo(InfoBean infoBean) {
        if(infoBean.getCode() == InfoCode.BufferedPosition){
            // The current buffering progress in milliseconds.
            long extraValue = infoBean.getExtraValue();
        }
    }
});

Real-time rendering and bitrate metrics

Obtain the rendering frame rate, audio and video bitrate, and network downstream bitrate in real time.

// Video rendering frame rate. Returns a float value.
aliPlayer.getOption(IPlayer.Option.RenderFPS);
// Video bitrate. Returns a float value in bit/s.
aliPlayer.getOption(IPlayer.Option.VideoBitrate);
// Audio bitrate. Returns a float value in bit/s.
aliPlayer.getOption(IPlayer.Option.AudioBitrate);
// Network downstream bitrate. Returns a float value in bit/s.
aliPlayer.getOption(IPlayer.Option.DownloadBitrate);

Handle A/V out-of-sync events

Under extreme conditions, such as software decoding during 4K playback or high-speed playback of HD H.265 streams on low-end devices, decoding performance may fall behind the playback speed. The SDK triggers a callback to notify you of this event.

aliPlayer.setOnAVNotSyncStatusListener(new IPlayer.OnAVNotSyncStatusListener() {
    @Override
    public void onAVNotSyncStart(int type) {
        if (type == 0) {
            //Reduce the playback speed to recover.
            if (aliPlayer.getSpeed() > 1) {
                aliPlayer.setSpeed(1);
            }
        }
        Toast.makeText(getContext(), "Out-of-sync detected" , Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onAVNotSyncEnd() {
        Toast.makeText(getContext(), "Out-of-sync resolved" , Toast.LENGTH_SHORT).show();
    }
});

Control volume

Change the volume

Call setVolume to change the volume. Valid values range from 0 to 2, where 1 is the original volume. Values greater than 1 amplify the audio and may introduce noise. We recommend that you do not set the volume to a value greater than 1.

// Set the volume. Valid values: 0 to 2.
aliPlayer.setVolume(1f);
// Get the current volume.
aliPlayer.getVolume();

Mute the player

Call setMute to mute or unmute the player.

aliPlayer.setMute(true); 

Set the playback speed

Call setSpeed to change the playback speed. Valid values range from 0.5 to 5. The audio pitch remains unchanged at different speeds.

// Common speeds: 0.5x, 1x, 1.5x, 2x.
aliPlayer.setSpeed(1.0f);

Switch resolutions

Note

For detailed code examples, see the MultiResolution module in the API-Example project.

UrlSource-based live streaming

For more information, see Standard live stream playback.

VidAuth or VidSts-based playback

If you use VidAuth or VidSts for VOD playback, the SDK automatically retrieves video definitions from ApsaraVideo VOD. No additional configuration is required.

Query available definitions

After the video is loaded, retrieve the available definitions.

// Retrieve all available track.
List<TrackInfo> trackInfos = aliPlayer.getMediaInfo().getTrackInfos();
//Retrieve the available definitions.
for (TrackInfo trackInfo : trackInfos) {
     if(trackInfo.getType() == TrackInfo.Type.TYPE_VOD){
             // Get video definition. 
        String vodDefinition = trackInfo.getVodDefinition();
     }
}

Switch the definition

Call selectTrack with the track index to switch definitions. Obtain the index from the TrackInfo object.

aliPlayer.selectTrack(index);

Listen for definition switching events

Set a listener to receive notifications when definition switching succeeds or fails.

aliPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
    @Override
    public void onChangedSuccess(TrackInfo trackInfo) { }

    @Override
    public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) { }
});

Enable fast switching

After you enable fast switching mode, calls to selectTrack respond immediately without waiting for buffering.

PlayerConfig config = aliPlayer.getConfig();
config.mSelectTrackBufferMode = 1;
aliPlayer.setConfig(config)

Enable loop playback

Call setLoop to enable loop playback. When playback reaches the end, it automatically restarts from the beginning.

aliPlayer.setLoop(true);

The onInfo callback is triggered when loop playback restarts.

aliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
    @Override
    public void onInfo(InfoBean infoBean) {
        if (infoBean.getCode() == InfoCode.LoopingStart){
            //Loop playback restarted.
        }
    }
});

Switch audio tracks

The ApsaraVideo Player SDK for Android supports audio track switching, which lets you switch between audio tracks in different languages during playback.

Supported stream types

You can switch audio tracks in the following stream types. The switching behavior varies based on the stream type.

Stream type

Extension

Bitrate count

Substream type

Switching behavior

Non-list stream (MP4)

.mp4

1

One video track, multiple audio and subtitle tracks

You can switch between audio tracks.

Single-bitrate mixed HLS

.m3u8

1

One video track, multiple audio and subtitle tracks

You can switch between audio tracks.

Single-bitrate HLS

.m3u8

1

Separate video, audio, and caption substreams

You can switch between audio tracks.

Multi-bitrate mixed HLS

.m3u8

n

Substreams with different bitrates, each with one video and multiple audio tracks

You can switch between substreams only, not audio tracks within a substream.

Usage example

  1. Set the onSubTrackReady callback. This callback is typically triggered before the onPrepared callback.

    aliPlayer.setOnSubTrackReadyListener(new IPlayer.OnSubTrackReadyListener() {
        @Override
        //onSubTrackReady. Typically triggered before the onPrepared callback.
        public void onSubTrackReady(MediaInfo mediaInfo) {
            if (mPlayerTrackFragment != null) {
                //mPlayerTrackFragment.showMediaInfo();
                // Call getSubMediaInfo after this callback is triggered. Calling it before this callback returns an empty result.
                MediaInfo subMediaInfo = aliPlayer.getSubMediaInfo();
                TrackInfos = subMediaInfo.getTrackInfos();
                // Find the target audio track from the track list.
                myTrack = myfunc(TrackInfos)
            }
        }
    });
  2. Switch to the target audio track.

    index = myTrack.getIndex();
    aliPlayer.selectTrack(index);

Use thumbnails

Note

For detailed code examples, see the Thumbnail module in the API-Example project.

Before you use thumbnails, configure sprite snapshots for your video. In the ApsaraVideo VOD console, create a snapshot template with Image Sprite as the snapshot type, and then create a workflow to process the video. For more information, see Video snapshots.

mAliPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
    @Override
    public void onPrepared() {
        // 1. Create a ThumbnailHelper instance with the sprite snapshot URL.
        ThumbnailHelper mThumbnailHelper = new ThumbnailHelper(URL);
        // 2. Set listeners.
        mThumbnailHelper.setOnPrepareListener(new ThumbnailHelper.OnPrepareListener() {
            @Override
            public void onPrepareSuccess() {
                // 4. After the thumbnail is loaded, request thumbnails at specific positions.
            }
            @Override
            public void onPrepareFail() {}
        });

        mThumbnailHelper.setOnThumbnailGetListener(new ThumbnailHelper.OnThumbnailGetListener() {
            @Override
            public void onThumbnailGetSuccess(long positionMs, ThumbnailBitmapInfo thumbnailBitmapInfo) {
                // 5. Get the thumbnail bitmap at the specified position.
                Bitmap thumbnailBitmap = thumbnailBitmapInfo.getThumbnailBitmap();
            }
            @Override
            public void onThumbnailGetFail(long positionMs, String errorMsg) {}
        });

        // 3. Load the thumbnail.
        mThumbnailHelper.prepare();
    }
});

Get SDK logs

SDK logs contain detailed information such as request status, invocation results, and permission requests. You can use these logs to debug issues during development. The SDK provides two methods to obtain logs.

Method 1: View logs in the development tool console

Use this method when you can reliably reproduce the issue on your device.

  1. Enable logging and set the log level.

    // Logs are stored under com.cicada.player.utils.
    Logger.getInstance(context).enableConsoleLog(true);
    // Default: AF_LOG_LEVEL_INFO. Use AF_LOG_LEVEL_TRACE for troubleshooting.
    Logger.getInstance(context).setLogLevel(Logger.LogLevel.AF_LOG_LEVEL_INFO);
  2. (Optional) Enable frame-level logging for troubleshooting.

    // 0: disabled, 1: enabled.
    Logger.getInstance(this).setLogOption(Logger.LogOption.FRAME_LEVEL_LOGGING_ENABLED, value);
  3. Reproduce the issue and retrieve the error log from Logcat or your development tool console.

Method 2: Set LogCallback to receive logs programmatically

Use this method when you cannot reliably reproduce the issue on your device. The callback exports logs to your application's log channel.

  1. Enable logging and set the log level.

    // Logs are stored under com.cicada.player.utils.
    // Default: AF_LOG_LEVEL_INFO. Use AF_LOG_LEVEL_TRACE for troubleshooting.
    Logger.getInstance(context).setLogLevel(Logger.LogLevel.AF_LOG_LEVEL_INFO);
    Logger.getInstance(mContext).setLogCallback(newLogger.OnLogCallback(){
            @Override
            public void onLog(Logger.LogLevel logLevel,Strings){
                // Process the log entry.
            }
    });
  2. After an error occurs, the SDK automatically exports the error log to your application's log channel.

References