You need to enable JavaScript to run this app.
导航
基础功能
最近更新时间:2025.11.05 16:06:25首次发布时间:2021.02.23 10:42:41
复制全文
我的收藏
有用
有用
无用
无用

本文为您介绍如何使用 iOS 播放器 SDK 的基础功能。

播放控制

TTVideoEngine 支持播放、暂停、Seek、从指定时间启播、停止和关闭等播放控制功能。

播放

调用 play 方法开始播放:

// 开始播放
[self.engine play];

暂停

调用 pause 方法暂停播放。再次调用 play 方法,状态可由暂停恢复到播放。示例代码如下:

// 异步执行,避免阻塞主线程
[self.engine pause:YES]; 
// 播放器由暂停恢复到播放状态
[self.engine play];

从指定时间起播

在调用 play 前设置 startTime 指定开始播放时间点,可实现从指定时间点开始播放或跳过片头等功能。示例代码如下:

注意

如果您使用预渲染功能,需在 prepareToPlay 前设置。

// 上次播放进度,可实现从指定时间起播的功能
CGFloat startTime = 5.0f;
// 在 play 之前设置
[engine setOptionForKey:VEKKeyPlayerStartTime_CGFloat value:@(startTime)];

Seek 到指定位置播放

调用 play 后,通过 setCurrentPlaybackTime:complete: 方法,可以 Seek 到指定位置进行播放,实现拖拽进度条到指定时间开始播放的功能。示例代码如下:

// currentTime 需要快进/快退到某个时间点,单位为秒
[self.engine setCurrentPlaybackTime:currentTime complete:^(BOOL success) {
    /// seek 操作状态完成回调
    NSLog(@"seek complete %@", @(success));
} renderComplete:^{
    /// seek 渲染完成回调
    NSLog(@"seek render complete");
}];

停止

调用 stop 方法停止播放视频:

// 停止播放
[self.engine stop];

释放

调用 closeAysnc 方法异步释放播放器实例。示例代码如下:

// 异步关闭播放器,不影响主线程
[self.engine closeAysnc];
// 记得移除视图
[self.engine.playerView removeFromSuperview];
// engine实例置为空
self.engine = nil;

说明

  • 播放器释放后,不应该再调用任何方法。
  • 释放后可以将 engine 设置为 nil,防止再次调用。

纯音频播放

播放器 SDK 支持在播放视频时,只解码音频而不解码视频,适用于纯音频播放场景。相比您根据自身业务逻辑实现的纯音频播放,SDK 只解码音频会更省电。

注意

该功能仅高级版支持。请确保您已购买高级版的 License,详见播放器 License

// 开启纯音频播放,视频停止渲染
self.videoEngine.radioMode = YES;
// 恢复音视频播放,视频恢复渲染    
self.videoEngine.radioMode = NO;

播放 DASH 视频

SDK 支持 BASH(经火山引擎优化的升级版 DASH 协议)视频流的播放。播放前需开启以下 option:

[self.videoEngine setOptionForKey:VEKKeyPlayerBashEnabled_BOOL value:@(YES)];
[self.videoEngine setOptionForKey:VEKKeyPlayerDashEnabled_BOOL value:@(YES)];

播放 QUIC 视频

自 1.46.2.9 版本起,SDK 支持 QUIC 协议视频的播放。播放前需进行以下操作:

  1. 添加以下依赖:

    # Podfile
    pod 'TTSDK', '1.46.2.xxx' ,:subspecs => ['Player-Quic', 'Uploader']
    
  2. 初始化 QUIC 播放配置:

    // 开启 mdl 2.0
    [[TTVideoEngine ls_localServerConfigure] setOptionForKey:@(VEMDLKeyIsEnableMDL2_BOOL) value:@(YES)];
    // 开启 QUIC 下载器
    [TTVideoEngine.ls_localServerConfigure setOptionForKey:@(VEMDLKeyIsEnableTTNetDownloader_BOOL) value:@(YES)];
    
    TTSDKConfiguration *configuration = [TTSDKConfiguration defaultConfigurationWithAppID:appId licenseName:licenseName];
    
    TTSDKTTNetConfiguration* ttnetConfig = [[TTSDKTTNetConfiguration alloc] init];
    // 开启 QUIC
    ttnetConfig.shouldEnableQuic = YES;
    
    // 设置 QUIC 域名。如不设置,SDK 内部会自行探测。
    NSMutableDictionary* hints = [NSMutableDictionary dictionary];
    hints[@"xxx.xxx.com"] = @(443);
    ttnetConfig.quicHints = hints;
    configuration.ttnetConfiguration = ttnetConfig;
    
    [TTSDKManager startWithConfiguration:configuration];
    

