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导入到你的项目中
#import ios/IJKMediaPlayer for MediaPlayer.framework-like interface (recommended)
#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:同上
iOS基于B站的IJKPlayer框架的流媒体探究的更多相关文章
- B站开源播放框架ijkplayer(iOS版)使用教程
最近在关注直播这块儿,开始时直接用ffmpeg写了一个,写得比较烂,卡顿很严重,后来听说了B站开源播放框架ijkplayer,于是就去试试看这是链接 ,一用之下果然不错,逢人便向人安利,可总是有部分同 ...
- IOS基于XMPP协议开发--XMPPFramewok框架(一):基础知识
最近蘑菇街团队的TT的开源,使我对im产生了兴趣,然后在网上找到了XMPPFramework进行学习研究, 并写了以下系列教程供大家参考,有写的不对的地方,请大家多多包涵指正. 目录索引 IOS基于X ...
- 基于.NET平台常用的框架整理(转)
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的 学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累了一些开源的组件,就目前想到的先整理于此,如果再想到, ...
- 【转】基于.NET平台常用的框架整理
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累 了一些开源的组件,就目前想到的先整理于此,如果再想到, ...
- 基于.NET平台常用的框架整理
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累了一些开源的组件,就目前想到的先整理于此,如果再想到,就 ...
- 基于.NET平台常用的框架整理【转】
转:http://www.cnblogs.com/hgmyz/p/5313983.html 自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产 ...
- ( 转)基于.NET平台常用的框架整理
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累了一些开源的组件,就目前想到的先整理于此,如果再想到,就 ...
- 基于.NET平台常用的框架整理 (转)
http://www.cnblogs.com/hgmyz/p/5313983.html 自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了 ...
- 基于.NET平台常用的框架和开源程序整理
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中 也积累了一些开源的组件,就目前想到的先整理于此,如果再想到, ...
随机推荐
- ASP.NET系统对象
一.ASP.NET 系统对象 Request:用来获取客户端在Web请求期间发送的值,如URL参数,表单参数 Response:用来负者返回到客户端的HTTP输出 ...
- 转:敏捷开发之Scrum扫盲篇
现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述Scrum中 ...
- DNS区域传送漏洞实验以及二级域名爆破
DNS区域传送漏洞实验以及二级域名爆破 目录: 1.DNS服务器的域传送漏洞(nslookup交互式.非交互式.批处理三种方式) 2.写个二级域名爆破脚本 一.DNS服务器的域传送漏洞 实验环境: 服 ...
- 将正在运行的Proxmox EV5.x版本更新到最新版本
问题描述: 最近搭建了一个KVM开源虚拟化平台 Proxmox Virtual Environment是一种基于QEMU / KVM和LXC的开源服务器虚拟化管理解决方案.您可以使用集成的,易于使用的 ...
- php学习----基本介绍及数据类型
php 官方手册:http://php.net/manual/zh/ 1.PHP(全称 Hypertext Preprocessor,超文本预处理器的字母缩写)是一种服务器端脚本语言,它可嵌入到 HT ...
- Servlet(一):Hello Servlet
今天介绍的专题是servlet和jsp,属于web开发中的基础,先来实际操作一下servlet,创建你的第一个web小项目. 1.新建一个maven项目. 鼠标右键单击eclipse左边项目栏的空白区 ...
- JDBC复习2
前面复习了一些基础知识以及如何抽取一些常用的代码,接下来就结合junit4做一个增删改查的小demo 重点是这么几个步骤:1.创建连接 2.编写sql语句 3.编写sql语句的载体 4.如果是Prep ...
- 本地项目上传到CODING
1.在Coding上添加项目 1).新建项目 README:一般项目中都会添加一个README文件对项目进行概述,以便一目了然地知道这个项目是做什么用的,如何使用等信息.README文件采用markd ...
- Web开发人员vs网页设计师
Web开发人员vs网页设计师 我们都遇到过,但实际的区别是什么?如果您是该领域的新手,请阅读详细内容,这些内容比您想象的更重要. 经过几周(或几个月)的规划和准备,进行市场调查,与其他企业家交谈,现在 ...
- 因PHP漏洞,超过4.5万个中国网站被攻击
因PHP漏洞,超过4.5万个中国网站被攻击 日前据外媒ZDNet了解,超过4.5万个中国网站受到了试图进入网络服务器的不法分子攻击. 此次黑客利用中国网络安全公司VulnSpy在ExploitDB上发 ...