本文为您介绍如何使用 iOS 点播 SDK 的基础功能。
TTVideoEngine 支持播放、暂停、Seek、从指定时间启播、停止和关闭等播放控制功能。
调用 play
方法,实现开始播放的功能,代码示例如下所示。
// 开始播放 [self.engine play];
调用 pause
方法,实现暂停播放视频的功能。再次调用 play
方法,状态可由暂停恢复到播放。代码示例如下所示。
// 异步执行,避免阻塞主线程 [self.engine pause:YES]; // 播放器由暂停恢复到播放状态 [self.engine play];
调用 setCurrentPlaybackTime:complete:
方法,可以 seek 到指定位置进行播放,实现拖拽进度条到指定时间开始播放的功能。代码示例如下所示。
// currentTime 需要快进/快退到某个时间点 [self.engine setCurrentPlaybackTime:currentTime complete:^(BOOL success) { /// seek 操作状态完成回调 NSLog(@"seek complete %@", @(success)); } renderComplete:^{ /// seek 渲染完成回调 NSLog(@"seek render complete"); }];
在调用 play
前设置 startTime
指定开始播放时间点,可实现从指定时间点开始播放或跳过片头等功能。示例代码如下:
注意
如果您使用预渲染功能,需在 prepareToPlay
前设置。
// 上次播放进度,可实现从指定时间起播的功能 CGFloat startTime = 5.0f; // 在 play 之前设置 [engine setOptionForKey:VEKKeyPlayerStartTime_CGFloat value:@(startTime)];
调用 stop
方法,实现停止播放视频的功能。代码示例如下所示。
// 停止播放 [self.engine stop];
调用 closeAysnc
方法,实现异步释放播放器实例。代码示例如下所示。
// 异步关闭播放器,不影响主线程 [self.engine closeAysnc]; // 记得移除视图 [self.engine.playerView removeFromSuperview]; // engine实例置为空 self.engine = nil;
说明
engine
设置为 nil
,防止再次调用。点播 SDK 支持在播放视频时,只解码音频而不解码视频,适用于纯音频播放场景。相比您根据自身业务逻辑实现的纯音频播放,SDK 只解码音频会更省电。
注意
该功能仅高级版或企业版支持。请确保您已购买高级版或企业版的 License 并添加高级版 SDK 依赖,详见 License 包管理。
// 开启纯音频播放,视频停止渲染 self.videoEngine.radioMode = YES; // 恢复音视频播放,视频恢复渲染 self.videoEngine.radioMode = NO;
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)];
设置视频显示时的旋转角度的代码示例如下所示。
// 无旋转角度 [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)];
设置视频镜像,支持水平镜像和垂直镜像的功能。代码示例如下所示。
// 无镜像(默认) [self.engine setOptionForKey:VEKKeyViewMirrorType_ENUM value:@(TTVideoEngineMirrorTypeNone)]; // 设置水平镜像 [self.engine setOptionForKey:VEKKeyViewMirrorType_ENUM value:@(TTVideoEngineMirrorTypeHorizontal)]; // 设置垂直镜像 [self.engine setOptionForKey:VEKKeyViewMirrorType_ENUM value:@(TTVideoEngineMirrorTypeVertical)];
获取视频宽高的方式有两种:
方式一:通过接口获取
VEKGetKeyPlayerVideoWidth_NSInteger VEKGetKeyPlayerVideoHeight_NSInteger
方式二:通过回调获取
- (void)videoSizeDidChange:(TTVideoEngine *)videoEngine videoWidth:(NSInteger)videoWidth videoHeight:(NSInteger)videoHeight;
调用 snapshot
方法,实现视频截图功能。可以在 completion block 中获取和处理截图生成的 UIImage 对象。方法声明如下所示:
- (void)snapshot:(void(^)(UIImage *))completion;
iOS 点播 SDK 支持获取当前播放进度、播放时长、缓存进度等播放信息。
调用 currentPlaybackTime
方法,实现当前播放位置的功能。代码示例如下所示。
NSInteger playTime = self.engine.currentPlaybackTime;
调用 duration
方法,实现获取播放时长的功能。代码示例如下所示。
NSInteger duration = self.engine.duration;
调用 playableDuration
方法,实现获取缓存进度的功能。代码示例如下所示。
NSInteger 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;
设置倍速,默认值为 1,取值范围为(0,3]。代码示例如下所示。代码示例如下所示。
// 默认为 1 倍速,取值范围(0,3] self.engine.playbackSpeed = 1.0;
// 打开静音 self.engine.muted = YES; // 关闭静音 self.engine.muted = NO;
// 建议使用系统音量方法进行调节。 // 如果只想调整单个视频的音量,需要在 play 之前配置 AudioDevice [self.engine setOptionForKey:VEKKeyPlayerAudioDevice_ENUM value:@(TTVideoEngineDeviceAudioGraph)]; // 音量设置 self.engine.volume = 1.0f;
使用 VideoID 视频源播放时,服务端会下发多个清晰度的播放地址。当 TTVideoEngine
接收到 videoEngine:fetchedVideoModel:
回调时,即可调用 supportedResolutionTypes
方法获取到所有清晰度的 NSArray<NSNumber *>
数组。您可用该数组做清晰度列表的展示和清晰度逻辑选择。
调用 currentResolution
方法,支持获取当前清晰度。代码示例如下所示。
// 当前清晰度信息 TTVideoEngineResolutionType currentType = self.engine.currentResolution;
- (void)videoEngine:(TTVideoEngine *)videoEngine fetchedVideoModel:(TTVideoEngineModel *)videoModel { // 获取当前 VideoModel 的清晰度数组,可用于清晰度列表展示 NSArray<NSNumber *> *allResolutions = [self.engine supportedResolutionTypes]; }
设置启播的清晰度:在播放之前预设值清晰度信息,如果没有对应的清晰度档位,会自动降级遍历支持清晰度列表,查找合适的清晰度档位。代码示例如下所示。
[self.engine configResolution:TTVideoEngineResolutionTypeFullHD];
起播后,需要明确支持哪些清晰度的视频,切换指定清晰度档位。
NSArray<NSNumber *> *allResolutions = [engine supportedResolutionTypes]; TTVideoEngineResolutionType useResolution = [[allResolutions objectAtIndex:0] integerValue]; [self.engine configResolution:useResolution completion:^(BOOL success, TTVideoEngineResolutionType completeResolution) { /// 清晰度切换结束 /// success 是否切换成功; /// completeResolution 切换后的清晰度 }];
TTVideoEngineResolutionType 部分枚举如下表所示。
key | 对应清晰度 | 视频描述 | 音频描述 |
---|---|---|---|
TTVideoEngineResolutionTypeSD | 360P | 标清 | 普通音质 |
TTVideoEngineResolutionTypeHD | 480P | 高清 | 高音质 |
TTVideoEngineResolutionTypeFullHD | 720P | 超清 | 音乐音质 |
TTVideoEngineResolutionType1080P | 1080P | 1080P | 原画 |
TTVideoEngineResolutionType2K | 2K | 2K | |
TTVideoEngineResolutionType4K | 4K | 4K | |
TTVideoEngineResolutionTypeAuto | 自动调节 | DASH 支持根据网速动态调节清晰度。不是 DASH 加密不建议设置这个参数。 |
支持通过不同方式播放 HLS 视频,设置过期时间的方法不同。
如果您通过 DirectUrl 方式播放 HLS 视频,在设置播放源和预加载时均可以通过 urlExpiredTimes
参数设置过期时间。
在设置 DirectUrl 播放源时,通过 urlExpiredTimes
参数设置过期时间,示例代码如下所示:
// 设置播放源信息 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:source preloadSize:800*1024]; [TTVideoEngine ls_addTaskWithURLItem:item];
您可以通过 Debug 调试状态下查看日志,确认播放地址中是否包含 hlsproxyQuery
关键字。示例如下:
hlsproxyQuery=expirteTime%03Dxxxxxxxxxx
如果您通过 Vid 方式播放 HLS 视频,客户端无需额外设置,只需确保 GetPlayInfo 接口中返回的 VideoModel
包含过期时间信息即可。
业务类型(tag)用于区分同一应用(appid)内,不同类型的音视频。可以根据业务需要按视频场景、视频时长等划分:比如沉浸式 feed 流、短视频视频、长视频等。代码示例如下所示。
[videoEngine setOptionForKey:VEKKeyLogTag_NSString value:@"tag"];//设置 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; // 内部的加载状态,可以根据该方法显示或者隐藏 loading 视图 /// @TTVideoEngineLoadStatePlayable 隐藏 loading 视图 /// @TTVideoEngineLoadStateStalled 显示 loading 视图 - (void)videoEngine:(TTVideoEngine *)videoEngine loadStateDidChanged:(TTVideoEngineLoadState)loadState; // 使用 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 并添加高级版 SDK 依赖,详见 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 方法清除视频缓存:
[TTVideoEngine ls_clearAllCaches:YES]; // YES 清除所有缓存; NO LRU 保留最近 10 条记录
在播放过程中,如果用户拖动进度条将视频快进到视频总时长 3 秒以内的位置,播放器会直接回调播放完成。如果您需要支持 Seek 到最后一帧,可通过如下方法配置:
[self.videoEngine setOptionForKey:VEKKeyIsEnableSeekLastFrame value:@(1)]; [self.videoEngine setOptionForKey:VEKKeyPlayerSeekEndEnabled_BOOL value:@(YES)];
SDK 支持 DirectUrl 模式下设置多个域名的 URL 实现主备容灾。
注意
1.35.1 及以上版本支持此功能。
在调用 startWithConfiguration
前开启 VEMDLKeyIsAllowTryLastUrl_BOOL
。
[TTVideoEngine.ls_localServerConfigure setOptionForKey:@(VEMDLKeyIsAllowTryLastUrl_BOOL) value:@(YES)]; [TTSDKManager startWithConfiguration:configuration];
构造播放源:
注意
主备地址指向的文件必须是同一个文件。
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];
默认情况下,点播 SDK 会自动生成唯一的设备 ID,您可在质量平台追查该设备 ID 的播放记录。参考以下代码获取设备 ID:
// 获取设备 ID [TTSDKManager getRangersDeivceID];
说明
如果您自己已有一套独立的用户 ID 体系,希望通过用户 ID 来追查单个用户的单次播放行为,则可自定义设备 ID。
注意
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