设置显示模式

iOS 播放器 SDK 支持填充模式、旋转和镜像等显示模式。

填充模式

视频的比例和播放视图的比例不一致,就会造成视频拉伸变形的问题。您可以通过 ScaleMode 设置不同的填充模式。示例代码如下:

// 无拉伸,不会有变形,可能有黑边
[self.engine setOptionForKey:VEKKeyViewScaleMode_ENUM value:@(TTVideoEngineScalingModeNone)]; 
// 等比例适配,不会有变形,按照视频宽高等比适配画面,可能有黑边
[self.engine setOptionForKey:VEKKeyViewScaleMode_ENUM value:@(TTVideoEngineScalingModeAspectFit)]; 
// 等比例填充,不会有变形,按照视频宽高等比充满画面,可能有画面裁切
[self.engine setOptionForKey:VEKKeyViewScaleMode_ENUM value:@(TTVideoEngineScalingModeAspectFill)]; 
// 拉伸填充,视频宽高比例与画面比例不一致,会导致画面变形
[self.engine setOptionForKey:VEKKeyViewScaleMode_ENUM value:@(TTVideoEngineScalingModeFill)]; 

旋转

通过 RotateType 设置视频显示时的旋转角度,示例代码如下:

// 无旋转角度
[self.engine setOptionForKey:VEKKeyViewRotateType_ENUM value:@(TTVideoEngineRotateTypeNone)]; 
// 旋转 90 度
[self.engine setOptionForKey:VEKKeyViewRotateType_ENUM value:@(TTVideoEngineRotateType90)]; 
// 旋转 180 度
[self.engine setOptionForKey:VEKKeyViewRotateType_ENUM value:@(TTVideoEngineRotateType180)]; 
// 旋转 270 度
[self.engine setOptionForKey:VEKKeyViewRotateType_ENUM value:@(TTVideoEngineRotateType270)]; 

镜像

通过 MirrorType 设置视频镜像。支持水平镜像和垂直镜像。示例代码如下:

// 无镜像(默认)
[self.engine setOptionForKey:VEKKeyViewMirrorType_ENUM value:@(TTVideoEngineMirrorTypeNone)]; 
// 设置水平镜像
[self.engine setOptionForKey:VEKKeyViewMirrorType_ENUM value:@(TTVideoEngineMirrorTypeHorizontal)]; 
// 设置垂直镜像
[self.engine setOptionForKey:VEKKeyViewMirrorType_ENUM value:@(TTVideoEngineMirrorTypeVertical)]; 

获取视频宽高

获取视频宽高的方式有两种:

  • 方式一:通过接口主动获取。建议在 videoEnginePrepared 回调中获取,示例代码如下:

    // 获取视频时机建议在 videoEnginePrepared 回调中获取
    - (void)videoEnginePrepared:(TTVideoEngine *)videoEngine {
        // 获取视频宽
        NSInteger width = [[self.videoEngine getOptionBykey:VEKKEY(VEKGetKeyPlayerVideoWidth_NSInteger)] integerValue];
        // 获取视频高
        NSInteger height = [[self.videoEngine getOptionBykey:VEKKEY(VEKGetKeyPlayerVideoHeight_NSInteger)] integerValue];
    }
    
  • 方式二:通过实现 TTVideoEngineResolutionDelegate 协议回调获取

    // 通过 TTVideoEngineResolutionDelegate 协议回调获取视频宽高
    - (void)videoSizeDidChange:(TTVideoEngine *)videoEngine videoWidth:(NSInteger)videoWidth videoHeight:(NSInteger)videoHeight {
        // 业务逻辑
    }
    

