Demo配置原理:
1、 需要导入第三方库:ASIHttpRequest,CocoaHTTPServer,m3u8(其中ASI用于网络请求,CocoaHTTPServer用于在ios端搭建服务器使用,m3u8是用来对返回的索引文件进行解析的)
2、导入系统库:libsqlite3.dylib、libz.dylib、libxml2.dylib、CoreTelephony.framework、SystemConfiguration.framework、MobileCoreServices.framework、Security.framework、CFNetwork.framework、MediaPlayer.framework
3、添加头文件
YCHLS-Demo.h
- 播放:直接播放在线的直播链接,是由系统的MPMoviePlayer完成的,它自带解析HLS直播链的功能。
- 下载:遵循HLS的协议,通过索引文件的资源路径下载相关的视频切片并保存到手机本地。
- 播放本地视频:使用下载好的视频文件片段进行连续播放。
- 清除缓存:删除下载好的视频片段
原理:
- 通过ASI请求链接,通过m3u8库解析返回的m3u8索引文件。
- 再通过ASI下载解析出的视频资源地址,仿照HLS中文件存储路径存储。
- 利用CocoaHTTPServer在iOS端搭建本地服务器,并开启服务,端口号为:12345(高位端口即可)。配置服务器路径与步骤二存储路径一致。
- 设置播放器直播链接为本地服务器地址,直接播放,由于播放器遵守HLS协议,所以能够解析我们之前使用HLS协议搭建的本地服务器地址。
- 点击在线播放,校验是否与本地播放效果一致。
上面是HLS中服务器存储视频文件切片和索引文件的结构图
整个操作流程就是:
- 先点击下载,通过解析m3u8的第三方库解析资源。(m3u8的那个库只能解析一种特定格式的m3u8文件,代码里会有标注)
- 点击播放本地视频播放下载好的资源。
- 点击播放是用来预览直播的效果,与整个流程无关。
- 其中进度条用来显示下载进度。
总结: 整个Demo并不只是让我们搭建一个Hls服务器或者一个支持Hls的播放器。目的在于了解Hls协议的具体实现,以及服务器端的一些物理架构。通过Demo的学习,可以详细的了解Hls直播具体的实现流程。
部分源码贴出:
开启本地服务器:
- (void)openHttpServer
{
self.httpServer = [[HTTPServer alloc] init];
[self.httpServer setType:@"_http._tcp."]; // 设置服务类型 [self.httpServer setPort:12345]; // 设置服务器端口 // 获取本地Library/Cache路径下downloads路径 NSString *webPath = [kLibraryCache stringByAppendingPathComponent:kPathDownload]; NSLog(@"-------------\nSetting document root: %@\n", webPath); // 设置服务器路径 [self.httpServer setDocumentRoot:webPath]; NSError *error; if(![self.httpServer start:&error])
{ NSLog(@"-------------\nError starting HTTP Server: %@\n", error);
}
视频下载:
- (IBAction)downloadStreamingMedia:(id)sender {
UIButton *downloadButton = sender; // 获取本地Library/Cache路径 NSString *localDownloadsPath = [kLibraryCache stringByAppendingPathComponent:kPathDownload]; // 获取视频本地路径 NSString *filePath = [localDownloadsPath stringByAppendingPathComponent:@"XNjUxMTE4NDAw/movie.m3u8"]; NSFileManager *fileManager = [NSFileManager defaultManager]; // 判断视频是否缓存完成,如果完成则播放本地缓存 if ([fileManager fileExistsAtPath:filePath]) {
[downloadButton setTitle:@"已完成" forState:UIControlStateNormal];
downloadButton.enabled = NO;
}else{
M3U8Handler *handler = [[M3U8Handler alloc] init];
handler.delegate = self; // 解析m3u8视频地址 [handler praseUrl:TEST_HLS_URL]; // 开启网络指示器 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}
}
播放本地视频:
- (IBAction)playVideoFromLocal:(id)sender { NSString * playurl = [NSString stringWithFormat:@"http://127.0.0.1:12345/XNjUxMTE4NDAw/movie.m3u8"]; NSLog(@"本地视频地址-----%@", playurl); // 获取本地Library/Cache路径 NSString *localDownloadsPath = [kLibraryCache stringByAppendingPathComponent:kPathDownload]; // 获取视频本地路径 NSString *filePath = [localDownloadsPath stringByAppendingPathComponent:@"XNjUxMTE4NDAw/movie.m3u8"]; NSFileManager *fileManager = [NSFileManager defaultManager]; // 判断视频是否缓存完成,如果完成则播放本地缓存 if ([fileManager fileExistsAtPath:filePath]) {
MPMoviePlayerViewController *playerViewController =[[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL URLWithString: playurl]];
[self presentMoviePlayerViewControllerAnimated:playerViewController];
} else{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Sorry" message:@"当前视频未缓存" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alertView show];
}
}
播放在线视频
- (IBAction)playLiveStreaming { NSURL *url = [[NSURL alloc] initWithString:TEST_HLS_URL];
MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
[self presentMoviePlayerViewControllerAnimated:player];
}
当然,《芈月传》的直播链接到现在也还没有找到,各位热心读者如果有链接的话可以留言给我,也让这篇文章能实至名归了,能对得文章的标题了