本文接 《如何使用iOS实现《芈月传》的直播、点播?-HTTP Live Streaming (HLS)(一)》css
HLS-Demo地址:https://github.com/yangchao0033/HLS-Demoios
使用demo前请注意下面的问题,我在代码中也作了注释。git
//#warning 注意,不要直接使用切换流的主索引,当前代码的协议只提供对.ts定位的子索引的下载和播放,并且其中只有点播协议那一小段是能够下载的,直播协议只能播放,没法下载,没法下载的缘由是由于m3u8的那个库中只对特定的一种m3u8的格式作了解析,而m3u8的格式有不少种,因此没法加息出来,该demo只作演示,不会对全部格式进行全解析,若是你们感兴趣的话能够对m3u8的库进行扩展,在github 上 pull request 我作一个补充扩展,我会及时在博客中进行更新。博客地址:superyang.gitcafe.io或yangchao0033.github.io 同简书:http://www.jianshu.com/users/f37a8f0ba6f8/latest_articles /** 点播协议 (只有这个是能够下载的,可是苦于过短,没办法播放出来,正在寻找能够下载并播放的新的点播或直播源,但愿有读者能够帮忙提供哈,不甚感激~)*/ //#define TEST_HLS_URL @"http://m3u8.tdimg.com/147/806/921/3.m3u8" /** 视频直播协议 */ /** 父索引(没法下载,只做为结构分析) */ //#define TEST_HLS_URL @"http://dlhls.cdn.zhanqi.tv/zqlive/34338_PVMT5.m3u8" /** 子索引(没法下载,只做为结构分析) */ //#define TEST_HLS_URL @"http://dlhls.cdn.zhanqi.tv/zqlive/34338_PVMT5_1024/index.m3u8?Dnion_vsnae=34338_PVMT5" /** wwcd视频,果真苹果本身就用这个协议(没法下载,只做为结构分析) */ //#define TEST_HLS_URL @"http://devstreaming.apple.com/videos/wwdc/2015/413eflf3lrh1tyo/413/hls_vod_mvp.m3u8"
若是以为文章有用的话,请读者在github上点个star,或者在简书上点个赞。github
本文在个人博客上一样有发布,欢迎各位读者留言。
博客地址:http://superyang.gitcafe.io/blog/2016/02/14/hls-2/web
Demo配置原理:sql
一、 须要导入第三方库:ASIHttpRequest,CocoaHTTPServer,m3u8(其中ASI用于网络请求,CocoaHTTPServer用于在ios端搭建服务器使用,m3u8是用来对返回的索引文件进行解析的)缓存
二、导入系统库:libsqlite3.dylib、libz.dylib、libxml2.dylib、CoreTelephony.framework、SystemConfiguration.framework、MobileCoreServices.framework、Security.framework、CFNetwork.framework、MediaPlayer.framework服务器
三、添加头文件网络
YCHLS-Demo.h
四、demo介绍架构
原理:
上面是HLS中服务器存储视频文件切片和索引文件的结构图
整个流程就是:
总结:
整个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]; }