This topic describes how to create an iOS player instance and use basic playback features. Examples include setting the volume, seeking, monitoring playback status, enabling loop playback, setting the playback speed, and switching audio tracks.
To run the demo, download it and follow the instructions in Run the demo to compile and run the project.
Set the data source (DataSource)
The ApsaraVideo Player SDK for iOS supports four VOD playback methods: VidAuth, VidSts, UrlSource, and encrypted playback. The VidAuth method is recommended for ApsaraVideo VOD users.
The ApsaraVideo Player SDK for iOS supports two live streaming methods: UrlSource and encrypted playback.
VOD playback
VOD playback using VidAuth (Recommended)
To play a VOD video using VidAuth, set the vid property of the player to the audio or video ID and the playauth property to the playback credential.
You can obtain the audio or video ID from the ApsaraVideo VOD console by navigating to Media Files > Audio/Video, or by calling the server-side SearchMedia operation after you upload the audio or video.
You can call the GetVideoPlayAuth operation to obtain the playback credential. We recommend that you integrate the server-side ApsaraVideo VOD SDK to obtain the playback credential. This eliminates the need to sign the request. For more information about calling this operation, see API Portal.
We recommend that ApsaraVideo VOD users use this playback method. The VidAuth method is easier to use and more secure than the VidSts method. For more information about the comparison, see Comparison between the credential-based method and the STS-based method.
If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, the default parameter name is MtsHIsUriToken. For more information, see HLS encryption parameter pass-through. In this case, set the MtsHIsUriToken value in the VOD source as shown in the following code.
AVPVidAuthSource *authSource = [[AVPVidAuthSource alloc] init];
authSource.vid = @"Vid information"; // Required. The video ID.
authSource.playAuth = @"<yourPlayAuth>"; // Required. The playback credential. You must call the GetVideoPlayAuth operation of ApsaraVideo VOD to generate the credential.
authSource.region = @"Region"; // For ApsaraVideo Player SDK V5.5.5.0 and later, this parameter is deprecated. You do not need to set the region because the player automatically parses it. For versions earlier than V5.5.5.0, this parameter is required. The region where ApsaraVideo VOD is activated. Default value: cn-shanghai.
// authSource.authTimeout = 3600; // The validity period of the playback URL in seconds. This value overwrites the validity period of URL signing that is set in the ApsaraVideo VOD console. If you do not set this parameter, the default value 3600 is used. If you set this parameter, make sure that the validity period is longer than the actual video duration to prevent the playback URL from expiring before the playback is complete.
// If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console and the default parameter name is MtsHlsUriToken, you must set the config and pass it to the vid. For more information, see the following code.
// If you do not enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, you do not need to integrate the following code.
VidPlayerConfigGenerator* vp = [[VidPlayerConfigGenerator alloc] init];
[vp setHlsUriToken:yourMtsHlsUriToken];
authSource.playConfig = [vp generatePlayerConfig];
[self.player setAuthSource:authSource];VOD playback using VidSts
With VidSts, you play a VOD video using a temporary STS credential instead of a playback credential. You must obtain a Security Token Service (STS) token and a temporary 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 MtsHIsUriToken. For more information, see HLS encryption parameter pass-through. In this case, set the MtsHIsUriToken value in the VOD source as shown in the following code.
AVPVidStsSource *source = [[AVPVidStsSource alloc] init];
source.vid = @"Vid information"; // Required. The video ID.
source.region = @"Region"; // Required. The region where ApsaraVideo VOD is activated. Default value: cn-shanghai.
source.securityToken = @"<yourSecurityToken>"; // Required. The STS token. You must call the AssumeRole operation of STS to generate the token.
source.accessKeySecret = @"<yourAccessKeySecret>"; // Required. The AccessKey secret of the temporary AccessKey pair. You must call the AssumeRole operation of STS to generate the secret.
source.accessKeyId = @"<yourAccessKeyId>"; // Required. The AccessKey ID of the temporary AccessKey pair. You must call the AssumeRole operation of STS to generate the ID.
// source.authTimeout = 3600; // The validity period of the playback URL in seconds. This value overwrites the validity period of URL signing that is set in the ApsaraVideo VOD console. If you do not set this parameter, the default value 3600 is used. If you set this parameter, make sure that the validity period is longer than the actual video duration to prevent the playback URL from expiring before the playback is complete.
// If you enable HLS encryption parameter pass-through in the ApsaraVideo VOD console and the default parameter name is MtsHlsUriToken, you must set the config and pass it to the vid. For more information, see the following code.
// If you do not enable HLS encryption parameter pass-through in the ApsaraVideo VOD console, you do not need to integrate the following code.
VidPlayerConfigGenerator* vp = [[VidPlayerConfigGenerator alloc] init];
[vp setHlsUriToken:yourMtsHlsUriToken];
source.playConfig = [vp generatePlayerConfig];
// Set the playback source.
[self.player setStsSource:source]VOD playback using UrlSource
To play a VOD video using UrlSource, set the source property of the player to the playback URL.
ApsaraVideo VOD playback URL: You can call the GetPlayInfo operation to obtain the URL. We recommend that you integrate the server-side ApsaraVideo VOD SDK to obtain the playback URL. This eliminates the need to sign the request. For more information about calling this operation, see API Portal.
Local video URL: Ensure you have the required access permissions. You can call a system API to obtain the full path of an accessible local video file, such as
/sdcard/xxx/xxx/xxx.mp4orcontent://xxx/xxx/xx.mp4.
AVPUrlSource *urlSource = [[AVPUrlSource alloc] urlWithString:url]; // Required. The playback URL. It can be a third-party VOD URL, a playback URL in ApsaraVideo VOD, or a local video URL.
[self.player setUrlSource:urlSource]; Encrypted VOD playback
VOD videos support HLS encryption, Alibaba Cloud proprietary cryptography, and DRM encryption. For more information about encrypted playback, see Play encrypted videos on iOS.
Live video playback
For more information, see Standard live streaming.
UrlSource plays a video directly from a URL. VidSts and VidAuth play a video using a video ID.
For more information about how to set the region, see VOD region IDs.
Control playback
The ApsaraVideo Player SDK for iOS supports common operations such as starting playback, pausing playback, and seeking to a specified time.
Prepare for playback
Call the prepare method to prepare for video playback. The following code provides an example:
[self.player prepare];Start playback
Call the start method to start video playback. The following code provides an example:
[self.player start];Start playback from a specified time
Call the seekToTime method to start playback from a specific time. This is useful for features such as dragging the progress bar or resuming playback from a specific point. The following code provides an example:
// The position parameter specifies the time. Unit: milliseconds. The seekMode parameter can be set to accurate or inaccurate mode.
// Accurate seek
[self.player seekToTime:position seekMode:AVP_SEEKMODE_ACCURATE];
// Inaccurate seek
[self.player seekToTime:position seekMode:AVP_SEEKMODE_INACCURATE];You can start playback from a specified position. This setting takes effect only once and is suitable for scenarios where the user needs to start playback from a specific time. The following code provides an example:
// Start playback from a specified position. Call this method before each prepare call. It takes effect only once. The time parameter specifies the time in milliseconds. The seekMode parameter can be set to accurate or inaccurate mode.
[self.player setStartTime:time seekMode:seekMode];Pause playback
Call the pause method to pause video playback. The following code provides an example:
[self.player pause];Resume playback
Call the start method to resume video playback. The following code provides an example:
[self.player start];Stop playback
Call the stop method to stop video playback. The following code provides an example:
[self.player stop];Destroy the player
You can destroy a player instance synchronously or asynchronously. The following code provides an example:
// Synchronously destroy the player. The stop method is automatically called internally.
[self.player destroy];
// Asynchronously destroy the player. The stop method is automatically called internally.
[self.player destroyAsync];If you call the synchronous destroy method, the system returns a response only after the player resources are completely released. If your application requires a fast interface response, we recommend that you use the asynchronous destroy method and note the following points:
Do not perform any other operations on the player object during the asynchronous destruction process.
You do not need to manually stop the player before calling the asynchronous destroy method, because the asynchronous destroy method includes a stop procedure.
Listen for player status
The ApsaraVideo Player SDK for iOS supports setting a player listener and monitoring the playback status.
Set a player listener
The player supports setting multiple listeners.
onPlayerEventandonErrorare important. We recommend that you set them.
@interface SimplePlayerViewController ()<AVPDelegate>
@end
- (void)viewDidLoad {
self.player = [[AliPlayer alloc] init];
self.player.playerView = self.avpPlayerView.playerView;
self.player.delegate = self;
//...
}
/**
@brief Error delegate callback.
@param player The player pointer.
@param errorModel The player error description. See AVPErrorModel.
*/
- (void)onError:(AliPlayer*)player errorModel:(AVPErrorModel *)errorModel {
// Display the error and stop the playback.
}
/**
@brief Player event callback.
@param player The player pointer.
@param eventType The player event type. @see AVPEventType
*/
-(void)onPlayerEvent:(AliPlayer*)player eventType:(AVPEventType)eventType{
switch(eventType){
case AVPEventPrepareDone:{
// The preparation is complete.
}
break;
case AVPEventAutoPlayStart:
// The autoplay starts.
break;
case AVPEventFirstRenderedStart:
// The first frame is rendered.
break;
case AVPEventCompletion:
// The playback is complete.
break;
case AVPEventLoadingStart:
// The buffering starts.
break;
case AVPEventLoadingEnd:
// The buffering is complete.
break;
case AVPEventSeekEnd:
// The seeking is complete.
break;
case AVPEventLoopingStart:
// The loop playback starts.
break;
default:
break;
}
}
/**
@brief Callback for the current playback position.
@param player The player pointer.
@param position The current playback position.
*/
- (void)onCurrentPositionUpdate:(AliPlayer*)player position:(int64_t)position {
// Update the progress bar.
}
/**
@brief Callback for the buffered position.
@param player The player pointer.
@param position The current buffered position.
*/
- (void)onBufferedPositionUpdate:(AliPlayer*)player position:(int64_t)position {
// Update the buffering progress.
}
/**
@brief Callback for track information.
@param player The player pointer.
@param info An array of track stream information. See AVPTrackInfo.
*/
- (void)onTrackReady:(AliPlayer*)player info:(NSArray<AVPTrackInfo*>*)info {
// Obtain multi-bitrate information.
}
/**
@brief Callback for displaying a caption.
@param player The player pointer.
@param index The index of the displayed caption.
@param subtitle The string of the displayed caption.
*/
- (void)onSubtitleShow:(AliPlayer*)player index:(int)index subtitle:(NSString *)subtitle {
// Obtain and display the caption.
}
/**
@brief Callback for hiding a caption.
@param player The player pointer.
@param index The index of the displayed caption.
*/
- (void)onSubtitleHide:(AliPlayer*)player index:(int)index {
// Hide the caption.
}
/**
@brief Callback for taking a snapshot.
@param player The player pointer.
@param image The image.
*/
- (void)onCaptureScreen:(AliPlayer *)player image:(UIImage *)image {
// Preview and save the snapshot.
}
/**
@brief Callback for when a track switch is complete.
@param player The player pointer.
@param info The information about the track to which the player is switched. See AVPTrackInfo.
*/
- (void)onTrackChanged:(AliPlayer*)player info:(AVPTrackInfo*)info {
// Notification for the result of a bitrate switch.
}Listen to playback status
Use this listener to monitor the player status. The onPlayerStatusChanged callback returns the current status of the player. The following code provides an example:
- (void)onPlayerStatusChanged:(AliPlayer*)player oldStatus:(AVPStatus)oldStatus newStatus:(AVPStatus)newStatus {
switch (newStatus) {
case AVPStatusIdle:{
// Idle
}
break;
case AVPStatusInitialzed:{
// Initialized
}
break;
case AVPStatusPrepared:{
// Prepared
}
break;
case AVPStatusStarted:{
// Playing
}
break;
case AVPStatusPaused:{
// Paused
}
break;
case AVPStatusStopped:{
// Stopped
}
break;
case AVPStatusCompletion:{
// Playback complete
}
break;
case AVPStatusError:{
// Playback error
}
break;
default:
break;
}
}Set display modes
The ApsaraVideo Player SDK for iOS lets you configure display settings such as fill, rotation, and mirroring.
Fill
The SDK supports three fill modes: aspect fit, aspect fill, and stretch to fill. Use the scalingMode property to set the fill mode.
// Set to aspect fit. Scales the video proportionally to fit within the view without distortion.
self.player.scalingMode = AVP_SCALINGMODE_SCALEASPECTFIT;
// Set to aspect fill. Scales the video proportionally to fill the view without distortion.
self.player.scalingMode = AVP_SCALINGMODE_SCALEASPECTFILL;
// Set to stretch to fill. Stretches the video to fill the view. This may cause distortion if the video and view aspect ratios differ.
self.player.scalingMode = AVP_SCALINGMODE_SCALETOFILL;Setting the fill mode does not affect Picture-in-Picture (PiP).
Rotation
You can rotate the video image by a specified angle. Use the rotateMode property to set the rotation angle.
// Set the image to rotate 0 degrees clockwise.
self.player.rotateMode = AVP_ROTATE_0;
// Set the image to rotate 90 degrees clockwise.
self.player.rotateMode = AVP_ROTATE_90;
// Set the image to rotate 180 degrees clockwise.
self.player.rotateMode = AVP_ROTATE_180;
// Set the image to rotate 270 degrees clockwise.
self.player.rotateMode = AVP_ROTATE_270;Mirroring
The SDK supports horizontal mirroring, vertical mirroring, and no mirroring. Use the mirrorMode property to set the mirror mode.
// Set to no mirroring.
self.player.mirrorMode = AVP_MIRRORMODE_NONE;
// Set to horizontal mirroring.
self.player.mirrorMode = AVP_MIRRORMODE_HORIZONTAL;
// Set to vertical mirroring.
self.player.mirrorMode = AVP_MIRRORMODE_VERTICAL;Get playback information
The ApsaraVideo Player SDK for iOS lets you retrieve the current playback progress, duration, and buffer progress.
Get the current playback progress
The current playback progress is the current point in time during playback. Retrieve this value from the position parameter in the onCurrentPositionUpdate callback. The following example shows how.
- (void)onCurrentPositionUpdate:(AliPlayer*)player position:(int64_t)position {
// The position is the current playback progress in milliseconds.
NSString *position = [NSString stringWithFormat:@"%lld, position"];
}Get the playback duration
The playback duration is the total length of the video. Retrieve this value after the video is loaded, such as after the onPrepared callback. The value is in milliseconds. The following example shows how.
-(void)onPlayerEvent:(AliPlayer*)player eventType:(AVPEventType)eventType {
switch (eventType) {
case AVPEventPrepareDone: {
if (self.player.duration >= 0) {
NSString *duration = self.player.duration;
}
}
break;
default:
break;
}
}Get the actual playback duration
You can retrieve the actual playback duration in real time. This value excludes time spent on pauses or stuttering. The following example shows how.
NSString *duration = [player getPlayedDuration];Get the buffer progress
You can retrieve the current buffer progress of the video from the position parameter in the onBufferedPositionUpdate callback. The following example shows how.
- (void)onBufferedPositionUpdate:(AliPlayer*)player position:(int64_t)position {
NSString *bufferPosition = position;
}Get the real-time rendering frame rate, audio and video bitrates, and network download bitrate
The following example shows how to retrieve these values.
// Get the current rendering frame rate. The data type is Float.
[self.player getOption:AVP_OPTION_RENDER_FPS]
// Get the bitrate of the video that is playing. The data type is Float. The unit is bps.
[self.player getOption:AVP_OPTION_VIDEO_BITRATE]
// Get the bitrate of the audio that is playing. The data type is Float. The unit is bps.
[self.player getOption:AVP_OPTION_AUDIO_BITRATE]
// Get the current network download bitrate. The data type is Float. The unit is bps.
[self.player getOption:AVP_OPTION_DOWNLOAD_BITRATE]Set the volume
Volume settings include volume adjustment and mute settings.
Volume adjustment
You can adjust the volume level. The supported range is from 0 to 2. A value greater than 1 is not recommended because it may cause noise. This action is implemented by the volume API. After you set the volume, you can also retrieve the current volume level. The following is an example:
// The value of volume is a real number from 0 to 2.
self.player.volume = 1.0f;
// Retrieve the volume information.
self.player.volume
Mute settings
You can mute the video during playback. This action is implemented by the muted API. The following is an example:
self.player.muted = YES;
Variable speed playback
The ApsaraVideo Player software development kit (SDK) for iOS supports variable speed playback for videos. Set the rate method to adjust the playback speed from 0.5 to 5 times the normal speed. The audio pitch remains unchanged. The following code provides an example:
// Set the playback speed. Supported speeds range from 0.5 to 5.0. Set the speed in increments of 0.5, such as 0.5, 1.0, and 1.5.
self.player.rate = 1.0f;Multiple definition settings
For detailed code examples, see the Multi-bitrate/resolution switching (MultiResolution) module in API-Example. This sample project for the ApsaraVideo Player SDK for iOS is based on Objective-C and demonstrates how to integrate the core features of the SDK.
Live streaming playback using UrlSource
For more information, see Standard live streaming playback.
VOD playback using Vid (VidAuth or VidSts)
No extra settings are required for playback using Vid (VidAuth or VidSts). The ApsaraVideo Player SDK for iOS obtains the list of definitions from the video-on-demand (VOD) service. The SDK supports retrieving and switching between definitions. This feature is not supported for playback using UrlSource.
Obtain definitions
After the video loads, you can retrieve the available definitions. The onTrackReady callback provides the info parameter, which contains the trackBitrate for each definition.
- (void)onTrackReady:(AliPlayer*)player info:(NSArray<AVPTrackInfo*>*)info {
for (int i=0; i<info.count; i++) {
AVPTrackInfo* track = [info objectAtIndex:i];
switch (track.trackType) {
case AVPTRACK_TYPE_VIDEO: {
int trackBitrate = track.trackBitrate;
}
break;
}
}
}Switch definitions
Call the selectTrack method and pass the index of the corresponding TrackInfo.
[self.player selectTrack:index];Definition switching notifications
The onTrackChanged callback is triggered after the definition is switched.
- (void)onTrackChanged:(AliPlayer*)player info:(AVPTrackInfo*)info {
// The switch is complete.
}Fast switching mode
After you enable fast switching mode, calls to selectTrack respond more quickly.
AVPConfig *config = [self.player getConfig];
config.selectTrackBufferMode = 1;
[self.player setConfig:config];Loop playback
The ApsaraVideo Player SDK for iOS provides a loop playback feature. You can call loop to enable loop playback. After playback is complete, the video automatically restarts from the beginning. The following code provides an example:
self.player.loop = YES;The AVPEventLoopingStart callback notifies you when a loop starts. The following code provides an example:
- (void)onPlayerEvent:(AliPlayer*)player eventType:(AVPEventType)eventType {
switch (eventType) {
case AVPEventLoopingStart:
break;
}
}Switch audio tracks
The ApsaraVideo Player SDK for iOS provides a feature to switch audio tracks. This is useful in scenarios where users watch videos with multi-language dubbing and want to switch the audio language.
Usage notes
You can switch audio tracks in streams that are not used for list playback such as MP4 streams, single-bitrate mixed HLS streams, audio tracks in single-bitrate HLS streams, and substreams in multi-bitrate mixed HLS streams. The following table describes different types of video streams.
Type | Video stream suffix | Bitrate quantity | M3U8 file quantity | Substream type | Description |
Non-list stream (such as MP4 stream) | .mp4 | 1 | - | A stream that contains a video track, multiple audio tracks, and multiple subtitle tracks. | You can switch between audio tracks. |
Single-bitrate mixed HLS stream | .m3u8 | 1 | 1 | A stream that contains a video track, multiple audio tracks, and multiple subtitle tracks. | You can switch between audio tracks. |
Single-bitrate HLS stream | .m3u8 | 1 | n | An M3U8 stream that contains only video tracks, audio tracks, or subtitle tracks. | You can switch between audio tracks. |
Multi-bitrate mixed HLS stream | .m3u8 | n | n | An M3U8 stream that contains a video track, multiple audio tracks, and multiple subtitle tracks. The bitrate of the substreams are different. | You can switch between different substreams. You cannot switch between the audio tracks of a substream. |
Examples
Set the callback.
// The onSubTrackReady callback. This usually occurs before the prepare callback. - (void)onSubTrackReady:(AliPlayer*)player info:(NSArray<AVPTrackInfo*>*)info { // Call getSubMediaInfo to get the MediaInfo. You must call this method after you receive the onSubTrackReady callback. Otherwise, the result is empty. AVPMediaInfo* subMediaInfo = [player getSubMediaInfo]; // Traverse for (int i=0; i<subMediaInfo.tracks.count; i++) { AVPTrackInfo* track = [mediaInfo.tracks objectAtIndex:i]; // Get the corresponding track. } }Switch the audio track.
[self.player selectTrack:myTrack.trackIndex accurate:YES]
Use thumbnails
For detailed code samples, see the Video Thumbnail Preview module in API-Example. This project is an Objective-C sample project for the ApsaraVideo Player SDK for iOS. It demonstrates how to integrate the core features of the SDK.
Before using thumbnails in the ApsaraVideo Player SDK, ensure that thumbnails are configured for your video. This requires that sprites have been generated for the video. In the ApsaraVideo VOD console, create a sprite snapshot template. Then, use a workflow to process the video with this template and generate the sprite data. For more information, see Video snapshots. The following sample code shows how to use thumbnails in the ApsaraVideo Player SDK:
/**
Specifies whether the current track has a thumbnail. If not, the thumbnail is not displayed.
*/
@property (nonatomic,assign)BOOL trackHasThumbnai;
/**
Creates a custom view to display the thumbnail.
*/
@property (nonatomic,strong)UIImageView *thumbnaiView;
/**
@brief: The callback for obtaining track information.
@param player: The player pointer.
@param info: An array of track stream information. For more information, see AVPTrackInfo.
*/
- (void)onTrackReady:(AliPlayer*)player info:(NSArray<AVPTrackInfo*>*)info {
AVPMediaInfo* mediaInfo = [player getMediaInfo];
if ((nil != mediaInfo.thumbnails) && (0 < [mediaInfo.thumbnails count])) {
[self.player setThumbnailUrl:[mediaInfo.thumbnails objectAtIndex:0].URL];
self.trackHasThumbnai = YES;
}else {
self.trackHasThumbnai = NO;
}
}
/**
The callback for a progress bar change.
@param playerView The player view.
@param value: The progress value.
*/
- (void)AVPPlayerView:(AVPPlayerView *)playerView progressSliderValueChanged:(CGFloat)value {
if (self.trackHasThumbnai) {
[self.player getThumbnail:self.player.duration*value];
}
}
/**
@brief: The callback for when a thumbnail is successfully obtained.
@param positionMs: The specified thumbnail position.
@param fromPos: The start position of the thumbnail.
@param toPos: The end position of the thumbnail.
@param image: The thumbnail image pointer. This is an NSImage pointer for macOS or a UIImage pointer for iOS.
*/
- (void)onGetThumbnailSuc:(int64_t)positionMs fromPos:(int64_t)fromPos toPos:(int64_t)toPos image:(id)image {
self.thumbnaiView.hidden = NO;
[self.thumbnaiView setImage:(UIImage *)image];
}
/**
@brief: The callback for when a thumbnail fails to be obtained.
@param positionMs: The specified thumbnail position.
*/
- (void)onGetThumbnailFailed:(int64_t)positionMs {
self.thumbnaiView.hidden = YES;
}Note: If a video is played using a URL, the preceding code cannot directly display the thumbnail. This is because the onTrackReady callback does not support MediaInfo callbacks for URL-based playback. In this case, you must specify the thumbnail URL directly.
/**
Specifies whether the current track has a thumbnail. If not, the thumbnail is not displayed.
*/
@property (nonatomic,assign)BOOL trackHasThumbnai;
/**
Creates a custom view to display the thumbnail.
*/
@property (nonatomic,strong)UIImageView *thumbnaiView;
/**
onPrepare
*/
- (void)onPlayerStatusChanged:(AliPlayer*)player oldStatus:(AVPStatus)oldStatus newStatus:(AVPStatus)newStatus {
if(newStatus == AVPStatusPrepared){
[self.player setThumbnailUrl:[URL]; // Generate the specific thumbnail URL based on the console API.
self.trackHasThumbnai = YES;
}
}
/**
The callback for a progress bar change.
@param playerView The player view.
@param value: The progress value.
*/
- (void)AVPPlayerView:(AVPPlayerView *)playerView progressSliderValueChanged:(CGFloat)value {
if (self.trackHasThumbnai) {
[self.player getThumbnail:self.player.duration*value];
}
}
/**
@brief: The callback for when a thumbnail is successfully obtained.
@param positionMs: The specified thumbnail position.
@param fromPos: The start position of the thumbnail.
@param toPos: The end position of the thumbnail.
@param image: The thumbnail image pointer. This is an NSImage pointer for macOS or a UIImage pointer for iOS.
*/
- (void)onGetThumbnailSuc:(int64_t)positionMs fromPos:(int64_t)fromPos toPos:(int64_t)toPos image:(id)image {
self.thumbnaiView.hidden = NO;
[self.thumbnaiView setImage:(UIImage *)image];
}
/**
@brief: The callback for when a thumbnail fails to be obtained.
@param positionMs: The specified thumbnail position.
*/
- (void)onGetThumbnailFailed:(int64_t)positionMs {
self.thumbnaiView.hidden = YES;
}Get SDK logs
The ApsaraVideo Player SDK generates detailed logs during runtime. These logs record runtime events, such as the status of network requests, results of system calls, and permission requests. You can view these logs to debug code or troubleshoot issues and to improve development efficiency.
Method 1: Get Player SDK logs from the console of a development tool
Use this method if you can reproduce the issue and collect logs on your local machine.
Enable logging and set the log level.
// Enable logging. [AliPlayer setEnableLog:YES]; // Set the log level. The default level is LOG_LEVEL_INFO. To troubleshoot issues, set the level to LOG_LEVEL_TRACE. [AliPlayer setLogCallbackInfo:LOG_LEVEL_INFO callbackBlock:nil];Set frame-level logging.
// Set frame-level log printing. // For the value option, 0 means disabled and 1 means enabled. [AliPlayer setLogOption:FRAME_LEVEL_LOGGING_ENABLED value:value];NoteUse the frame-level logging feature mainly for troubleshooting.
Collect logs.
Method 1: View logs in the console
After you reproduce the issue, retrieve the logs from the console of your development tool, such as Xcode.
Method 2: Output logs to a file in a custom path
After you enable logging and before you create a player instance, set a custom path in the sandbox to generate the log file.
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; // logFilePath is an example path. You can create a custom file, such as xxxx.log, in the sandbox. NSString *logFilePath = [documentDirectory stringByAppendingPathComponent:@"xxxx.log"];Write the log information to the custom file.
freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+", stdout); freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+", stderr);After you reproduce the issue, retrieve the generated
.logfile from the custom path.
Method 2: Use LogCallback to listen for Player SDK output logs
Use this method if the issue occurs on the user's device and you cannot reproduce it or collect logs on your local machine. Use LogCallback to listen for the output logs from the ApsaraVideo Player SDK. The logs are then automatically sent to your app's log channel.
Enable logging and set the log level.
// Enable logging. [AliPlayer setEnableLog:YES]; // Set the log level. The default level is LOG_LEVEL_INFO. To troubleshoot issues, set the level to LOG_LEVEL_TRACE. [AliPlayer setLogCallbackInfo:LOG_LEVEL_INFO callbackBlock:^(AVPLogLevel logLevel, NSString *strLog) { NSLog(@"strLog:%@", strLog); }];Collect logs.
After the issue is reproduced, the logs are automatically sent to your app's log file through your app's log channel.