截图

调用 snapshot 方法进行视频截图。可以在 completion block 中获取和处理截图生成的 UIImage 对象。方法声明如下所示:

- (void)snapshot:(void(^)(UIImage *))completion;

获取播放信息

iOS 播放器 SDK 支持获取当前播放进度、播放时长、缓存进度等播放信息。

当前播放进度

通过 currentPlaybackTime 获取当前播放位置:

// 单位为秒
NSTimeInterval currentPlaybackTime = self.engine.currentPlaybackTime;

播放时长

通过 duration 获取播放时长:

// 单位为秒
NSTimeInterval duration = self.engine.duration;

获取缓存进度

通过 playableDuration 获取缓存进度:

// 单位为秒
NSTimeInterval playableDuration = self.engine.playableDuration; 

播放状态监听

// 内部封装 NSTimer 定时器,方便您在获取播放进度时,您也可以自己实现
[self.engine addPeriodicTimeObserverForInterval:0.5  queue:dispatch_get_main_queue() usingBlock:^{
    /// 这里获取当前播放进度,播放时长,可播放时长在 UI 上展示
}];

// 播放停止时需要主动移除,避免产生内存泄漏
[self.engine removeTimeObserver];

循环播放

looping 设为 YES 开启循环播放。示例代码如下:

// 开启循环播放
self.engine.looping = YES; 

// 关闭循环播放
self.engine.looping = NO; 

倍速播放

通过 playbackSpeed 设置播放速度。默认值为 1,取值范围为(0,3]。示例代码如下:

// 默认为 1 倍速,取值范围(0,3]
self.engine.playbackSpeed = 1.0;

若需要播放倍速大于 3,需开启高倍速开关:

// 请在 play/prepare 前设置
[self.videoEngine setOptionForKey:VEKKeyPlaySpeedExtendEnable_BOOL value:@(1)];

设置音量

静音

// 打开静音
self.engine.muted = YES;
// 关闭静音
self.engine.muted = NO;

调节音量

// 建议使用系统音量方法进行调节。      
// 如果只想调整单个视频的音量,需要在 play 之前配置 AudioDevice
[self.engine setOptionForKey:VEKKeyPlayerAudioDevice_ENUM value:@(TTVideoEngineDeviceAudioGraph)];
// 音量设置
self.engine.volume = 1.0f;

Vid 播放源的多清晰度管理

Vid 模式下播放视频时,视频点播服务会下发多个清晰度的播放地址。播放器 SDK 通过 TTVideoEngineResolutionType 枚举(详见清晰度枚举)来统一管理所有清晰度档位。

获取清晰度列表

获取视频点播服务下发的所有清晰度信息:

获取可用清晰度列表

在播放器 SDK 成功获取到视频信息后(即触发 videoEngine:fetchedVideoModel: 回调),您可以通过 supportedResolutionTypes 获取当前视频支持的所有清晰度档位,用于构建 UI 上的选择列表。

- (void)videoEngine:(TTVideoEngine *)videoEngine fetchedVideoModel:(TTVideoEngineModel *)videoModel {
    // 获取视频点播服务下发的清晰度数组,可用于清晰度列表展示
    NSArray<NSNumber *> *allResolutions = [self.engine supportedResolutionTypes];
}

获取当前清晰度

在播放过程中的任何时刻,通过访问 currentResolution 属性即可获取当前正在播放的实际清晰度。

// 获取当前清晰度
TTVideoEngineResolutionType currentType = self.engine.currentResolution;

切换清晰度

无论是设置起播清晰度,还是在播放中切换,都统一使用 configResolution: 方法。

设置起播清晰度

在调用 play 方法前设置 configResolution:,即可指定初始播放的清晰度。您预设的起播清晰度可能不在视频实际支持的列表中。这种情况下,SDK 会自动向下查找最接近的可用档位进行播放。

[self.engine configResolution:TTVideoEngineResolutionTypeFullHD];

播放中切换清晰度

当用户从 UI 选择新的清晰度时,调用带有 completion block 的 configResolution:withCompletion: 方法发起切换请求,并处理切换结果。

