进阶功能

本文提供iOS播放器进阶功能的使用示例,完整功能使用说明参见API说明。

播放

短视频列表播放

针对典型的短视频列表播放场景,iOS播放器SDK提供了完善的列表播放功能,结合预加载等机制大幅改善短视频的起播速度。长视频场景不建议使用该功能。

操作步骤

  1. 创建播放器。

    创建AliListPlayer播放器。示例如下:

    self.listPlayer = [[AliListPlayer alloc] init];
    [listPlayer setTraceID:@"xxxxxx"];  //TraceID为设备或用户的唯一标识符,通常为imei或idfa
  2. 可选:设置监听器。

    创建列表播放时,监听器为非必须配置,但如果不设置,将无法收到播放器的播放失败、播放进度等事件通知,因此,建议您设置。

    播放器支持设置多个监听器,其中onPlayerEventonError较为重要,建议您设置。

    /**
     @brief 错误代理回调
     @param player 播放器player指针
     @param errorModel 播放器错误描述,参考AliVcPlayerErrorModel
     */
    - (void)onError:(AliPlayer*)player errorModel:(AVPErrorModel *)errorModel {
        //提示错误,及stop播放
    }
    /**
     @brief 播放器事件回调
     @param player 播放器player指针
     @param eventType 播放器事件类型,@see AVPEventType
     */
    -(void)onPlayerEvent:(AliPlayer*)player eventType:(AVPEventType)eventType {
        switch (eventType) {
            case AVPEventPrepareDone: {
                // 准备完成
            }
                break;
            case AVPEventAutoPlayStart:
                // 自动播放开始事件
                break;
            case AVPEventFirstRenderedStart:
                // 首帧显示
                break;
            case AVPEventCompletion:
                // 播放完成
                break;
            case AVPEventLoadingStart:
                // 缓冲开始
                break;
            case AVPEventLoadingEnd:
                // 缓冲完成
                break;
            case AVPEventSeekEnd:
                // 跳转完成
                break;
            case AVPEventLoopingStart:
                // 循环播放开始
                break;
            default:
                break;
        }
    }
    /**
     @brief 视频当前播放位置回调
     @param player 播放器player指针
     @param position 视频当前播放位置
     */
    - (void)onCurrentPositionUpdate:(AliPlayer*)player position:(int64_t)position {
        // 更新进度条
    }
    /**
     @brief 视频缓存位置回调
     @param player 播放器player指针
     @param position 视频当前缓存位置
     */
    - (void)onBufferedPositionUpdate:(AliPlayer*)player position:(int64_t)position {
        // 更新缓冲进度
    }
    /**
     @brief 获取track信息回调
     @param player 播放器player指针
     @param info track流信息数组,参考AVPTrackInfo
     */
    - (void)onTrackReady:(AliPlayer*)player info:(NSArray<AVPTrackInfo*>*)info {
        // 获取多码率信息
    }
    /**
     @brief 字幕显示回调
     @param player 播放器player指针
     @param index 字幕显示的索引号
     @param subtitle 字幕显示的字符串
     */
    - (void)onSubtitleShow:(AliPlayer*)player index:(int)index subtitle:(NSString *)subtitle {
        // 获取字幕进行显示
    }
    /**
     @brief 字幕隐藏回调
     @param player 播放器player指针
     @param index 字幕显示的索引号
     */
    - (void)onSubtitleHide:(AliPlayer*)player index:(int)index {
        // 隐藏字幕
    }
    /**
     @brief 获取截图回调
     @param player 播放器player指针
     @param image 图像
     */
    - (void)onCaptureScreen:(AliPlayer *)player image:(UIImage *)image {
        // 预览,保存截图
    }
    /**
     @brief track切换完成回调
     @param player 播放器player指针
     @param info 切换后的信息,可参考AVPTrackInfo
     */
    - (void)onTrackChanged:(AliPlayer*)player info:(AVPTrackInfo*)info {
        // 切换码率结果通知
    }
    //...
  3. 设置预加载个数。

    合理设置预加载个数,能够有效的提高起播的速度。示例如下:

    //设置预加载个数。总共加载的个数为: 1 + count*2。
    self.listplyer.preloadCount = 2;
  4. 添加或移除多个播放源。

    列表播放支持两种播放源:VidSts播放和UrlSource播放。Url为视频的播放地址,vid为点播视频的音视频ID(VideoId)。示例如下:

    • Url:播放地址可以是第三方点播地址或阿里云点播服务中的播放地址。

      阿里云播放地址可以调用获取音视频播放地址接口获取。建议您集成点播服务端SDK来获取音视频播放地址,免去自签名的麻烦。调用接口获取音视频播放地址的示例请参见开发者门户

    • Vid:音视频ID,可以在音视频上传完成后通过控制台(路径:媒资库 > 音/视频。)或服务端接口(SearchMedia - 搜索媒体信息)获取。

    //添加vid播放源
    [self.listPlayer addVidSource:videoId uid:UUIDString];
    //添加URL播放源
    [self.listPlayer addUrlSource:URL uid:UUIDString];
    //移除某个源
    [self.listPlayer removeSource:UUIDString];
    说明
    • 不支持VidAuth播放。

    • uid是视频的唯一标志。用于区分视频是否一样。如果uid一样,则认为视频是一样的。如果播放出现串流的情况,请注意查看是不是在不同的界面设置了同一个uid。uid没有格式限制,可以是任意的字符串。

  5. 设置显示View。

    如果播放源有画面,需要设置View到播放器中,用来显示画面。示例代码如下:

    self.listPlayer.playerView = self.simplePlayScrollView.playView;
  6. 播放视频源。

    添加了一个或多个播放源之后,调用moveTo便可以自动播放某个视频源。示例如下:

    //UrlSource播放方式时使用此接口
    - (BOOL) moveTo:(NSString*)uid;
    //VidSts播放方式时使用此接口,需要传递STS临时凭证和临时AK对,请提前获取,获取方式请参见创建RAM角色并进行STS临时授权。
    - (BOOL) moveTo:(NSString*)uid accId:(NSString*)accId accKey:(NSString*)accKey token:(NSString*)token region:(NSString*)region;
  7. 播放上一个、下一个视频。

    调用moveTo播放某个视频源后,调用moveToPrevmoveToNext接口以moveTo的视频源为锚点进行播放上一个,下一个视频。示例如下:

    说明

    在基于同一个view的情况下,调用moveto或者moveToNext等切换视频源操作时,会出现闪烁黑屏的情况。此时建议在listPlayer初始化时,配置PlayerConfigclearShowWhenStop字段为false,并调用setConfig使其生效。

    UrlSource播放源
    //移动到下一个视频。
    - (BOOL) moveToNext;
    //移动到上一个视频。
    - (BOOL) moveToPre;
    VidSts播放源
    //移动到下一个视频。
    - (BOOL) moveToNext:(NSString*)accId accKey:(NSString*)accKey token:(NSString*)token region:(NSString*)region;
    // 移动到上一个视频。
    - (BOOL) moveToPre:(NSString*)accId accKey:(NSString*)accKey token:(NSString*)token region:(NSString*)region;
  8. 可选:使用预渲染实例提升视频切换的顺畅度。

    说明

    iOS播放器SDK 5.5.2.0及以上版本才支持本功能,并且需要开启本地缓存,开启方法请参见本地缓存

    iOS播放器SDK从5.5.2.0版本开始提供getPreRenderPlayermoveToNextWithPrerendered接口,用于提升滑动切换到下一个视频播放时的顺畅度,根据您的SDK集成场景不同,其使用方法有所差异,具体如下:

    全新集成5.5.2.0及以后版本

    使用PreRenderPlayer来实现。示例代码如下:

    AliPlayer *prePlayer = [self.listPlayer getPreRenderPlayer];
    if (prePlayer != nil) {
        prePlayer.autoPlay = YES;
            prePlayer.playerView  = playerView;
            [prePlayer prepare];
    
      [self.listPlayer moveToNextWithPrerendered];
    }

    从低版本升级至5.5.2.0及以后版本

    您需要修改低版本SDK的代码实现,具体如下:

    1. 创建渲染View。

      • 如果使用UIScrollView控制,则需要使用多个playerView,有几个播放源就需要设置几个playerView,然后分别在moveToNext、moveToPre的时候重新设置playerView。

      • 如果使用UITableView控制,建议设置适量的cell,每个cell中需要有一个playerView。

    2. 修改切换播放源的逻辑。

      从iOS播放器SDK 5.5.2.0版本开始,会增加对preRenderPlayer的调用,因此需要单独对当前要渲染的playerView进行设置。其中,moveToNextmoveToPre的逻辑有所差异。示例代码如下:

      • moveToNext

        // moveToNext时,先判断当前是否有预渲染prePlayer
        AliPlayer *prePlayer = [self.listPlayer getPreRenderPlayer];
        if (prePlayer) {
            prePlayer.autoPlay = YES;
            prePlayer.playerView = playerView;
            [prePlayer prepare];
        } else {
            self.listPlayer.playerView = playerView;
        }
        
        if (prePlayer) {
        [self.listPlayer moveToNextWithPrerendered];
        } else {
        [self.listPlayer moveToNext];
        }
      • moveToPre

        // moveToPre时,先设置playerView,再调用moveToPre
        [self.listPlayer getCurrentPlayer].playerView = playerView;
        [self.listPlayer moveToPre];
    3. 可选:修改滑动播放的逻辑。

      支持通过修改滑动播放的逻辑,实现在滑动切换视频时,当滑动到下一个视频的一半画面出现时,开始播放下一个视频。通过监听UIScrollViewDelegate中的滑动回调,当playerView出现在屏幕一半时,切换播放源,并设置一个全局的currentIndex承接滑动index变化,示例代码如下:

      - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
      CGFloat offsetY = scrollView.contentOffset.y;
      if (offsetY < 0) {
      return;
      }
      
      NSInteger index = lroundf(offsetY/[UIScreen mainScreen].bundle.size.height);
      if (self.currentIndex != index) {
      if (offsetY - CGRectGetMinY(currentPlayView.frame) >= [UIScreen mainScreen].bundle.size.height / 2.0) {
      self.currentIndex = index;
      // 执行moveToNext
      } else if (CGRectGetMinY(currentPlayView.frame) - offsetY >= [UIScreen mainScreen].bundle.size.height / 2.0) {
      self.currentIndex = index;
      // 执行moveToPre
      }
      }
      }

