美文网首页IOSabout iOSiOS 直播视频
如何使用iOS实现《芈月传》的直播、点播、缓存?-HTTP Li

如何使用iOS实现《芈月传》的直播、点播、缓存?-HTTP Li

作者: superYang0033 | 来源:发表于2016-02-15 13:32 被阅读5026次

    本文接 《如何使用iOS实现《芈月传》的直播、点播?-HTTP Live Streaming (HLS)(一)》

    HLS-Demo地址:https://github.com/yangchao0033/HLS-Demo

    使用demo前请注意下面的问题,我在代码中也做了注释。

    //#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,或者在简书上点个赞。

    本文在我的博客上同样有发布,欢迎各位读者留言。
    博客地址:http://superyang.gitcafe.io/blog/2016/02/14/hls-2/

    Demo配置原理:

    1、 需要导入第三方库:ASIHttpRequest,CocoaHTTPServer,m3u8(其中ASI用于网络请求,CocoaHTTPServer用于在ios端搭建服务器使用,m3u8是用来对返回的索引文件进行解析的)

    ASI配置注意事项ASI配置注意事项 MRC报错处理MRC报错处理

    2、导入系统库:libsqlite3.dylib、libz.dylib、libxml2.dylib、CoreTelephony.framework、SystemConfiguration.framework、MobileCoreServices.framework、Security.framework、CFNetwork.framework、MediaPlayer.framework

    3、添加头文件

    YCHLS-Demo.h
    

    4、demo介绍


    demo样式demo样式
    • 播放:直接播放在线的直播链接,是由系统的MPMoviePlayer完成的,它自带解析HLS直播链的功能。
    • 下载:遵循HLS的协议,通过索引文件的资源路径下载相关的视频切片并保存到手机本地。
    • 播放本地视频:使用下载好的视频文件片段进行连续播放。
    • 清除缓存:删除下载好的视频片段

    原理:

    1. 通过ASI请求链接,通过m3u8库解析返回的m3u8索引文件。
    2. 再通过ASI下载解析出的视频资源地址,仿照HLS中文件存储路径存储。
    3. 利用CocoaHTTPServer在iOS端搭建本地服务器,并开启服务,端口号为:12345(高位端口即可)。配置服务器路径与步骤二存储路径一致。
    4. 设置播放器直播链接为本地服务器地址,直接播放,由于播放器遵守HLS协议,所以能够解析我们之前使用HLS协议搭建的本地服务器地址。
    5. 点击在线播放,校验是否与本地播放效果一致。
    HLS协议文件存储结构HLS协议文件存储结构

    上面是HLS中服务器存储视频文件切片和索引文件的结构图
    整个流程就是:

    1. 先点击下载,通过解析m3u8的第三方库解析资源。(m3u8的那个库只能解析一种特定格式的m3u8文件,代码里会有标注)
    2. 点击播放本地视频播放下载好的资源。
    3. 点击播放是用来预览直播的效果,与整个流程无关。
    4. 其中进度条用来显示下载进度。

    总结:
    整个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];
    }
    

    当然,《芈月传》的直播链接到现在也还没有找到,各位热心读者如果有链接的话可以留言给我,也让这篇文章能实至名归了,能对得文章的标题了。

    同志们,找到了官方的切片工具,已将《芈月传》切片放到了服务器上,1080P高清无码,敬请观看😁
    具体代码我也做了更新,请大家更新代码后测试Demo~

    具体播放地址为:http://yangchao0033.github.io/hlsSegement/0640.m3u8(可在safari中直接观看)
    切片工具博客:http://www.henishuo.com/hls-streaming-tool/
    总算不用做标题党了,摔🤓~

    相关文章

      网友评论

      • WSGNSLog:刚开始看,不明白为什么要搭建一个本地服务器呢?
        superYang0033:@WSGNSLog 这是为了给客户端搭建一个hls 的服务,这样可以让客户端通过服务来解析hls指向的视频资源,简单来讲就是模拟远程hls 播放,这种成本最低,主要原因其实苹果米有本地hls 的接口,自己写成本比较高,当然也可以在下载时将hls 切片合成完整mp4文件,这样也可以绕过本地播放hls 的问题
      • 2fccb0689f51:请问这样做直播 怎么做推流呢?请楼主能说个大概吗?
        superYang0033:@fuckOnly180 推流具体不是我这边做的,是后台使用开源的切片工具切好的,会定期推。
      • lonelyprince:你好,很感谢你的文章,受益匪浅。Media Player视频播放正式在iOS 9中弃用,必须迁移使用AVKit或AV Foundation才可以,这样是否会影响MPMoviePlayer的使用呢? 如果影响的话,请问在您的代码中做一些怎么样的修改就不影响了
        lonelyprince:@大爱阿狸哈多 恩,好的 :grin:
        superYang0033:@lonelyprince git上的代码已更新为AVPlayrViewController.博客还未修改:smile:
      • iOS开发:为什么下载不了啊
        iOS开发:@大爱阿狸哈多 可以下载了 下载成功了
        superYang0033:@iOS开发 有相关的错误提示吗?复现步骤是?
      • HanWoonYong:httpserver 拼接完的地址里不能有汉字么?
        superYang0033:@白色的胖子 理论上如果你需要拼接中文路径是需要百分号转义的。
      • 来宝:不错
      • 醉卧栏杆听雨声:感谢分享!最近打算做直播类App。
      • zhao1zhihui:问一下大神,把你的demo下载下来还需要配置什么吗?为什么播放不了
        superYang0033:@zhao1zhihui 有什么错误日志可以提供吗?http://yangchao0033.github.io/hlsSegement/0640.m3u8在手机和mac的Safari中都是可以播放的。
        zhao1zhihui:@大爱阿狸哈多 你那个demo是不是直接就可以用的。我看了一下你的流程 完全是按照你写的做的不过你的demo好像都做了.之后运行app安装在了手机上播放不了 同时链接在safri上也播放不了
        superYang0033:@zhao1zhihui 可以描述一下具体步骤吗?
      • 小程序迷途:楼主请问你们导入CocoaHTTPServer这个三方的时候会不会编译出错
        Implicit declaration of function 'LOG_OBJC_MAYBE' is invalid in C99
        是不是要引入什么有文件啊
        小程序迷途:我是在pod上搜索的Cocoa HTTP Server 2.3版本的
        小程序迷途:没有啊,就这一条错误提示啊
        superYang0033:@牛奶奶买刘奶 没有发现过,有具体的错误日志吗?
      • eb025db40113:很不错的东西,谢谢楼主,
      • 系统盘:我在想用cocoahttpserver实现WiFi手机传输,你对这个框架了解吗,大概内容做了,但是有些细节问题
        superYang0033:@我旁边坐了一个胖子 我现在在外地休假,具体的代码可能看不了,不过对你的研究内容很感兴趣,希望可以通过博文之类分享更多的经验:smile:
        系统盘:@大爱阿狸哈多 就是我要在手机上监听上传数据的进度,是要用gcdasyncsocket这个类进行吗?还是要用哪个,而且我想HTML页面改变一些配置,格局,不知道会不会对上传有影响
        superYang0033:@我旁边坐了一个胖子 理论上是可以,这个框架我就是为了搭服务器用的,不过你说的手机之间的传输理论上是可以,用WiFi搭建局域网
      • cdd111d1cf99:楼主您好!blog很赞,但是dome运行起来直播这块有很大的延迟,是下载一部分播放一部分,在下载在播放吗?播放一段一段的呢!
        superYang0033:@kinsey 我猜你可能理解错了,我不是在讨论播放器,是在讨论hls播放技术,建议你先看一下第一篇了解一下,这篇博客是用来介绍hls这种特定技术的:smile:
        cdd111d1cf99:@大爱阿狸哈多 楼主你这个dome你有试过能不能播放flv格式的视频呢?我播放本地的flv格式的播放不出来!
        superYang0033:@kinsey 直播这块是视当前的网络环境和播放源而定的:smile:
      • 辰北:下载下来了并不是能播放的格式
        superYang0033:@辰北 替换成@"id%d.ts"就行
        superYang0033:@辰北 嗯,是的,代码里面构造m3u8表和存储下载文件的时候id%d后面没写.ts 这样可以适配很多播放器,可以在代码里进行修改,全局搜索@"id 替换一下 :smiley:
        辰北:是id开头的 但是没有后缀名 添加后缀名ts mac的上能播放
      • Sanchain:http://video-zfish.oss-cn-shenzhen.aliyuncs.com/camera/30/vod.m3u8
        superYang0033:下载结束后,你会在你的沙盒目录/Doucments/Downloads/XNjUxMTE4NDAw/ 路劲中找到列id开头的文件,如果这些文件可以直接双击播放就没问题,或者你把后缀改成.ts看能不能双击打开,如果打不开很有可能是文件做了加密,ts切片文件在mac环境下是可以独立播放的,还有你测试一下你的m3u8链接,AVPlayer播放一下,MP已经废弃了,试试能不能播放,如果在线也不能播放,那下载的文件也不行
        superYang0033:@Sanchain 还有我想问一下你的链接不能在线播放吗?做了加密了吧,因为沙盒里下载的文件也不能打开
        superYang0033:@Sanchain 我刚才试了一下下载没有问题,本地造的m3u8也是对的,那问题很有可能是在本地的服务了
      • Sanchain:刚查过沙盒,只有movie.m3u8文件,没有看到有ts文件。附上我的m3u8: @"http://video-zfish.oss-cn-shenzhen.aliyuncs.com/camera/30/vod.m3u8" , 楼主可以帮忙试一下吗?PS:我在您的demo里作了点修改,读取片段url时, NSRange linkRangeEnd = [remainData rangeOfString:@".ts"]; 因为我这个m3u8解析出来最后一个片段后面没有#EXT-X-ENDLIST,所以我把@"#"替换为@".ts"
        superYang0033:@Sanchain 这么修改没有问题,只要保证每一天url是对的就行,还有你把沙盒里的m3u8文件能贴一份出来吗 :blush:
      • Sanchain:楼主您好,我用您的Demo来下载后台给的m3u8直播索引文件,可以实现下载,但是播放本地视频时播不了,请问这是不是因为m3u8里的格式不一样所致?有解决方法吗
        superYang0033:@Lee_Cen 方便给我测试链接吗?
        LeeCen:@大爱阿狸哈多 我运行 Demo 也是出现同样的问题,能下载,能在线播放,就是不能本地播放,沙盒里有对应的m3u8文件和ts文件


        content:#EXTM3U
        #EXT-X-TARGETDURATION:30
        #EXT-X-VERSION:2
        #EXT-X-DISCONTINUITY
        #EXTINF:0,
        http://127.0.0.1:12345/0640/id0.ts
        #EXTINF:16,
        http://127.0.0.1:12345/0640/id1.ts
        #EXTINF:8,
        http://127.0.0.1:12345/0640/id2.ts
        #EXTINF:8,
        http://127.0.0.1:12345/0640/id3.ts
        #EXTINF:8,
        http://127.0.0.1:12345/0640/id4.ts
        #EXTINF:8,
        http://127.0.0.1:12345/0640/id5.ts
        superYang0033:@Sanchain 能下载不能播放?有没有检查过沙盒里确实有对应的m3u8文件和ts文件吗?还有手机里起的服务有没有成功?
      • 范少:直播边下载边播放有什么好的思路吗,需要自己控制给播放器的数据吗,有什么办法取出播放器的视频数据吗 :sob:
        superYang0033:@范少 如果是这种需求可以参考http://www.jianshu.com/p/990ee3db0563?utm_campaign=hugo&utm_medium=reader_share&utm_content=note
      • 无赖正义丶:下载了 demo 点击下载并不能正常下载 是什么原因?
        无赖正义丶:@大爱阿狸哈多 好的 多谢
        superYang0033:@无赖正义丶 本文已更新,并你说的问题做了解释,只需要把能下载的那个链接注释打开并注释其他链接即可下载。希望能帮到你 :smile:
      • 无赖正义丶:正在研究 iOS 的视频直播技术, 楼主的 blog 很不错, 蛮有收货, 赞一个
      • 叶舞清风:攒
        superYang0033:@叶舞清风 谢谢:blush:

      本文标题:如何使用iOS实现《芈月传》的直播、点播、缓存?-HTTP Li

      本文链接:https://www.haomeiwen.com/subject/jqdpkttx.html