NSArray<NSNumber *> *allResolutions = [self.engine supportedResolutionTypes];
// 目标切换的清晰度档位,这里举例取清晰度列表第一个档位作为要切换的目标档位
TTVideoEngineResolutionType targetResolution = [[allResolutions objectAtIndex:0] integerValue]; 
[self.engine configResolution:targetResolution withCompletion:^(BOOL success, NSError * _Nullable err, TTVideoEngineResolutionType completeResolution) {
    if (success) {
        NSLog(@"切换清晰度成功");
    } else {
        // NSError 的 code 中包含了具体的错误码
        // 错误码含义请参考:https://www.volcengine.com/docs/4/66441
        // 特别情况:分辨率切换因播放器状态异常导致未成功执行时,错误码为 -1
        // 回调可能在非 UI 线程触发,因此请勿在回调中直接执行涉及 UI 的操作。建议将 UI 操作放到 UI 线程中执行。
        NSLog(@"切换清晰度失败,错误码:%ld", err.code);
    }
}];

清晰度枚举

TTVideoEngineResolutionType 的枚举如下表所示。

Key

对应清晰度

视频描述

音频描述

TTVideoEngineResolutionTypeSD

360P

标清

普通音质

TTVideoEngineResolutionTypeHD

480P

高清

高音质

TTVideoEngineResolutionTypeFullHD

720P

超清

音乐音质

TTVideoEngineResolutionType1080P

1080P

1080P

原画

TTVideoEngineResolutionType2K

2K

2K

此档位对音频不生效

TTVideoEngineResolutionType4K

4K

4K

此档位对音频不生效

TTVideoEngineResolutionTypeAuto

自动调节

DASH 支持根据网速动态调节清晰度。不是 DASH 加密不建议设置这个参数。

此档位对音频不生效

开启平滑切换

针对视频点播服务生成的帧对齐的 MP4、HLS 视频,支持在播放过程中平滑切换多个分辨率的播放地址,提升用户的播放体验。以下示例代码演示如何在 Vid 模式下开启平滑切换:

注意

如需了解如何转码生成帧对齐视频以及在 DirectUrl 模式下开启平滑切换功能,可提交工单联系火山引擎技术支持。

// HLS 播放源平滑切换
[self.videoEngine setOptionForKey:VEKKeyPlayerHLSSeamlessSwitchEnable_BOOL value:@(YES)];
[self.videoEngine setOptionForKey:VEKKeyMasterm3u8OptimizeEnable_BOOL value:@(YES)];

// MP4 播放源平滑切换
[self.videoEngine setOptionForKey:VEKKeyPlayerBashEnabled_BOOL value:@(YES)];
[self.videoEngine setOptionForKey:VEKeyPlayerSegmentFormatFlag value:@(TTVideoEngineDashSegmentFlagFormatMp4 | TTVideoEngineDashSegmentFlagFormatFMP4)];

播放 HLS 视频

设置 URL 过期时间

如果您通过 DirectUrl 方式播放 HLS 视频,在设置播放源和预加载时均可以通过 urlExpiredTimes 参数设置过期时间。

  • 设置 DirectUrl 播放源时设置过期时间:

    // 设置播放源
    NSString *videoUrl = @"you video url";
    /// cacheKey 为该 url 对应的唯一标识,建议使用 url md5 值
    NSString *cacheKey = [videoUrl md5]; 
    TTVideoEngineUrlSource *urlSource = [[TTVideoEngineUrlSource alloc] initWithUrl:videoUrl cacheKey:cacheKey];
    NSString *expireTime1 = @"1693497600"; // 秒级时间戳
    urlSource.urlExpiredTimes = @[expireTime1]; // URL 过期时间戳字符串数组,单位为秒,UTC 时间,适配主、备播放地址。示例为只有一个播放地址的情况
    [self.engine setVideoEngineVideoSource:urlSource]; 
    [self.engine play];
    
  • 预加载场景中,在创建 TTVideoEnginePreloaderURLItem 时,通过 urlExpiredTimes 设置过期时间,然后按照预加载流程调用 ls_addTaskWithURLItem 完成预加载。示例代码如下:

    // 设置播放源信息
    NSString *videoUrl = @"you video url";
    /// cacheKey 为该 url 对应的唯一标识,建议使用 url md5 值
    NSString *cacheKey = [videoUrl md5]; 
    TTVideoEngineUrlSource *urlSource = [[TTVideoEngineUrlSource alloc] initWithUrl:videoUrl cacheKey:cacheKey];
    NSString *expireTime1 = @"1693497600"; // 秒级时间戳
    urlSource.urlExpiredTimes = @[expireTime1]; // URL 过期时间戳字符串数组,单位为秒,UTC 时间,适配主、备播放地址。示例为只有一个播放地址的情况
    TTVideoEnginePreloaderURLItem *item = [TTVideoEnginePreloaderURLItem urlItemWithVideoSource:urlSource preloadSize:800*1024];
    [TTVideoEngine ls_addTaskWithURLItem:item];
    
  • 判断过期时间是否设置成功:在 Debug 调试状态下查看日志,确认播放地址中是否包含 hlsproxyQuery 关键字。示例如下:

    hlsproxyQuery=expirteTime%03Dxxxxxxxxxx
    