播放带透明度视频

功能简介

阿里云播放器SDK支持渲染Alpha通道,实现播放透明礼物的动态效果。在直播间等场景中,播放透明礼物动效且不会遮挡直播间内容,明显提升用户观看和互动体验。

使用限制

一体化SDK6.8.0及以后版本或播放器SDK6.9.0及以后版本支持透明渲染能力。

功能优势

使用带有透明度信息的MP4视频作为礼物特效可以提供更好的动效质量,较小的文件体积,更高的兼容性和更高的开发效率。这使得礼物特效能够更好地展示给用户,提升用户体验。

  1. 更好的动效质量:MP4视频可以保留原始的动效质量,包括细节和颜色等,相比于其他格式,如 APN 或IXD,MP4可以更准确地还原设计师创作的动效效果。

  2. 较小的文件体积:MP4视频文件相比于其他格式,如APNG或IXD,可以更有效地压缩文件体积,提升加载速度并降低网络带宽消耗。

  3. 更高的兼容性:MP4视频是一种通用的视频格式,在各种设备和浏览器中都得到广泛支持,支持在主流设备上播放和观看礼物特效。

  4. 更高的开发效率:使用MP4视频作为礼物特效的技术方案相对简单,不需要开发人员去研究和实现复杂的解析和渲染逻辑,开发人员可以专注于其他功能的实现,提高开发效率。

示例代码

新增如下接口:设置alpha模式(alpha通道在视频素材的方位:上、下、左、右),默认值是None。

说明
  • 素材的alpha通道的位置要与setAlphaRenderMode参数设置的一致。

  • playerview的大小要与素材的分辨率成比例。

/**
 @brief Alpha渲染模式,支持alpha在右侧、左侧、上侧、下侧,默认值无
 @see AVPAlphaRenderMode
 */
/****
 @brief Set a rendering mode. Support alpha at right, left, top and bottom. Default value is none.
 @see AVPAlphaRenderMode
 */
