本文提供iOS播放器進階功能的使用示例,完整功能使用說明參見API說明。
播放
短視頻列表播放
針對典型的短視頻列表播放場景,iOS播放器SDK提供了完善的列表播放功能,結合預加載等機制大幅改善短視頻的起播速度。長視頻場景不建議使用該功能。
操作步驟
創建播放器。
創建AliListPlayer播放器。示例如下:
self.listPlayer = [[AliListPlayer alloc] init]; [listPlayer setTraceID:@"xxxxxx"]; //TraceID為設備或用戶的唯一標識符,通常為imei或idfa
可選:設置監聽器。
創建列表播放時,監聽器為非必須配置,但如果不設置,將無法收到播放器的播放失敗、播放進度等事件通知,因此,建議您設置。
播放器支持設置多個監聽器,其中
onPlayerEvent
、onError
較為重要,建議您設置。/** @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 { // 切換碼率結果通知 } //...
設置預加載個數。
合理設置預加載個數,能夠有效的提高起播的速度。示例如下:
//設置預加載個數。總共加載的個數為: 1 + count*2。 self.listplyer.preloadCount = 2;
添加或移除多個播放源。
列表播放支持兩種播放源: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沒有格式限制,可以是任意的字符串。
設置顯示View。
如果播放源有畫面,需要設置View到播放器中,用來顯示畫面。示例代碼如下:
self.listPlayer.playerView = self.simplePlayScrollView.playView;
播放視頻源。
添加了一個或多個播放源之后,調用
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;
播放上一個、下一個視頻。
調用
moveTo
播放某個視頻源后,調用moveToPrev
,moveToNext
接口以moveTo
的視頻源為錨點進行播放上一個,下一個視頻。示例如下:說明在基于同一個
view
的情況下,調用moveto
或者moveToNext
等切換視頻源操作時,會出現閃爍黑屏的情況。此時建議在listPlayer
初始化時,配置PlayerConfig
的clearShowWhenStop
字段為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;
可選:使用預渲染實例提升視頻切換的順暢度。
說明iOS播放器SDK 5.5.2.0及以上版本才支持本功能,并且需要開啟本地緩存,開啟方法請參見本地緩存。
iOS播放器SDK從5.5.2.0版本開始提供
getPreRenderPlayer
和moveToNextWithPrerendered
接口,用于提升滑動切換到下一個視頻播放時的順暢度,根據您的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的代碼實現,具體如下:
創建渲染View。
如果使用UIScrollView控制,則需要使用多個playerView,有幾個播放源就需要設置幾個playerView,然后分別在moveToNext、moveToPre的時候重新設置playerView。
如果使用UITableView控制,建議設置適量的cell,每個cell中需要有一個playerView。
修改切換播放源的邏輯。
從iOS播放器SDK 5.5.2.0版本開始,會增加對
preRenderPlayer
的調用,因此需要單獨對當前要渲染的playerView進行設置。其中,moveToNext
、moveToPre
的邏輯有所差異。示例代碼如下: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];
可選:修改滑動播放的邏輯。
支持通過修改滑動播放的邏輯,實現在滑動切換視頻時,當滑動到下一個視頻的一半畫面出現時,開始播放下一個視頻。通過監聽
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視頻作為禮物特效可以提供更好的動效質量,較小的文件體積,更高的兼容性和更高的開發效率。這使得禮物特效能夠更好地展示給用戶,提升用戶體驗。
更好的動效質量:MP4視頻可以保留原始的動效質量,包括細節和顏色等,相比于其他格式,如 APN 或IXD,MP4可以更準確地還原設計師創作的動效效果。
較小的文件體積:MP4視頻文件相比于其他格式,如APNG或IXD,可以更有效地壓縮文件體積,提升加載速度并降低網絡帶寬消耗。
更高的兼容性:MP4視頻是一種通用的視頻格式,在各種設備和瀏覽器中都得到廣泛支持,支持在主流設備上播放和觀看禮物特效。
更高的開發效率:使用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種格式的字幕。示例如下:
創建顯示字幕的View。
根據不同的字幕格式創建不同的View。
// 初始化自定義subTitleLabel UILabel *subTitleLabel = [[UILabel alloc] initWithFrame:frame]; // 將字幕添加至自定義的superView,superView是用戶自定義的界面存在的父視圖 [superView addSubview:subTitleLabel];
設置字幕相關監聽。
//外掛字幕被添加 - (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]; }
添加字幕。
[self.player addExtSubtitle:URL];
切換字幕。
[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參數。示例如下:
畫中畫
畫中畫功能的環境要求: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
頭文件的內容。
增加畫中畫代理回調監聽。
[self.player setPictureinPictureDelegate:self];
實現代理配置。
增加全局變量,用于控制播放器的狀態變更。
// 監聽畫中畫當前是否是暫停狀態 @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;
監聽播放事件狀態變更回調接口時,主動調用下述方法更新畫中畫控制器相關狀態。
- (void)onPlayerStatusChanged:(AliPlayer*)player oldStatus:(AVPStatus)oldStatus newStatus:(AVPStatus)newStatus { self.currentPlayerStatus = newStatus; if (_pipController) { [self.pipController invalidatePlaybackState]; } }
監聽播放事件回調接口時,主動調用下述方法更新畫中畫控制器相關狀態。
- (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]; } } }
設置監聽。
監聽畫中畫即將啟動回調
/** @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方式播放。可參考:http://m.bestwisewords.com/document_detail/57294.html
@param source AVPVidAuthSource的輸入類型
@see AVPVidAuthSource
*/
- (void)setAuthSource:(AVPVidAuthSource*)source;
用法說明
通過其中的VidPlayerConfigGenerator接口的addVidPlayerConfigByStringValue添加playDomain字段。
VidPlayerConfigGenerator* gen = [[VidPlayerConfigGenerator alloc]init];
//增加playDomain字段,可以添加的字段參考
//http://m.bestwisewords.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
控制。示例如下:
開啟或關閉單個URL的本地緩存
如果想要針對單個URL關閉本地緩存功能,可以在player config
中設置。示例如下:
大緩存
通過設置數據的最大緩沖區時長可以在播放視頻時通過緩存視頻數據到內存中,從而提高播放性能和觀看體驗。當最大緩沖區時長設置過大時,會造成緩沖區對內存的消耗。通過啟用大緩存,可以將視頻數據緩存到文件中,從而降低內存的占用,進一步提高播放器性能。
當mMaxBufferDuration設置超過50000 ms時,通過開啟本地緩存觸發大緩存功能自動啟用。操作流程如下:
開啟全局本地緩存。
本地緩存功能默認關閉,如需使用,需要手動開啟。通過
AliPlayerGlobalSettings
中的enableLocalCache
控制。代碼示例請參見本地緩存中的開啟本地緩存。開啟URL的本地緩存。
代碼示例請參見本地緩存中的開啟或關閉單個URL的本地緩存。
預加載
iOS播放器SDK提供預加載功能,是對本地緩存功能的升級,通過設置視頻緩存的內存占用大小,更能提升視頻的起播速度。
預加載功能的使用限制如下:
目前支持MP4、MP3、FLV、HLS等單個媒體文件的加載。
僅支持UrlSource播放方式播放視頻的預加載,暫不支持VidAuth、VidSts方式播放視頻的預加載。
iOS播放器SDK默認提供預加載時網絡資源自動調度能力,以減少預加載的網絡請求對正在播放視頻的網絡請求的影響。自動調度的策略是:僅當正在播放的視頻緩沖到達一定閾值后,才會允許預加載進行請求。若您需要自行控制預加載的實時請求,可以通過以下方法將此策略關閉:
[AliPlayerGlobalSettings enableNetworkBalance:false];
開啟本地緩存功能,詳細操作請參見本地緩存。
獲取AliMediaLoader實例。
AliMediaLoader實例為單例,即無論獲取多少次,創建的都是同一個實例。
[AliMediaLoader shareInstance];
配置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
可選:刪除加載文件。
可按需刪除加載文件,以節省空間。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方式支持視頻下載功能。
使用播放器的視頻下載功能,需要在點播控制臺開啟并配置下載模式,詳細操作請參見離線下載。
視頻下載支持斷點續傳。
操作步驟
可選:配置安全下載的加密校驗文件。僅安全下載需要配置,普通下載無需配置。
說明請確保配置的加密校驗文件與App信息一致,否則會導致視頻下載失敗。
如果設置為安全下載方式,則需要將在點播控制臺生成的密鑰文件配置到播放器SDK中,用于視頻下載和播放的解密驗證,密鑰文件的生成請參見開啟安全下載。
建議在Application中配置一次即可,示例如下:
NSString *encrptyFilePath = [[NSBundle mainBundle] pathForResource:@"encryptedApp" ofType:@"dat"]; [AliPrivateService initKey:encrptyFilePath];
創建并設置下載器。
示例如下:
AliMediaDownloader *downloader = [[AliMediaDownloader alloc] init]; [downloader setSaveDirectory:self.downLoadPath]; [downloader setDelegate:self];
設置監聽事件。
下載器提供了多個事件監聽。示例如下:
-(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 { //下載成功 }
準備下載源。
通過
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];
準備成功后,選擇下載項。
準備成功后,會回調
onPrepared
方法。返回的TrackInfo中會包含各視頻流的清晰度等信息,請選擇一個Track進行下載,示例如下:-(void)onPrepared:(AliMediaDownloader *)downloader mediaInfo:(AVPMediaInfo *)info { NSArray<AVPTrackInfo*>* tracks = info.tracks; //比如:下載第一個TrackInfo [downloader selectTrack:[tracks objectAtIndex:0].trackIndex]; }
更新下載源并開始下載。
為了防止VidSts和VidAuth過期,建議更新下載源的信息后開始下載。示例如下:
//更新下載源 [downloader updateWithVid:vidSource] //開始下載 [downloader start];
下載成功或失敗后,釋放下載器。
下載成功后,調用
destroy
釋放下載器。[self.downloader destroy]; self.downloader = nil;
視頻加密播放
點播視頻支持HLS標準加密、阿里云私有加密和DRM加密,直播視頻僅支持DRM加密。加密播放請參見如何播放加密視頻。
Native RTS播放
iOS播放器SDK集成Native RTS SDK實現Native端低延時直播功能,詳情請參見阿里云播放器SDK集成Native RTS SDK實現說明(iOS端)。
異常處理
使用阿里云播放器播放視頻發生異常時,可借助單點探查功能快速定位問題,詳細內容,請參見單點追查。