播放 HLS 标准加密视频

服务端配置

在实现客户端播放逻辑前,请确保已满足以下服务端配置:

  1. 完成服务端配置:已参照 HLS 标准加密文档完成解密服务搭建、加密转码等所有准备工作。
  2. 设置正确的 FileType:与播放普通视频的关键不同在于,您的应用服务端在调用 GetPlayInfo 接口获取播放地址或签发 PlayAuthToken 时,必须将 FileType 参数设置为 standard_evideo(加密视频)或 standard_eaudio(加密音频)。

客户端实现

在此场景下,客户端的播放代码与播放普通 Vid 视频基本相同。SDK 内部会自动处理解密流程。若您开启了 HLS 标准加密改写功能,需要额外设置 urlExtendParams 属性传入鉴权参数 AppAuthToken

说明

若您开启 HLS 标准加密改写功能,在播放、下载和预加载的全链路中,都可以通过 urlExtendParams 参数传递 AppAuthToken

  • 播放时:在 TTVideoEngineVidSource 对象上设置。
  • 下载时:在 TTVideoEngineDownloadVidTask 对象上设置。
  • 预加载时
    • 自定义预加载:在 TTVideoEnginePreloaderVidItem 对象上设置 urlExtendParams 属性。
    • 预加载策略:您传递给预加载策略的 TTVideoEngineVidSource 实例也必须设置 urlExtendParams 属性。策略会读取此属性并将其应用到内部创建的预加载任务中。
// 1. 准备基础参数
NSString *vid = @"your_hls_encrypted_vid";
NSString *playAuthToken = @"your_play_auth_token";

// 2. 构造 Vid 播放源
TTVideoEngineVidSource *vidSource = [[TTVideoEngineVidSource alloc] initWithVid:vid playAuthToken:playAuthToken resolution:TTVideoEngineResolutionTypeAuto];

// 3. (按需配置) 处理 HLS 标准加密改写场景
// 如果开启了“HLS 标准加密改写”,需传入您的鉴权参数。
// SDK 会自动将这些参数拼接到 M3U8 文件的请求 URL 末尾。
// NSDictionary *authParams = @{ @"AppAuthToken": @"<your_token>" };
// vidSource.urlExtendParams = authParams; 

// 4. 设置播放源并播放
[self.engine setVideoEngineVideoSource:vidSource];
[self.engine play];

设置业务类型

业务类型(tag)用于区分同一应用(appid)内,不同类型的音视频。可以根据业务需要按视频场景、视频时长等划分,比如沉浸式 feed 流、短视频视频、长视频等。示例代码如下:

// 设置 Tag
[videoEngine setOptionForKey:VEKKeyLogTag_NSString value:@"tag"];

设置子业务类型

子业务类型 subtag 用于区分同一业务类型下的不同细分,比如加密视频、非加密加密、音频等。示例代码如下:

[videoEngine setOptionForKey:VEKKeyLogSubTag_NSString value:@"subtag"]; //设置 SubTag

屏幕常亮

视频播放状态控制屏幕常亮支持 2 种方式,设置系统 API 或者 SDK 提供的 API。实现的示例代码如下:

