You need to enable JavaScript to run this app.
导航

基础功能

最近更新时间2024.04.22 20:32:06

首次发布时间2021.02.23 10:42:41

快速开始中,我们完成 TTVideoEngine 实例创建。本文档介绍如何使用 iOS 的 TTVideoEngine 实现播放功能,适用于基础版 SDK 和高级版 SDK。

播放控制

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

播放

调用 play 方法,实现开始播放的功能,代码示例如下所示。

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

暂停

调用 pause 方法,实现暂停播放视频的功能。再次调用 play 方法,状态可由暂停恢复到播放。代码示例如下所示。

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

Seek

调用 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 只解码音频会更省电。

注意

仅高级版或企业版 SDK 支持纯音频播放。请确保您已购买高级版或企业版的 License 并添加高级版 SDK 依赖,详见以下文档:

// 开启纯音频播放,视频停止渲染
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;
    

HDR 功能

iOS 点播 SDK 支持播放 HDR 视频源,详见 HDR 功能接入

截图功能

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

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

下载功能

iOS 点播 SDK 提供下载功能,支持用户在播放器中将视频缓存至本地观看。详见下载功能接入

获取播放信息

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];
}

切换清晰度

  1. 设置启播的清晰度:在播放之前预设值清晰度信息,如果没有对应的清晰度档位,会自动降级遍历支持清晰度列表,查找合适的清晰度档位。代码示例如下所示。

    [self.engine configResolution:TTVideoEngineResolutionTypeFullHD];
    
  2. 起播后,需要明确支持哪些清晰度的视频,切换指定清晰度档位。

    NSArray<NSNumber *> *allResolutions = [engine supportedResolutionTypes];
    TTVideoEngineResolutionType useResolution = [[allResolutions objectAtIndex:0] integerValue]; 
    [self.engine configResolution:useResolution completion:^(BOOL success, TTVideoEngineResolutionType completeResolution) {
        /// 清晰度切换结束
        /// success 是否切换成功;
        /// completeResolution 切换后的清晰度
    }];
    

    TTVideoEngineResolutionType 部分枚举如下表所示。

    key对应清晰度视频描述音频描述
    TTVideoEngineResolutionTypeSD360P标清普通音质
    TTVideoEngineResolutionTypeHD480P高清高音质
    TTVideoEngineResolutionTypeFullHD720P超清音乐音质
    TTVideoEngineResolutionType1080P1080P1080P原画
    TTVideoEngineResolutionType2K2K2K-
    TTVideoEngineResolutionType4K4K4K-
    TTVideoEngineResolutionTypeAuto自动调节DASH 支持根据网速动态调节清晰度。不是 DASH 加密不建议设置这个参数。-

设置 HLS 过期时间

支持通过不同方式播放 HLS 视频,设置过期时间的方法不同。

DirectUrl 方式

如果您通过 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 方式

如果您通过 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、卡顿等情况下展示当前视频下载速度。实现的示例代码如下所示。

注意

仅高级版或企业版 SDK 支持展示当前视频下载速度。请确保您已购买高级版或企业版的 License 并添加高级版 SDK 依赖,详见以下文档:

// 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);
}