@property(nonatomic) AVPAlphaRenderMode alphaRenderMode;
//--------------View用法-------------
//对于View 需要设置clearColor
@property (weak, nonatomic) IBOutlet UIView *mediaPlayerView;
[self.aliplayerview setBackgroundColor:UIColor.clearColor];

//-----------AliPlayer用法-----------
//设置alpha模式
[self.aliplayer setAlphaRenderMode:AVP_RENDERMODE_ALPHA_AT_LEFT];
//设置alpha模式对应的素材
AVPUrlSource *source = [[AVPUrlSource alloc] urlWithString:@"https://alivc-player.oss-cn-shanghai.aliyuncs.com/video/%E4%B8%9A%E5%8A%A1%E9%9C%80%E6%B1%82%E6%A0%B7%E6%9C%AC/alpha%E9%80%9A%E9%81%93/alpha_left.mp4"];
[self.aliplayer setUrlSource:source];

//可选:单实例播放完成后如果有衔接问题,可以清屏
#pragma mark -- AVPDelegate
- (void)onPlayerEvent:(AliPlayer *)player eventType:(AVPEventType)eventType {
    switch (eventType) {
        case AVPEventCompletion:
        {
            [player clearScreen];
        }
            break;
        //...
    }
}

[self.aliplayer setAutoPlay: YES];
[self.aliplayer prepare];

Metal渲染

iOS播放器SDK支持使用Metal框架进行视频渲染。

说明

目前仅支持设置背景颜色、缩放模式和画中画功能。

配置项

/**
 @brief 视频渲染类型,0 表示默认渲染器;1 表示混合渲染器。默认值0
 */
/****
 @brief video renderType, 0 means default render; 1 means mixed render.
 */
@property(nonatomic, assign) int videoRenderType;

使用示例

AVPConfig *config = [self.player getConfig];
//使用metal渲染方式
config.videoRenderType = 1;
[self.player setConfig:config];
[self.player prepare];

外挂字幕

iOS播放器SDK支持添加和切换外挂字幕,现已支持SRT、SSA、ASS、VTT这4种格式的字幕。示例如下:

  1. 创建显示字幕的View。

    根据不同的字幕格式创建不同的View。

    // 初始化自定义subTitleLabel
    UILabel *subTitleLabel = [[UILabel alloc] initWithFrame:frame];
    // 将字幕添加至自定义的superView,superView是用户自定义的界面存在的父视图
    [superView addSubview:subTitleLabel];
  2. 设置字幕相关监听。

    展开查看代码

    //外挂字幕被添加
    - (void)onSubtitleExtAdded:(AliPlayer*)player trackIndex:(int)trackIndex URL:(NSString *)URL {}
    //字幕头信息回调
    - (void)onSubtitleHeader:(AliPlayer *)player trackIndex:(int)trackIndex Header:(NSString *)header{}
    //字幕显示回调
    - (void)onSubtitleShow:(AliPlayer*)player trackIndex:(int)trackIndex subtitleID:(long)subtitleID subtitle:(NSString *)subtitle {
     subTitleLabel.text =subtitle;
     subTitleLabel.tag =subtitleID;
    }
    //字幕隐藏回调
    - (void)onSubtitleHide:(AliPlayer*)player trackIndex:(int)trackIndex subtitleID:(long)subtitleID{
     [subTitleLabel removeFromSuperview];
    }
  3. 添加字幕。

    [self.player addExtSubtitle:URL];
  4. 切换字幕。

    [self.player selectExtSubtitle:trackIndexenable:YES];

纯音频播放

通过禁用视频播放,达到纯音频播放的效果。在prepare之前配置PlayerConfig。

AVPConfig *config = [self.player getConfig];
config.disableVideo = YES;
[self.player setConfig:config];

软硬解切换

iOS播放器SDK提供了H.264、H.265的硬解码能力,同时提供了enableHardwareDecoder提供开关。默认开,并且在硬解初始化失败时,自动切换为软解,保证视频的正常播放。示例如下:

//开启硬解,默认开启
self.player.enableHardwareDecoder = YES;

如果从硬解自动切换为软解,将会通过onPlayerEvent回调,示例如下:

-(void)onPlayerEvent:(AliPlayer*)player eventWithString:(AVPEventWithString)eventWithString description:(NSString *)description {
 if (eventWithString == EVENT_SWITCH_TO_SOFTWARE_DECODER) {
 //切换到软解
 }
}

网络自适应切换视频清晰度

说明
  • HLS的多码率自适应视频流可以在视频点播中经过视频打包转码模板组进行转码处理后生成,详细操作请参见点播多码率自适应配置

  • 经过视频点播转码生成的自适应流,如果使用Vid方式播放,则需要指定默认播放清晰度列表为AUTO,才会获取并播放自适应的视频流;否则将按照默认逻辑选择低清晰度的视频流进行播放,默认清晰度播放顺序请参见清晰度相关问题。以VidAuth播放方式为例,指定清晰度列表的示例如下:

    AVPVidAuthSource *authSource = [[AVPVidAuthSource alloc] init];
    authSource.definitions = @"AUTO";

iOS播放器SDK支持多码率自适应HLS、DASH视频流。在prepare成功之后,通过getMediaInfo可以获取到各个码流的信息,即TrackInfo。示例如下:

AVPMediaInfo *info = [self.player getMediaInfo];
NSArray<AVPTrackInfo*>* tracks = info.tracks;

在播放过程中,可以通过调用播放器的selectTrack方法切换播放的码流,取值为SELECT_AVPTRACK_TYPE_VIDEO_AUTO时,为多码率自适应。示例如下:

//多码率切换
[self.player selectTrack:track.trackIndex];
//多码率切换并自适应
[self.player selectTrack:SELECT_AVPTRACK_TYPE_VIDEO_AUTO];

切换的结果会在onTrackChanged监听之后会回调。示例如下:

- (void)onTrackChanged:(AliPlayer*)player info:(AVPTrackInfo*)info {
 if (info.trackType == AVPTRACK_TYPE_VIDEO) {
 // video changed
 }
 // etc
}

截图

iOS播放器SDK提供了对当前视频截图的功能,由snapshot接口实现。截取的是原始的数据,并转为bitmap返回。回调接口为onCaptureScreen。示例如下:

//截图回调
- (void)onCaptureScreen:(AliPlayer *)player image:(UIImage *)image {
 // 处理截图
}
//截取当前播放的画面
aliyunVodPlayer.snapshot();
说明

截图是不包含界面的。

试看

iOS播放器SDK通过配合点播服务配置,可以实现试看功能,支持VidSts和VidAuth(视频点播推荐使用此方式)两种播放方式。如何配置和使用试看功能,请参见试看视频

配置试看功能之后,通过VidPlayerConfigGen接口的setPreviewTime方法设置播放器的试看时长。以VidSts播放方式为例,示例如下:

AVPVidStsSource *source = [[AVPVidStsSource alloc] init];
....
VidPlayerConfigGenerator* vp = [[VidPlayerConfigGenerator alloc] init];
[vp setPreviewTime:20];//20秒试看
source.playConfig = [vp generatePlayerConfig];//设置给播放源
...

当设置试看的时长,通过iOS播放器SDK播放视频时,服务端将不会返回完整的视频内容,而是返回试看时间段的内容。

说明

VidPlayerConfigGen支持设置服务端支持的请求参数。请参见请求参数说明

设置Referer

iOS播放器SDK支持设置Referer,配合控制台的黑白名单Referer,可以控制访问权限,由AVPConfig方法设置请求Referer。iOS播放器SDK的设置示例如下:

//先获取配置
AVPConfig *config = [self.player getConfig];
//设置referer
config.referer = referer;
....//其他设置
//设置配置给播放器
[self.player setConfig:config];

设置UserAgent

iOS播放器SDK提供了AVPConfig用来设置请求UA。设置之后,播放器请求的过程中将会带上UA信息。示例如下:

//先获取配置
AVPConfig *config = [self.player getConfig];
//设置userAgent
config.userAgent = userAgent;
....//其他设置
//设置配置给播放器
[self.player setConfig:config];

配置网络重试时间和次数

支持设置iOS播放器SDK的网络超时的时间和重试次数,由AVPConfig方法实现。示例如下:

//先获取配置
AVPConfig *config = [self.player getConfig];
//设置网络超时时间,单位ms
config.networkTimeout = 5000;
//设置超时重试次数。每次重试间隔为networkTimeout。networkRetryCount=0则表示不重试,重试策略app决定,默认值为2
config.networkRetryCount = 2;
....//其他设置
//设置配置给播放器
[self.player setConfig:config];
说明
  • 如果设置了networkRetryCount:如此时发生网络问题,导致出现loading后,那么将会重试networkRetryCount次,每次的间隔时间为networkTimeout。

  • 如果重试多次之后,还是loading的状态,那么就会回调onError事件,此时AVPErrorModel.code为ERROR_LOADING_TIMEOUT。

  • 如果networkRetryCount设置为0,当网络重试超时的时候,播放器就会回调onPlayerEvent,参数eventWithString为EVENT_PLAYER_NETWORK_RETRY。此时,可以调用播放器的reload方法进行重新加载网络,或者进行其他的处理。

配置缓存和延迟控制

对于播放器来说,缓存的控制非常重要。合理的配置可以有效的加快起播速度并减少卡顿。iOS播放器SDK通过AVPConfig提供了设置缓存和延迟的控制接口。示例如下:

展开查看代码

//先获取配置
AVPConfig *config = [self.player getConfig];
//最大延迟。注意:直播有效。当延时比较大时,播放器SDK内部会追帧等,保证播放器的延时在这个范围内。
config.maxDelayTime = 5000;
// 最大缓冲区时长。单位ms。播放器每次最多加载这么长时间的缓冲数据。
config.maxBufferDuration = 50000;
//高缓冲时长。单位ms。当网络不好导致加载数据时,如果加载的缓冲时长到达这个值,结束加载状态。
config.highBufferDuration = 3000;
// 起播缓冲区时长。单位ms。这个时间设置越短,起播越快。也可能会导致播放之后很快就会进入加载状态。
config.startBufferDuration = 500;
//其他设置
//设置配置给播放器
[self.player setConfig:config];
说明
  • 三个缓冲区时长的大小关系必须为:startBufferDuration ≤ highBufferDuration ≤ maxBufferDuration。

  • 当最大缓冲区时长(mMaxBufferDuration)大于5分钟时,为防止因为缓冲区过大导致的内存异常,系统将默认按5分钟生效。当mMaxBufferDuration设置超过50000 ms(即50s)时,可以启用大缓存,来降低内存占用,进一步提高播放性能,如有需要,请参见大缓存

设置HTTP Header

通过AVPConfig方法,可以给播放器中的请求加上HTTP的header参数。示例如下:

展开查看代码

//先获取配置
AVPConfig *config = [self.player getConfig];
//定义header
NSMutableArray *httpHeaders = [[NSMutableArray alloc] init];
//比如使用httpdns时,需要设置Host。
[httpHeaders addObject:@"Host:example.com"];
//设置header
config.httpHeaders = httpHeaders;
....//其他设置
//设置配置给播放器
[self.player setConfig:config];

画中画

说明
  • 画中画功能的环境要求:iOS系统版本为iOS 15及以后、iOS播放器SDK版本为5.4.9.0及以后。

  • 5.5.2.0之前版本的iOS播放器SDK,画中画仅提供开启和关闭画中画的调用方法,以及进入后台展示画中画视框;从5.5.2.0版本开始支持从外部设置画中画代理,从而支持更加个性化的画中画功能开发。

  • 如需画中画功能生效, 请确保手机设置中的画中画功能已开启(设置 > 通用 > 画中画)。

开启画中画

开启画中画功能后,当应用退到后台时,视频会以画中画的形式在小窗口继续播放;当应用切回到前台时,视频恢复成原来的播放形式继续播放。画中画通过setPictureInPictureEnable开关控制,如果要开启画中画功能,需要在AVPEventPrepareDone的状态下进行。开启画中画功能的示例如下:

展开查看代码

- (void)onPlayerEvent:(AliPlayer *)player eventType:(AVPEventType)eventType {
 switch (eventType) {
 case AVPEventPrepareDone:
 {
 [self.player setPictureInPictureEnable:YES];
 }
 break;
 default:
 break;
 }
}
说明

当播放器调用stop停止播放时,此时画中画视窗已不需要,需要先通过setPictureInPictureEnable开关关闭画中画后,再调用stop