// 方式一,通过系统 API 设置
[UIApplication sharedApplication].idleTimerDisabled = YES;

// 方式二,通过 SDK 提供的 API 设置
[self.videoEngine setOptionForKey:VEKKeyPlayerIdleTimerAuto_NSInteger value:@(YES)];

播放状态回调

播放状态回调的示例代码如下:

// 播放状态修改时会触发该方法
- (void)videoEngine:(TTVideoEngine *)videoEngine playbackStateDidChanged:(TTVideoEnginePlaybackState)playbackState;
  
/**
 * @locale zh
 * @type callback
 * @brief 加载状态改变回调。
 * @notes 内部加载状态发生变化时 SDK 会触发此回调。您可以根据此回调显示或者隐藏 loading 视图。
 * @param videoEngine `videoEngine` 对象。
 * @param loadState 当前加载状态,详见 [TTVideoEngineLoadState](803941#TTVideoEngineLoadState) 。
 * @param extraInfo 额外信息:<br>
 *        - `TTVideoEngineBufferStartAction:@(TTVideoEngineStallActionNone)`: 导致出现卡顿的动作,详见 [TTVideoEngineStallAction](803941#TTVideoEngineStallAction) 。<br>
 *        - `TTVideoEngineBufferStartReason:@(TTVideoEngineStallReasonNetwork)`: 导致出现卡顿的具体原因,详见 [TTVideoEngineStallReason](803941#TTVideoEngineStallReason) 。
 */
- (void)videoEngine:(TTVideoEngine *)videoEngine
loadStateDidChanged:(TTVideoEngineLoadState)loadState
              extra:(nullable NSDictionary<NSString *,id> *)extraInfo {
    if (loadState == TTVideoEngineLoadStateStalled) {
        // 展示加载进度,进度 0%
    } else if (loadState == TTVideoEngineLoadStatePlayable) {
        // 移除加载进度展示,恢复播放,进度 100%
    }              
}

/**
 * @locale zh
 * @type callback
 * @brief 视频加载进度回调。
 * @notes 播放器加载视频进度发生变化时 SDK 会触发此回调。您可以根据此回调显示加载的进度。
 * @param videoEngine `videoEngine` 对象。
 * @param progress 当前加载进度,progress  范围  progress > 0 && progress <1
 */
- (void)videoEngine:(TTVideoEngine *)videoEngine
    loadingProgress:(CGFloat)progress {
    // 更新加载进度,progress 加载进度     
}
 
// 使用 videoId 播放方式,获取到 urls 有效信息回调
- (void)videoEngine:(TTVideoEngine *)videoEngine fetchedVideoModel:(TTVideoEngineModel *)videoModel;  
// 使用 videoId 播放方式,这个是通知具体使用 @TTVideoEngineURLInfo 信息
- (void)videoEngine:(TTVideoEngine *)videoEngine usingUrlInfos:(NSArray<TTVideoEngineURLInfo *> *)urlInfos;
  
// 播放器各个模块完成初始化,即将开始播放。
- (void)videoEnginePrepared:(TTVideoEngine *)videoEngine;
  
// 显示视频的首帧,可以根据该回调隐藏封面图,显示视频画面
- (void)videoEngineReadyToDisPlay:(TTVideoEngine *)videoEngine;
  
// 视频开始播放
- (void)videoEngineReadyToPlay:(TTVideoEngine *)videoEngine;

// SDK 内部在重试,@error 内部的错误信息
- (void)videoEngine:(TTVideoEngine *)videoEngine retryForError:(NSError *)error;
  
// 视频发生了卡顿
- (void)videoEngineStalledExcludeSeek:(TTVideoEngine *)videoEngine;
  
// 当前播放命中的缓存信息,key 对应缓存的唯一标识符
/// 如果视频做了预加载,cacheSize > 0,表示命中了预加载
- (void)videoEngine:(TTVideoEngine *)videoEngine mdlKey:(NSString *)key hitCacheSze:(NSInteger)cacheSize;
  
// 调用了播放器的 stop 方法,执行完毕回调该方法
- (void)videoEngineUserStopped:(TTVideoEngine *)videoEngine;
  
