zoukankan      html  css  js  c++  java
  • iOS基于B站的IJKPlayer框架的流媒体探究

    这里写图片描述

    学习交流及技术讨论可新浪微博关注:极客James

    一.流媒体

    流媒体技术从传输形式上可以分为:渐进式下载和实施流媒体。

    1.渐进式下载

    它是介于实时播放和本地播放之间的一种播放方式,渐进式下载不必等到全部下载完成后在播放,可以边下载边播放,播放完成后,整个文件会保存下来。从用户的体验上合播放方的效果来看,渐进式下载和实时流媒体没有什么区别,不过是渐进式下载保留有文件在本地。下面来介绍下渐进式下载的开发 渐进式下载的API和本地播放的API没有什么太大的区别,可以使用MediaPlayer框架中得MediaPlayerController和MediaPlayerViewController进行播放,亦可以使用AVFoundation框架中得AVPlayer进行播放。在mac os系统下都有一个Apache HTTP服务器,首先打开服务,使用命令行:sudo apachectl -v 输入密码后 接着输入 sudo apachectl start 就可以了 然后把要播放的文件放到/Library/WebServer/documents下就可以了 .

    2.实时流媒体

    实时流媒体是一边接收数据包一边进行播放,本地不保留文件副本,数据总是实时传送的。用户可以快进快退,不过,实时流媒体播放必须保证数据包的传输速度大于文件的播放速度,否则影响播放效果。  
    实时流媒体传输的协议有:RTSP和HLS、MMS。HLS是苹果公司提出的,它只请求基本的HTTP报文,与RTSP和MMS不同,HLS可以穿过任何允许HTTP数据通过的防火墙。而且,HLS对服务器没有特殊要求,只要能够提供HTTP服务就可以了。  
    HLS的解决方案:首先通过音频或视频采集设备采集数据,然后将数据传递给Server对音频或者视频进行编码,编码要求采用MPEG-2格式,编码完成之后再通过媒体文件分隔工具进行分割,然后再讲这些分割好的文件和他们的索引文件发布到发布服务器上,然后客户端就可以访问了。

    二.HLS

    HTTP Live Streaming(HLS)是苹果公司(Apple Inc.)实现的基于HTTP的流媒体传输协议,可实现流媒体的直播和点播,主要应用在iOS系统,为iOS设备(如iPhone、iPad)提供音视频直播和点播方案。HLS点播,基本上就是常见的分段HTTP点播,不同在于,它的分段非常小。要实现HLS点播,重点在于对媒体文件分段,目前有不少开源工具可以使用,这里我就不再讨论,只谈HLS直播技术。

    HLS实现方式原理图 
    这里写图片描述

    相对于常见的流媒体直播协议,例如RTMP协议、RTSP协议、MMS协议等,HLS直播最大的不同在于,直播客户端获取到的,并不是一个完整的数据流。HLS协议在服务器端将直播数据流存储为连续的、很短时长的媒体文件(MPEG-TS格式),而客户端则不断的下载并播放这些小文件,因为服务器端总是会将最新的直播数据生成新的小文件,这样客户端只要不停的按顺序播放从服务器获取到的文件,就实现了直播。由此可见,基本上可以认为,HLS是以点播的技术方式来实现直播。由于数据通过HTTP协议传输,所以完全不用考虑防火墙或者代理的问题,而且分段文件的时长很短,客户端可以很快的选择和切换码率,以适应不同带宽条件下的播放。不过HLS的这种技术特点,决定了它的延迟一般总是会高于普通的流媒体直播协议。

    根据以上的了解要实现HTTP Live Streaming直播,需要研究并实现以下技术关键点

    (1)采集视频源和音频源的数据 
    (2)对原始数据进行H264编码和AAC编码 
    (3)视频和音频数据封装为MPEG-TS包 
    (4)HLS分段生成策略及m3u8索引文件 
    (5)HTTP传输协议

    三.基于B站的流媒体解决方案Ijkplayer框架

    最近在关注流媒体直播这块儿,经过技术老大的推荐B站的ijkplayer框架,开始了一段爬坑历程…… 
    (1)第一步到github上下载B站开源的ijkplayer框架: 
    github网址:B站开源ilkplayer下载地址 
    (2)根据说明文档进行编译前的各种操作,其实不难就三大步骤

    注意: 带有#号标注的是注释,不用在控制台中输入 
    第一步:运行环境的搭建(需要ruby,home-brew,git,yams等环境),打开终端将以下没有#号开头的语句进行输入.

    # install homebrew, git, yasm

    ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)” 
    brew install git 
    brew install yasm

    # add these lines to your ~/.bash_profile or ~/.profile
    # export ANDROID_SDK=
    # export ANDROID_NDK=
    # on Cygwin (unmaintained)
    # install git, make, yams

    第二步: 将ijkplayer项目克隆到本地并且将ffmpeg集成到ijkplayer中(这一步骤比较耗时,需要耐心等待),在终端输入以下命令..

    git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-ios 
    cd ijkplayer-ios 
    git checkout -B latest 

    ./init-ios.sh

    cd ios 
    ./compile-ffmpeg.sh clean 
    ./compile-ffmpeg.sh all

    第三步: 打开ijkplayer-ios下的iOS文件下的IJKMedioDemo 
    官方上的以下两句的意思是将IJKMediaPlayer导入到你的项目中

    #open ios/IJKMediaDemo/IJKMediaDemo.xcodeproj with Xcode

    这里写图片描述
    然后将IJKMediaPlayer拖到此文件中. 
    这样就可以打开官方给出的demo示例程序了.

    这里写图片描述 
    运行出来的效果图: 
    这里写图片描述
    这里写图片描述
    以上是官方给出的demo,仿照demo里面很多功能都是可以实现的.那么问题来了,如何将IJKPlayer集成到自己的项目中呢?本人在集成的时候遇到了很大的坑……

    将ijkplayer集成到自己的项目中: 
    创建自己的项目: 
    第一步:将IJKMediaFrameWork.framework静态库和IJKMediaPlayer入到项目文件中 
    这里写图片描述

    第二不:打开项目添加到这两个文件到主目录,然后打开Build Phases添加以下库 
    这里写图片描述

    这样就完美了,run以下就可以轻松加愉快的进行流媒体的相关开发了……..

    四.M3U8

    做流媒体开发必须接触的一种文件叫M3U8文件,那么什么是M3U8呢? 
    M3U8文件是指UTF-8编码格式的M3U文件。M3U文件是记录了一个索引纯文本文件,打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。 
    M3U文件标签及属性说明 
    M3U文件中可以包含多个tag,每个tag的功能和属性如下:

    #EXTM3U

    每个M3U文件第一行必须是这个tag,请标示作用

    #EXT-X-MEDIA-SEQUENCE:140651513

    每一个media URI 在 PlayList中只有唯一的序号,相邻之间序号+1, 一个media URI并不是必须要包含的,如果没有,默认为0

    #EXTINF:,

    duration 指定每个媒体段(ts)的持续时间(秒),仅对其后面的URI有效,title是下载资源的url

    #EXT-X-TARGETDURATION

    指定最大的媒体段时间长(秒)。所以#EXTINF中指定的时间长度必须小于或是等于这个最大值。这个tag在整个PlayList文件中只能出现一 次(在嵌套的情况下,一般有真正ts url的m3u8才会出现该tag)

    #EXT-X-KEY

    表示怎么对media segments进行解码。其作用范围是下次该tag出现前的所有media URI,属性为NONE 或者 AES-128。NONE表示 URI以及IV(Initialization Vector)属性必须不存在, AES-128(Advanced EncryptionStandard)表示URI必须存在,IV可以不存在。 
    对于AES-128的情况,keytag和URI属性共同表示了一个key文件,通过URI可以获得这个key,如果没有IV(Initialization Vector),则使用序列号作为IV进行编解码,将序列号的高位赋到16个字节的buffer中,左边补0;如果有IV,则将改值当成16个字节的16进制数。

    #EXT-X-PROGRAM-DATE-TIME

    将一个绝对时间或是日期和一个媒体段中的第一个sample相关联,只对下一个meida URI有效,格式如#EXT-X-PROGRAM-DATE-TIME: 
    For example: #EXT-X-PROGRAM-DATE-TIME:2010-02-19T14:54:23.031+08:00

    #EXT-X-ALLOW-CACHE

    是否允许做cache,这个可以在PlayList文件中任意地方出现,并且最多出现一次,作用效果是所有的媒体段。格式如下:#EXT-X-ALLOW-CACHE:

    #EXT-X-PLAYLIST-TYPE

    提供关于PlayList的可变性的信息, 这个对整个PlayList文件有效,是可选的,格式如下:#EXT-X-PLAYLIST-TYPE::如果是VOD,则服务器不能改变PlayList 文件;如果是EVENT,则服务器不能改变或是删除PlayList文件中的任何部分,但是可以向该文件中增加新的一行内容。

    #EXT-X-ENDLIST

    表示PlayList的末尾了,它可以在PlayList中任意位置出现,但是只能出现一个,格式如下:#EXT-X-ENDLIST

    #EXT-X-MEDIA

    被用来在PlayList中表示相同内容的不用语种/译文的版本,比如可以通过使用3个这种tag表示3中不用语音的音频,或者用2个这个tag表示不同角度的video在PlayLists中。这个标签是独立存在的,属性包含: 
    URI:如果没有,则表示这个tag描述的可选择版本在主PlayList的EXT-X-STREAM-INF中存在; 
    TYPE:AUDIO and VIDEO; 
    GROUP-ID:具有相同ID的MEDIAtag,组成一组样式; 
    LANGUAGE:确定使用的主要语言 
    NAME:人类可读的语言的翻译 
    DEFAULT:YES或是NO,默认是No,如果是YES,则客户端会以这种选项来播放,除非用户自己进行选择。 
    AUTOSELECT:YES或是NO,默认是No,如果是YES,则客户端会根据当前播放环境来进行选择(用户没有根据自己偏好进行选择的前提下)。

    #EXT-X-STREAM-INF

    指定一个包含多媒体信息的 media URI 作为PlayList,一般做M3U8的嵌套使用,它只对紧跟后面的URI有效,格式如下:#EXT-X-STREAM-INF:有以下属性: 
    BANDWIDTH:带宽,必须有。 
    PROGRAM-ID:该值是一个十进制整数,惟一地标识一个在PlayList文件范围内的特定的描述。一个PlayList 文件中可能包含多个有相同ID的此tag。 
    CODECS:不是必须的。 
    RESOLUTION:分辨率。 
    AUDIO:这个值必须和AUDIO类别的“EXT-X-MEDIA”标签中“GROUP-ID”属性值相匹配。 
    VIDEO:同上

    版权声明:本文为博主原创文章,转载请注明出处,仅用于学习交流和资源共享。关注新浪微博:极客James https://blog.csdn.net/zc639143029/article/details/51191886
  • 相关阅读:
    WPF 柱状图显示数据
    WPF 寻找控件模板中的元素
    WPF 寻找数据模板中的元素
    WPF VisualTreeHelper的使用
    WPF依赖项属性不需要包装属性也可以工作
    WPF依赖属性对内存的使用方式
    WPF Binding Path妙用
    WPF Binding Path妙用代码实现
    WPF Binding妙处-既无Path也无Source
    WPF ListView的使用
  • 原文地址:https://www.cnblogs.com/sundaysgarden/p/9071352.html
Copyright © 2011-2022 走看看