设置画中画代理

下述仅提供部分常用的画中画视窗和播放器视窗进行交互操作的代码示例,包含显示画中画的暂停、播放、快进、快退按钮以及重新播放的逻辑,具体代理方法请参考播放器SDK Demo中SDK文件夹中AliyunPlayer.framework的AliPlayerPictureInPictureDelegate.h头文件的内容。

  1. 增加画中画代理回调监听。

    [self.player setPictureinPictureDelegate:self];
  2. 实现代理配置。

    1. 增加全局变量,用于控制播放器的状态变更。

      展开查看代码

      // 监听画中画当前是否是暂停状态
      @property (nonatomic, assign) BOOL isPipPaused;
      // 监听播放器当前的播放状态,通过监听播放事件状态变更newStatus回调设置
      @property (nonatomic, assign) AVPStatus currentPlayerStatus;
      // 设置画中画控制器,在画中画即将启动的回调方法中设置,并需要在页面准备销毁时主动将其设置为nil,建议设置
      @property (nonatomic, strong) AVPictureInPictureController *pipController;
      // 监听播放器当前播放进度,currentPosition设置为监听视频当前播放位置回调中的position参数值
      @property(nonatomic, assign) int64_t currentPosition;
    2. 监听播放事件状态变更回调接口时,主动调用下述方法更新画中画控制器相关状态。

      展开查看代码

      - (void)onPlayerStatusChanged:(AliPlayer*)player oldStatus:(AVPStatus)oldStatus newStatus:(AVPStatus)newStatus {
       self.currentPlayerStatus = newStatus;
      
       if (_pipController) {
       [self.pipController invalidatePlaybackState];
       }
      }
    3. 监听播放事件回调接口时,主动调用下述方法更新画中画控制器相关状态。

      展开查看代码

      - (void)onPlayerEvent:(AliPlayer*)player eventType:(AVPEventType)eventType {
       if (eventType == AVPEventCompletion) {
       if (_pipController) {
       self.isPipPaused = YES; // 播放结束后,将画中画状态变更为暂停
       [self.pipController invalidatePlaybackState];
       }
       } else if (eventType == AVPEventSeekEnd) {
       // 跳转完成
       if (_pipController) {
       [self.pipController invalidatePlaybackState];
       }
       }
      }
    4. 设置监听。

      • 监听画中画即将启动回调

        展开查看代码

        /**
         @brief 画中画即将启动
         @param pictureInPictureController 画中画控制器
         */
        - (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
         if (!_pipController) {
         self.pipController = pictureInPictureController;
         }
         self.isPipPaused = !(self.currentPlayerStatus == AVPStatusStarted);
         [pictureInPictureController invalidatePlaybackState];
        }
      • 监听画中画准备停止回调

        展开查看代码

        /**
         @brief 画中画准备停止
         @param pictureInPictureController 画中画控制器
         */
        - (void)pictureInPictureControllerWillStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
         self.isPipPaused = NO;
         [pictureInPictureController invalidatePlaybackState];
        }
      • 监听画中画停止前告诉代理恢复用户回调

        展开查看代码

        /**
         @brief 在画中画停止前告诉代理恢复用户接口
         @param pictureInPictureController 画中画控制器
         @param completionHandler 调用并传值YES以允许系统结束恢复播放器用户接口
         */
        - (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler {
         if (_pipController) {
         _pipController = nil;
         }
         completionHandler(YES);
        }
      • 监听设置画中画当前可播放视频的时间范围回调

        展开查看代码

        /**
         @brief 通知画中画控制器当前可播放的时间范围
         @param pictureInPictureController 画中画控制器
         @return 当前可播放的时间范围
         */
         - (CMTimeRange)pictureInPictureControllerTimeRangeForPlayback:(nonnull AVPictureInPictureController *)pictureInPictureController layerTime:(CMTime)layerTime{
         Float64 current64 = CMTimeGetSeconds(layerTime);
        
         Float64 start;
         Float64 end;
        
         if (currentPosition <= self.player.duration) {
         double curPostion = self.currentPosition / 1000.0;
         double duration = self.player.duration / 1000.0;
         double interval = duration - curPostion;
         start = current64 - curPostion;
         end = current64 + interval;
         CMTime t1 = CMTimeMakeWithSeconds(start, layerTime.timescale);
         CMTime t2 = CMTimeMakeWithSeconds(end, layerTime.timescale);
         return CMTimeRangeFromTimeToTime(t1, t2);
         } else {
         return CMTimeRangeMake(kCMTimeNegativeInfinity, kCMTimePositiveInfinity);
         }
        }
      • 监听设置画中画是否为暂停或播放状态回调

        展开查看代码

        /**
         @brief 将暂停或播放状态反映到UI上
         @param pictureInPictureController 画中画控制器
         @return 暂停或播放
         */
        - (BOOL)pictureInPictureControllerIsPlaybackPaused:(nonnull AVPictureInPictureController *)pictureInPictureController{
         return self.isPipPaused;
        }
      • 监听画中画点击快进或快退按钮回调,同步播放器状态

        展开查看代码

        /**
         @brief 点击快进或快退按钮
         @param pictureInPictureController 画中画控制器
         @param skipInterval 快进或快退的事件间隔
         @param completionHandler 一定要调用的闭包,表示跳转操作完成
         */
         - (void)pictureInPictureController:(nonnull AVPictureInPictureController *)pictureInPictureController skipByInterval:(CMTime)skipInterval completionHandler:(nonnull void (^)(void))completionHandler {
         int64_t skipTime = skipInterval.value / skipInterval.timescale;
         int64_t skipPosition = self.currentPosition + skipTime * 1000;
         if (skipPosition < 0) {
         skipPosition = 0;
         } else if (skipPosition > self.player.duration) {
         skipPosition = self.player.duration;
         }
         [self.player seekToTime:skipPosition seekMode:AVP_SEEKMODE_INACCURATE];
         [pictureInPictureController invalidatePlaybackState];
        }
      • 监听画中画点击暂停或播放按钮回调,需要执行的操作

        展开查看代码

        /**
         @brief 点击画中画暂停按钮
         @param pictureInPictureController 画中画控制器
         @param playing 是否正在播放
         */
        - (void)pictureInPictureController:(nonnull AVPictureInPictureController *)pictureInPictureController setPlaying:(BOOL)playing {
         if (!playing){
         [self.player pause];
         self.isPipPaused = YES;
         } else {
         // 建议:如果画中画播放完成,需要重新播放,可额外执行下面if语句的代码
         if (self.currentPlayerStatus == AVPStatusCompletion) {
         [self.player seekToTime:0 seekMode:AVP_SEEKMODE_ACCURATE];
         }
        
         [self.player start];
         self.isPipPaused = NO;
         }
         [pictureInPictureController invalidatePlaybackState];
        }

RTS降级播放

在使用超低延时直播RTS地址播放的场景下,通过设置RTS的降级地址(如HLS地址或FLV地址),当RTS拉流失败时,会自动降级到该地址播放。

//设置降级源downgradeUrl
AVPUrlSource *urlSource = [[AVPUrlSource alloc] urlWithString:downgradeUrl];
//可选,配置config其他项
AVPConfig *config = [self.player getConfig];
//设置降级URL
[self.player enableDowngrade:urlSource config:config];

设置视频背景色

iOS播放器SDK支持设置播放器渲染的背景色。接口和用法说明如下:

接口示例

/**
 @brief 设置视频的背景色
 @param color  the color
 */
/****
 @brief Set video background color
 @param color  the color
 */
-(void) setVideoBackgroundColor:(UIColor *)color;

用法说明

//参数为8位16进制数据,8位数据两两为一组,按照顺序分别表示R(red) G(green) B(blue) A(alpha 透明度)
//例如0x00ff00ff,表示绿色
[aliPlayer setVideoBackgroundColor:0x00ff00ff]

vidAuth设置指定播放域名

通过vidAuth方式可以指定vid对应的域名等字段,支持的字段详情请参见GetPlayInfo请求参数。接口及用法说明如下:

接口示例

/**
 @brief 使用vid+playauth方式播放。可参考:https://help.aliyun.com/document_detail/57294.html
 @param source AVPVidAuthSource的输入类型
 @see AVPVidAuthSource
 */
- (void)setAuthSource:(AVPVidAuthSource*)source;

用法说明

通过其中的VidPlayerConfigGenerator接口的addVidPlayerConfigByStringValue添加playDomain字段。

VidPlayerConfigGenerator* gen = [[VidPlayerConfigGenerator alloc]init];
//增加playDomain字段,可以添加的字段参考
//https://help.aliyun.com/zh/vod/developer-reference/api-vod-2017-03-21-getplayinfo?spm=a2c4g.11186623.0.0.2bec2e44eqeDgx#api-detail-35
[gen addVidPlayerConfigByStringValue:@"playDomain" value: @"com.xxx.xxx"];
[source setPlayConfig:[gen generatePlayerConfig]];
[self.player setAuthSource:source]:

后台解码

播放器SDK自6.12.0版本开始支持后台解码能力,开启本功能后,当播放器在后台时,依然可以进行视频流的解码、播放以及回调。使用示例如下:

//值为1表示进行后台解码,值为0表示不进行后台解码,默认值为0
[self.player setOption:ALLOW_DECODE_BACKGROUND valueInt:1];

性能

本地缓存

iOS播放器SDK提供了本地缓存的功能,能够让用户重复播放视频时,提高起播速度、提高seek速度、减少卡顿,也能达到节省流量的目的。

开启本地缓存

本地缓存功能默认关闭,如需使用,需要手动开启。通过AliPlayerGlobalSettings中的enableLocalCache控制。示例如下:

展开查看代码

/**
 * 开启本地缓存,开启之后,就会缓存到本地文件中。
 * @param enable:本地缓存功能开关。true:开启,false:关闭,默认关闭。
 * @param maxBufferMemoryKB:5.4.7.1及以后版本已废弃,暂无作用。
 * @param localCacheDir:必须设置,本地缓存的文件目录,为绝对路径。
 */
[AliPlayerGlobalSettings enableLocalCache:true maxBufferMemoryKB:1024 localCacheDir:@""];

/**
 @brief 本地缓存文件自动清理相关的设置。
 @param expireMin:5.4.7.1及以后版本已废弃,暂无作用。
 @param maxCapacityMB:最大缓存容量。单位:兆,默认值20GB,在清理时,如果缓存总容量超过此大小,则会以cacheItem为粒度,按缓存的最后时间排序,一个一个的删除最旧的缓存文件,直到小于等于最大缓存容量。
 @param freeStorageMB:磁盘最小空余容量。单位:兆,默认值0,在清理时,同最大缓存容量,如果当前磁盘容量小于该值,也会按规则一个一个的删除缓存文件,直到freeStorage大于等于该值或者所有缓存都被清理掉。
 */
[AliPlayerGlobalSettings setCacheFileClearConfig:0 maxCapacityMB:0 freeStorageMB:0];

/**
 * 获取加载url的hash值回调,用来做url唯一的id,必须要保证每个url都不一样。
 */

// 需要自己实现这个函数并把函数指针交给setCacheUrlHashCallback
static NSString *CaheUrlHashHandle(NSString *url) {
 return @"xxx";
}

[AliPlayerGlobalSettings setCacheUrlHashCallback:&CaheUrlHashHandle];
说明
  • 如果视频播放URL带有鉴权参数,本地缓存和播放时鉴权参数会变化,可以将URL的鉴权参数去掉后再计算md5值。例如:带有鉴权参数的视频播放URL为http://****.mp4?aaa,则加载时使用http://****.mp4计算md5值。

  • 如果服务器同时支持HTTP和HTTPS协议,但是不同的协议指向的媒体文件是同一个,则可以将请求头去掉或者统一后再计算md5值。例如:

    • 视频播放URL为https://****.mp4http://****.mp4,则加载时使用****.mp4计算md5值。

    • 视频播放URL为https://****.mp4,加载时统一为http://****.mp4后再计算md5值。

  • 针对5.5.4.0及以后版本的播放器SDK,如果视频播放URL带有鉴权参数且播放协议为HLS,可以通过设置AVPConfig.enableStrictAuthMode字段,进行不同鉴权模式的选择(默认值为false):

    • 非严格鉴权(false):鉴权也缓存,若上一次只缓存了部分媒体,下次播放至非缓存部分时,播放器会用缓存的鉴权发起请求,如果URL鉴权设置的有效期很短,会导致播放异常。

    • 严格鉴权(true):鉴权不缓存,每次起播都进行鉴权,无网络下会导致起播失败。

开启或关闭单个URL的本地缓存

如果想要针对单个URL关闭本地缓存功能,可以在player config中设置。示例如下:

展开查看代码

//先获取配置
AVPConfig *config = [self.player getConfig];
//是否针对播放的URL开启本地缓存,默认值为true。当AliPlayerGlobalSettings处的本地缓开启时,且同时开启此处的本地缓存,即设置为true,该URL的本地缓存才会生效;若此处设置为false,则关闭该URL的本地缓存。
config.enableLocalCache = false;
....//其他设置

//设置配置给播放器
[self.player setConfig:config];

大缓存

通过设置数据的最大缓冲区时长可以在播放视频时通过缓存视频数据到内存中,从而提高播放性能和观看体验。当最大缓冲区时长设置过大时,会造成缓冲区对内存的消耗。通过启用大缓存,可以将视频数据缓存到文件中,从而降低内存的占用,进一步提高播放器性能。

当mMaxBufferDuration设置超过50000 ms时,通过开启本地缓存触发大缓存功能自动启用。操作流程如下:

  1. 开启全局本地缓存。

    本地缓存功能默认关闭,如需使用,需要手动开启。通过AliPlayerGlobalSettings中的enableLocalCache控制。代码示例请参见本地缓存中的开启本地缓存

  2. 开启URL的本地缓存。

    代码示例请参见本地缓存中的开启或关闭单个URL的本地缓存

预加载

iOS播放器SDK提供预加载功能,是对本地缓存功能的升级,通过设置视频缓存的内存占用大小,更能提升视频的起播速度。

预加载功能的使用限制如下:

  • 目前支持MP4、MP3、FLV、HLS等单个媒体文件的加载。

  • 仅支持UrlSource播放方式播放视频的预加载,暂不支持VidAuth、VidSts方式播放视频的预加载。

说明

iOS播放器SDK默认提供预加载时网络资源自动调度能力,以减少预加载的网络请求对正在播放视频的网络请求的影响。自动调度的策略是:仅当正在播放的视频缓冲到达一定阈值后,才会允许预加载进行请求。若您需要自行控制预加载的实时请求,可以通过以下方法将此策略关闭:

[AliPlayerGlobalSettings enableNetworkBalance:false];
  1. 开启本地缓存功能,详细操作请参见本地缓存

  2. 获取AliMediaLoader实例。

    AliMediaLoader实例为单例,即无论获取多少次,创建的都是同一个实例。

    [AliMediaLoader shareInstance];
  3. 配置AliMediaLoader。

    展开查看代码

    //配置回调,并开始加载。
    // url:为视频文件地址。 duration:加载的时长大小,单位:毫秒。
    [[AliMediaLoader shareInstance] load:obj.url duration:1000];
    // 设置回调代理
    [[AliMediaLoader shareInstance] setAliMediaLoaderStatusDelegate:self];
    
    @protocol AliMediaLoaderStatusDelegate <NSObject>
    @optional
    
    /**
     @brief 错误回调
     @param url 加载url
     @param code 错误码
     @param msg 错误描述
     */
    - (void)onError:(NSString *)url code:(int64_t)code msg:(NSString *)msg;
    
    /**
     @brief 完成回调
     @param url 加载url
     */
    - (void)onCompleted:(NSString *)url;
    
    /**
     @brief 取消回调
     @param url 加载url
     */
    - (void)onCanceled:(NSString *)url;
    
    @end
  4. 可选:删除加载文件。

    可按需删除加载文件,以节省空间。iOS播放器SDK不提供删除接口,需要在App删除加载目录下的文件。

动态预加载

动态预加载策略,支持集成方既可以控制当前正在播放视频的缓存,又可以控制预加载的个数和缓存,满足业务方对播放体验与成本开销之间取得平衡的诉求。

展开查看代码

// 开启推荐配置和动态预加载
[self.listPlayer setScene:AVP_SHORT_VIDEO];

// 配置基准预加载时长
// 设置预加载时长为1000ms
AVPPreloadConfig *config = [[AVPPreloadConfig alloc] init];
config.preloadDuration = 1000;
[self.listPlayer updatePreloadConfig:config];

// 配置预加载的数量,支持双向
// 1为向前预加载的数量,3为向后预加载的数量
[self.listPlayer setPreloadCount:1 nextCount:3];

// 配置动态预加载的递减的offset
[self.listPlayer enableStrategy:AVP_STRATEGY_DYNAMIC_PRELOAD enable:true];
[self.listPlayer setStrategyParam:AVP_STRATEGY_DYNAMIC_PRELOAD strategyParam:@"{\"algorithm\": \"sub\",\"offset\": \"200\"}"];

获取下载速度

获取当前播放视频的下载速度,在onCurrentDownloadSpeed回调中获取speed。示例如下:

- (void)onCurrentDownloadSpeed:(AliPlayer *)player speed:(int64_t)speed{
 intspeed_=speed;
}

网络特性

HTTPDNS

HTTPDNS是通过DNS解析技术将域名解析请求发送到特定的HTTPDNS服务器,以获取更快、更稳定的域名解析结果,降低DNS劫持风险。

阿里云播放器SDK提供增强型HTTPDNS功能,专为阿里云CDN域名提供HTTPDNS服务,支持阿里云CDN网络精准调度、实时解析生效,有效提高网络性能。

说明

播放器SDK从6.7.0版本开始支持增强型HTTPDNS。6.7.0~6.11.0版本播放器SDK,请先提交工单或联系阿里云商务经理申请开通;6.12.0及以后版本无需申请,默认开启。

增强型HTTPDNS使用示例

增强型HTTPDNS仅为阿里云CDN域名提供HTTPDNS服务,请确保您配置的域名为阿里云CDN域名且已完成域名配置可正常使用。视频点播中添加和配置CDN域名请参见添加加速域名。更多有关CDN域名的信息请参见阿里云CDN

//打开增强型httpdns
[AliPlayerGlobalSettings enableEnhancedHttpDns:YES];
//可选,增加httpdns预解析域名
[[AliDomainProcessor shareInstance] addPreResolveDomain:@"player.***alicdn.com"];

HTTP/2

说明

iOS播放器SDK自5.5.0.0版本开始默认开启使用HTTP/2。

iOS播放器SDK支持使用HTTP/2协议,该协议通过多路复用,避免队头阻塞,以改善播放性能。示例如下:

[AliPlayerGlobalSettingssetUseHttp2:true];

HTTP预建连TCP

针对HTTP的视频播放请求(非HTTPS),通过提前建立TCP连接能够显著改善用户体验,降低网络连接耗时,确保播放的即时性与连续性,同时优化网络和系统资源的使用效率。使用方式如下:

// domain格式为host[:port],port可选,多个域名之间用分号(;)隔开
// 全局设置
// 全量接口每次设置后使用当前的字符串为准(多-新增,少-删除),字符串空为停止预建连
[AliPlayerGlobalSettings setOption:SET_PRE_CONNECT_DOMAIN value: @"domain1;domain2"];

视频下载

iOS播放器SDK提供了点播服务视频的下载功能,允许用户通过阿里云播放器将视频缓存至本地观看。同时,提供了普通下载和安全下载两种下载方式。

  • 普通下载:下载后的视频数据未经过阿里云加密,用户可以用第三方播放器播放。

  • 安全下载:下载后的视频数据经过阿里云加密。第三方播放器无法播放。仅支持使用阿里云的播放器进行播放。

使用说明

  • 仅VidSts和VidAuth方式支持视频下载功能。

  • 使用播放器的视频下载功能,需要在点播控制台开启并配置下载模式,详细操作请参见离线下载

  • 视频下载支持断点续传。

操作步骤

  1. 可选:配置安全下载的加密校验文件。仅安全下载需要配置,普通下载无需配置。

    说明

    请确保配置的加密校验文件与App信息一致,否则会导致视频下载失败。

    如果设置为安全下载方式,则需要将在点播控制台生成的密钥文件配置到播放器SDK中,用于视频下载和播放的解密验证,密钥文件的生成请参见开启安全下载

    建议在Application中配置一次即可,示例如下:

    NSString *encrptyFilePath = [[NSBundle mainBundle] pathForResource:@"encryptedApp" ofType:@"dat"];
    [AliPrivateService initKey:encrptyFilePath];
  2. 创建并设置下载器。

    示例如下:

    AliMediaDownloader *downloader = [[AliMediaDownloader alloc] init];
    [downloader setSaveDirectory:self.downLoadPath];
    [downloader setDelegate:self];
  3. 设置监听事件。

    下载器提供了多个事件监听。示例如下:

    -(void)onPrepared:(AliMediaDownloader *)downloader mediaInfo:(AVPMediaInfo *)info {
        //准备下载项成功
    }
    -(void)onError:(AliMediaDownloader *)downloader errorModel:(AVPErrorModel *)errorModel {
        //下载出错
    }
    -(void)onDownloadingProgress:(AliMediaDownloader *)downloader percentage:(int)percent {
        //下载进度百分比
    }
    -(void)onProcessingProgress:(AliMediaDownloader *)downloader percentage:(int)percent {
        //处理进度百分比
    }
    -(void)onCompletion:(AliMediaDownloader *)downloader {
        //下载成功
    }
  4. 准备下载源。

    通过prepare方法准备下载源,支持VidSts和VidAuth两种方式。示例如下:

    • VidSts

      //创建VidSts
      AVPVidStsSource* stsSource = [[AVPVidStsSource alloc] init];
      stsSource.region = @"接入地域"; // 点播服务的接入地域,默认为cn-shanghai。
      stsSource.vid = @"Vid信息"; // 视频ID(VideoId)。
      stsSource.securityToken = @"<yourSecurityToken>"; // STS安全令牌,需要调用STS服务的AssumeRole接口生成。
      stsSource.accessKeySecret = @"<yourAccessKeySecret>"; // STS临时AK对的访问密钥,需要调用STS服务的AssumeRole接口生成。
      stsSource.accessKeyId = @"<yourAccessKeyId>"; // STS临时AK对的访问密钥ID,需要调用STS服务的AssumeRole接口生成。
      //准备下载源
      [downloader prepareWithVid:stsSource];
    • VidAuth

      //创建VidAuth
      AVPVidAuthSource *authSource = [[AVPVidAuthSource alloc] init];
      authSource.vid = @"Vid信息"; // 视频ID(VideoId)。
      authSource.playAuth = @"<yourPlayAuth>"; // 播放凭证,需要调用点播服务的GetVideoPlayAuth接口生成。
      authSource.region = @"接入地域"; // 5.5.5.0及之后版本播放器SDK,本参数已弃用,无需设置region,播放器会自动解析region;5.5.5.0之前版本播放器SDK,本参数必选,点播服务的接入地域,默认为cn-shanghai。
      //准备下载源
      [downloader prepareWithVid:authSource];
  5. 准备成功后,选择下载项。

    准备成功后,会回调onPrepared方法。返回的TrackInfo中会包含各视频流的清晰度等信息,请选择一个Track进行下载,示例如下:

    -(void)onPrepared:(AliMediaDownloader *)downloader mediaInfo:(AVPMediaInfo *)info {
        NSArray<AVPTrackInfo*>* tracks = info.tracks;
        //比如:下载第一个TrackInfo
        [downloader selectTrack:[tracks objectAtIndex:0].trackIndex];
    }
  6. 更新下载源并开始下载。

    为了防止VidSts和VidAuth过期,建议更新下载源的信息后开始下载。示例如下:

    //更新下载源
    [downloader updateWithVid:vidSource]
    //开始下载
    [downloader start];
  7. 下载成功或失败后,释放下载器。

    下载成功后,调用destroy释放下载器。

    [self.downloader destroy];
    self.downloader = nil;

视频加密播放

点播视频支持HLS标准加密、阿里云私有加密和DRM加密,直播视频仅支持DRM加密。加密播放请参见如何播放加密视频

Native RTS播放

iOS播放器SDK集成Native RTS SDK实现Native端低延时直播功能,详情请参见阿里云播放器SDK集成Native RTS SDK实现说明(iOS端)

异常处理

使用阿里云播放器播放视频发生异常时,可借助单点探查功能快速定位问题,详细内容,请参见单点追查

相关文档