// 播放结束,@error 为空,正常播放结束,@error 不为空,播放失败,@error 对应具体的错误信息
- (void)videoEngineDidFinish:(TTVideoEngine *)videoEngine error:(nullable NSError *)error;
  
// 调用 closeAysnc , 执行完毕回调该方法
- (void)videoEngineCloseAysncFinish:(TTVideoEngine *)videoEngine;

展示当前视频下载速度

播放器 SDK 支持回调当前视频一段时间内获取的视频数据大小,可用来在视频的起播、Seek、卡顿等情况下展示当前视频下载速度。示例代码如下:

注意

该功能仅高级版支持。请确保您已购买高级版的 License,详见播放器 License

// 1. 设置 delegate
- (void)setPreloadDelegate {
    [TTVideoEngine ls_setPreloadDelegate:self];
}

// 2. 收到网络模块回调
- (void)localServerTestSpeedInfo:(NSTimeInterval)timeInternalMs size:(NSInteger)sizeByte {
    NSTimeInterval time = timeInternalMs / 1000; /// 间隔时间,单位秒
    CGFloat dataSize = sizeByte / 1024;          /// 间隔时间内下载数据大小,单位 KB
    CGFloat downloadSpeed = dataSize / time;     /// 当前视频下载速度
    NSLog(@"localServerTestSpeedInfo callback, timeInternalMs: %@, size: %@, speed: %.1f KB/s", @(timeInternalMs), @(sizeByte), downloadSpeed);
}

清除视频缓存

调用 clearAllCaches 方法清除视频缓存:

// YES 清除所有缓存; NO LRU 保留最近 10 条记录
[TTVideoEngine ls_clearAllCaches:YES];

Seek 到最后一帧

在播放过程中,如果用户拖动进度条将视频快进到视频总时长 3 秒以内的位置,播放器会直接回调播放完成。如果您需要支持 Seek 到最后一帧,可通过如下方法配置:

[self.videoEngine setOptionForKey:VEKKeyIsEnableSeekLastFrame value:@(1)];
[self.videoEngine setOptionForKey:VEKKeyPlayerSeekEndEnabled_BOOL value:@(YES)];

主备地址容灾

为提升播放的稳定性和可靠性,播放器 SDK 在 DirectUrl 模式下提供了主备地址容灾功能。您可以设置一个主播放地址和一个备用播放地址。当主播放地址播放失败(如 DNS 解析失败、连接超时、收到 4xx/5xx 响应等)时,播放器内部会自动尝试切换到备用地址进行播放。

注意

1.35.1 及以上版本支持此功能。

  1. 在调用 startWithConfiguration 前开启 VEMDLKeyIsAllowTryLastUrl_BOOL

    [TTVideoEngine.ls_localServerConfigure setOptionForKey:@(VEMDLKeyIsAllowTryLastUrl_BOOL) value:@(YES)];
    [TTSDKManager startWithConfiguration:configuration]; 
    
  2. 构造播放源:

    注意

    主备地址指向的文件必须是同一个文件。

    NSString *mainUrl = @"your main video url"; // 主 URL
    NSString *backUpUrl = @"your backup video url"; // 备 URL
    /// cacheKey 建议用 url 中不变的不分的 md5,比如 path 部分的 md5
    NSString *cacheKey = [mainUrl md5]; 
    TTVideoEngineUrlSource *urlSource = [[TTVideoEngineUrlSource alloc] initWithUrls:@[mainUrl, backupUrl] cacheKey:cacheKey];
    

获取设备 ID

默认情况下,播放器 SDK 会自动生成唯一的设备 ID,您可在视频点播质量平台追查该设备 ID 的播放记录。具体请见单点追查。参考以下代码获取设备 ID:

// 获取设备 ID
[TTSDKManager getRangersDeviceID];

说明

如果您自己已有一套独立的用户 ID 体系,希望通过用户 ID 来追查单个用户的单次播放行为,则可自定义用户 ID

自定义 TS 文件缓存 key

注意

1.43.1 及以上版本支持此功能。

