KTVHTTPCache 是唱吧开源的一个高效的音视频缓存框架,专门为解决 iOS/macOS 平台上的音视频边下边播需求而设计。下面我将详细解释它的实现原理和使用方法。
核心架构
KTVHTTPCache 采用了代理服务器 + 数据调度器的架构:
+-------------------+ +-----------------+ +-------------------+
| AVPlayer | | KTVHTTPCache | | Remote Server |
| (AVFoundation) | ---> | Proxy Server | ---> | (原始视频源) |
+-------------------+ +-----------------+ +-------------------+
^ |
| v
| +-----------------+
+-----------------| Cache Storage |
| (文件系统) |
+-----------------+
实现原理
1. URL 重定向(核心机制)
KTVHTTPCache 通过创建一个本地 HTTP 代理服务器(默认端口 8080),并重写视频 URL 来拦截播放器的请求:
// 原始URL
NSURL *originalURL = [NSURL URLWithString:@"https://example.com/video.mp4"];
// 转换为本地代理URL
NSURL *proxyURL = [KTVHTTPCache proxyURLWithOriginalURL:originalURL];
// proxyURL: http://localhost:8080/proxy/https://example.com/video.mp4
2. 请求拦截与处理
当播放器请求代理 URL 时,KTVHTTPCache 会:
- 解析出原始 URL
- 检查本地是否已有缓存
- 根据请求的 Range 头部决定如何响应
3. 数据调度策略
KTVHTTPCache 实现了智能的数据调度:
- 缓存命中:直接返回本地缓存数据
- 部分缓存:返回已缓存部分,同时异步下载缺失部分
- 无缓存:启动下载并实时返回数据给播放器
4. 缓存管理
- 使用文件系统存储缓存数据
- 支持缓存大小限制和自动清理
- 支持缓存验证和过期策略
集成与使用
1. 安装
通过 CocoaPods 安装:
pod 'KTVHTTPCache'
2. 初始化
在 App 启动时初始化 KTVHTTPCache:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 初始化HTTP缓存服务器
[KTVHTTPCache proxyStart:nil];
// 配置缓存目录
NSString *cacheDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"vhcache"];
[KTVHTTPCache cacheSetDirectory:cacheDirectory];
// 设置缓存最大容量(100MB)
[KTVHTTPCache cacheSetMaxCacheLength:100 * 1024 * 1024];
return YES;
}
3. 基本使用
// 获取代理URL
NSURL *originalURL = [NSURL URLWithString:@"https://example.com/video.mp4"];
NSURL *proxyURL = [KTVHTTPCache proxyURLWithOriginalURL:originalURL];
// 创建播放器
AVPlayer *player = [AVPlayer playerWithURL:proxyURL];
AVPlayerViewController *playerVC = [[AVPlayerViewController alloc] init];
playerVC.player = player;
// 播放
[self presentViewController:playerVC animated:YES completion:^{
[player play];
}];
4. 高级功能
预加载视频
// 预加载视频(提前缓存)
NSURL *url = [NSURL URLWithString:@"https://example.com/video.mp4"];
[KTVHTTPCache cacheRequestWithURL:url completion:^(NSError *error) {
if (!error) {
NSLog(@"预加载完成");
}
}];
获取缓存信息
// 检查缓存状态
NSURL *url = [NSURL URLWithString:@"https://example.com/video.mp4"];
KTVHCCacheConfiguration *configuration = [KTVHTTPCache cacheConfigurationWithURL:url];
// 缓存进度(0-1)
CGFloat cacheProgress = configuration.progress;
// 缓存文件路径
NSString *cachePath = configuration.filePath;
// 文件总大小
long long contentLength = configuration.totalLength;
清理缓存
// 清理所有缓存
[KTVHTTPCache cacheDeleteAllCaches];
// 清理指定URL缓存
NSURL *url = [NSURL URLWithString:@"https://example.com/video.mp4"];
[KTVHTTPCache cacheDeleteCacheWithURL:url];
自定义配置
// 设置User-Agent
[KTVHTTPCache proxySetUserAgent:@"Custom User Agent"];
// 设置网络请求超时
[KTVHTTPCache proxySetConnectionTimeout:20];
// 设置支持的内容类型
NSSet<NSString *> *contentTypes = [NSSet setWithArray:@[@"video/mp4", @"audio/mp3"]];
[KTVHTTPCache proxySetContentTypes:contentTypes];
实际应用示例
实现视频列表预加载
// 预加载下一个视频
- (void)preloadNextVideo:(NSURL *)nextVideoURL {
if (!nextVideoURL) return;
// 检查是否已缓存
KTVHCCacheConfiguration *config = [KTVHTTPCache cacheConfigurationWithURL:nextVideoURL];
if (config.progress >= 1.0) {
return; // 已完整缓存
}
// 预加载前5MB
KTVHCDataRequest *request = [[KTVHCDataRequest alloc] initWithURL:nextVideoURL
range:NSMakeRange(0, 5 * 1024 * 1024)];
[KTVHTTPCache cacheRequestWithRequest:request completion:^(NSError *error) {
if (!error) {
NSLog(@"预加载成功");
}
}];
}
处理认证请求
// 设置认证处理器
[KTVHTTPCache proxySetAuthenticationChallengeBlock:^NSURLCredential *(NSURLSession *session,
NSURLAuthenticationChallenge *challenge) {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
return [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
} else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) {
// HTTP基本认证
return [NSURLCredential credentialWithUser:@"username"
password:@"password"
persistence:NSURLCredentialPersistenceForSession];
}
return nil;
}];
注意事项
-
App Transport Security:需要在 Info.plist 中允许本地 HTTP 连接:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsLocalNetworking</key> <true/> </dict>
后台播放:如果需要支持后台播放,需要在 Capabilities 中开启 Background Modes 的 Audio, AirPlay, and Picture in Picture。
缓存策略:根据应用需求调整缓存大小,过大的缓存可能占用过多存储空间。
网络状态处理:KTVHTTPCache 本身不处理网络状态变化,应用层需要监听网络状态并做出相应处理。
总结
KTVHTTPCache 通过本地代理服务器的方式,巧妙地拦截并处理音视频请求,实现了边下边播功能。它的优点包括:
- 对现有代码侵入性小,只需替换 URL
- 支持多种视频格式和协议
- 提供完善的缓存管理功能
- 支持认证和自定义请求头
- 具有良好的性能表现
对于需要实现音视频边下边播功能的 iOS/macOS 应用,KTVHTTPCache 是一个值得考虑的解决方案。