本文接 《如何使用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]; }