// 1. 声明 TTVideoEngineHLSProxyDelegate 协议
@interface AppDelegate () <TTVideoEngineHLSProxyDelegate>

@end

@implementation AppDelegate

// 初始化 SDK
- (void)initTTSDK {
#ifdef DEBUG
    // 设置日志输出级别为全部
    [TTVideoEngine setLogFlag:TTVideoEngineLogFlagAll];
#endif
    
    // 2. 开启 HLSProxy
    [TTVideoEngine.ls_localServerConfigure setOptionForKey:@(VEKKeyHLSProxyProtocolEnable_BOOL) value:@(YES)];
    
    // 设置 AppID 和 LicenseName
    NSString *appId = @"you appid";
    NSString *licenseName = @"you license name";
    
    TTSDKConfiguration *configuration = [TTSDKConfiguration defaultConfigurationWithAppID:appId licenseName:licenseName];
    
    // 设置播放器缓存大小为 300M
    TTSDKVodConfiguration *vodConfig = [[TTSDKVodConfiguration alloc] init];
    vodConfig.cacheMaxSize = 300 * 1024 * 1024; // 300M
    configuration.vodConfiguration = vodConfig;
    
    // 启动 TTSDK
    [TTSDKManager startWithConfiguration:configuration];
    
    // 3. 设置 HLSProxyDelegate 为当前类
    [TTVideoEngine setHLSProxyDelegate:self];
}

// 4. 实现 HLSProxy 协议,根据您的自身需求,自定义 TS 文件缓存 Key
- (NSString * _Nullable)generateFileKey:(NSString *_Nonnull)url hlsFileKey:(NSString *_Nonnull )hlsFileKey infos:(NSDictionary *_Nullable)infos {
    if (!url || !url.length) {
        return nil;
    }
    
    NSURL *nsurl = [NSURL URLWithString:url];
    NSString *path = nsurl.path;
    if ([path hasPrefix:@"/"]) {
        path = [path substringFromIndex:1];
    }
    
    NSArray *arr = [path componentsSeparatedByString:@"/"];
    if (arr.count > 2) {
        path = [NSString stringWithFormat:@"%@/%@",arr[arr.count - 2], arr.lastObject];
    }
    
    return [NSString stringWithFormat:@"biz_%@_%@", hlsFileKey, path.md5String];
}

@end

设置网络超时时间

支持设置 SDK 的网络超时时间,推荐 10 秒。示例如下:

// 1. 打开全局开关,启用网络超时检测功能
// 设置 VEGSKeyAlgoOptionUseEngineNetworkTimeout 为 1
[TTVideoEngine setGlobalForKey:VEGSKeyAlgoOptionUseEngineNetworkTimeout 
    value:@(1)]);
 TTVideoEngine* engine = [[TTVideoEngine alloc] initWithOwnPlayer:YES];
 // 2. 为 engine 实例设置网络超时时间(秒)
 // 本示例设置为 10 秒
[engine setOptionForKey:VEKKeyPlayerOpenTimeOut_NSInteger value:@(10)];
// 3. 关闭 engine 层播放失败重试。播放失败时,不进行重试
 [engine setOptionForKey:VEKKeyPlayerMaxAccumulatedErrCount_NSInteger value:@(0)]

生成 UnionInfo

UnionInfo 是播放端从设备中提取的用于标识访问或设备唯一性的信息。播放器 SDK 通过 UnionInfo 向应用服务端发起播放请求,应用服务端通过服务端 SDK 本地签发包含 UnionInfoPlayAuthToken 并下发给播放器 SDK,即可播放火山引擎私有加密视频。更多信息,请见火山引擎私有加密方案。您可通过以下代码生成 UnionInfo

NSString* unionInfo = [TTVideoEngine getEngineUniqueId]];

播放 5.1 声道视频

需开启以下开关:

[self.videoEngine setOptionForKey:VEKKeyIsEnableAudioSpatialMixer value:@(1)];
[self.videoEngine setOptionForKey:VEKKeyIsEnableVoiceBlockOpt value:@(2)];
[self.videoEngine setOptionForKey:VEKKeyIsSpatialMixerFullRetryCount value:@(2000)]

更多文档

播放器 SDK 常见问题