最近研究hexo中......
  • About Me


  • 兴趣爱好

  • 上一张

HTML5视频指标扫盲

目录

返回博客列表
原 荐 【腾讯bugly干货分享】HTML 5 视频直播一站式扫盲
腾讯Bugly 腾讯Bugly
发布时间: 2016/07/04 12:35 阅读: 93 收藏: 6 点赞: 0 评论: 0
摘要
视频直播这么火,再不学就 out 了。 为了紧跟潮流,本文将向大家介绍一下视频直播中的基本流程和主要的技术点,包括但不限于前端技术。
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1277

视频直播这么火,再不学就 out 了。

为了紧跟潮流,本文将向大家介绍一下视频直播中的基本流程和主要的技术点,包括但不限于前端技术。

  1. H5 到底能不能做视频直播?

当然可以, H5 火了这么久,涵盖了各个方面的技术。

对于视频录制,可以使用强大的 webRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音对话或视频对话的技术,缺点是只在 PC 的 chrome 上支持较好,移动端支持不太理想。

对于视频播放,可以使用 HLS(HTTP Live Streaming)协议播放直播流, ios 和 android 都天然支持这种协议,配置简单,直接使用 video 标签即可。

webRTC 兼容性:

video 标签播放 hls 协议视频:

Your browser does not support HTML5 video.


  1. 到底什么是 HLS 协议?

简单讲就是把整个流分成一个个小的,基于 HTTP 的文件来下载,每次只下载一些,前面提到了用于 H5 播放直播视频时引入的一个 .m3u8 的文件,这个文件就是基于 HLS 协议,存放视频流元数据的文件。

每一个 .m3u8 文件,分别对应若干个 ts 文件,这些 ts 文件才是真正存放视频的数据,m3u8 文件只是存放了一些 ts 文件的配置信息和相关路径,当视频播放时,.m3u8 是动态改变的,video 标签会解析这个文件,并找到对应的 ts 文件来播放,所以一般为了加快速度,.m3u8 放在 web 服务器上,ts 文件放在 cdn 上。

.m3u8 文件,其实就是以 UTF-8 编码的 m3u 文件,这个文件本身不能播放,只是存放了播放信息的文本文件:

#EXTM3U m3u文件头

#EXT-X-MEDIA-SEQUENCE 第一个TS分片的序列号

#EXT-X-TARGETDURATION 每个分片TS的最大的时长

#EXT-X-ALLOW-CACHE 是否允许cache

#EXT-X-ENDLIST m3u8文件结束符

#EXTINF 指定每个媒体段(ts)的持续时间(秒),仅对其后面的URI有效
mystream-12.ts
ts 文件:

HLS 的请求流程是:
1 http 请求 m3u8 的 url。
2 服务端返回一个 m3u8 的播放列表,这个播放列表是实时更新的,一般一次给出5段数据的 url。
3 客户端解析 m3u8 的播放列表,再按序请求每一段的 url,获取 ts 数据流。

简单流程:

  1. HLS 直播延时

我们知道 hls 协议是将直播流分成一段一段的小段视频去下载播放的,所以假设列表里面的包含5个 ts 文件,每个 TS 文件包含5秒的视频内容,那么整体的延迟就是25秒。因为当你看到这些视频时,主播已经将视频录制好上传上去了,所以时这样产生的延迟。当然可以缩短列表的长度和单个 ts 文件的大小来降低延迟,极致来说可以缩减列表长度为1,并且 ts 的时长为1s,但是这样会造成请求次数增加,增大服务器压力,当网速慢时回造成更多的缓冲,所以苹果官方推荐的ts时长时10s,所以这样就会大改有30s的延迟。参考资料:https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html

  1. 视频直播的整个流程是什么?

当视频直播可大致分为:

1 视频录制端:一般是电脑上的音视频输入设备或者手机端的摄像头或者麦克风,目前以移动端的手机视频为主。

2 视频播放端:可以是电脑上的播放器,手机端的 native 播放器,还有就是 h5 的 video 标签等,目前还是已手机端的 native 播放器为主。

3 视频服务器端:一般是一台 nginx 服务器,用来接受视频录制端提供的视频源,同时提供给视频播放端流服务。

简单流程:

  1. 怎样进行音视频采集?

当首先明确几个概念:

视频编码:所谓视频编码就是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式文件的方式,我们使用的 iphone 录制的视频,必须要经过编码,上传,解码,才能真正的在用户端的播放器里播放。

编解码标准:视频流传输中最为重要的编解码标准有国际电联的H.261、H.263、H.264,其中 HLS 协议支持 H.264 格式的编码。

音频编码:同视频编码类似,将原始的音频流按照一定的标准进行编码,上传,解码,同时在播放器里播放,当然音频也有许多编码标准,例如 PCM 编码,WMA 编码,AAC 编码等等,这里我们 HLS 协议支持的音频编码方式是AAC编码。

下面将利用 ios 上的摄像头,进行音视频的数据采集,主要分为以下几个步骤:

1 音视频的采集,ios 中,利用 AVCaptureSession和AVCaptureDevice 可以采集到原始的音视频数据流。
2 对视频进行 H264 编码,对音频进行 AAC 编码,在 ios 中分别有已经封装好的编码库来实现对音视频的编码。
3 对编码后的音、视频数据进行组装封包;
4 建立 RTMP 连接并上推到服务端。

ps:由于编码库大多使用 c 语言编写,需要自己使用时编译,对于 ios,可以使用已经编译好的编码库。

x264编码:https://github.com/kewlbear/x264-ios

faac编码:https://github.com/fflydev/faac-ios-build

ffmpeg编码:https://github.com/kewlbear/FFmpeg-iOS-build-script

关于如果想给视频增加一些特殊效果,例如增加滤镜等,一般在编码前给使用滤镜库,但是这样也会造成一些耗时,导致上传视频数据有一定延时。

简单流程:

  1. 前面提到的 ffmpeg 是什么?

和之前的 x264 一样,ffmpeg 其实也是一套编码库,类似的还有 Xvid,Xvid 是基于 MPEG4 协议的编解码器,x264是基于 H.264 协议的编码器, ffmpeg 集合了各种音频,视频编解码协议,通过设置参数可以完成基于 MPEG4,H.264 等协议的编解码,demo 这里使用的是 x264 编码库。

  1. 什么是 RTMP?

Real Time Messaging Protocol(简称 RTMP)是 Macromedia 开发的一套视频直播协议,现在属于 Adobe。和 HLS 一样都可以应用于视频直播,区别是 RTMP 基于 flash 无法在 ios 的浏览器里播放,但是实时性比 HLS 要好。所以一般使用这种协议来上传视频流,也就是视频流推送到服务器。

这里列举一下 hls 和 rtmp 对比:

  1. 推流

简所谓推流,就是将我们已经编码好的音视频数据发往视频流服务器中,一般常用的是使用 rtmp 推流,可以使用第三方库 librtmp-iOS 进行推流,librtmp 封装了一些核心的 api 供使用者调用,如果觉得麻烦,可以使用现成的 ios 视频推流sdk,也是基于 rtmp 的,https://github.com/runner365/LiveVideoCoreSDK

  1. 推流服务器搭建

简简单的推流服务器搭建,由于我们上传的视频流都是基于 rtmp 协议的,所以服务器也必须要支持 rtmp 才行,大概需要以下几个步骤:

1 安装一台 nginx 服务器。

2 安装 nginx 的 rtmp 扩展,目前使用比较多的是https://github.com/arut/nginx-rtmp-module

3 配置 nginx 的 conf 文件:

rtmp {

server {  

    listen 1935;  #监听的端口

    chunk_size 4000;  


    application hls {  #rtmp推流请求路径
        live on;  
        hls on;  
        hls_path /usr/local/var/www/hls;  
        hls_fragment 5s;  
    }  
}  

}
4 重启 nginx,将 rtmp 的推流地址写为 rtmp://ip:1935/hls/mystream,其中 hls_path 表示生成的 .m3u8 和 ts 文件所存放的地址,hls_fragment 表示切片时长,mysteam 表示一个实例,即将来要生成的文件名可以先自己随便设置一个。更多配置可以参考:https://github.com/arut/nginx-rtmp-module/wiki/

根据以上步骤基本上已经实现了一个支持 rtmp 的视频服务器了。

  1. 在 html5 页面进行播放直播视频?

简单来说,直接使用 video 标签即可播放 hls 协议的直播视频:

Your browser does not support HTML5 video.



需要注意的是,给 video 标签增加 webkit-playsinline 属性,这个属性是为了让 video 视频在 ios 的 uiwebview 里面可以不全屏播放,默认 ios 会全屏播放视频,需要给 uiwebview 设置 allowsInlineMediaPlayback=YES。 业界比较成熟的 videojs,可以根据不同平台选择不同的策略,例如 ios 使用 video 标签,pc 使用 flash 等。

  1. 坑点总结

简根据以上步骤,笔者写了一个 demo,从实现 ios 视频录制,采集,上传,nginx 服务器下发直播流,h5 页面播放直播视频者一整套流程,总结出以下几点比较坑的地方:

1 在使用 AVCaptureSession 进行采集视频时,需要实现 AVCaptureVideoDataOutputSampleBufferDelegate 协议,同时在- (void)captureOutput:(AVCaptureOutput )captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection )connection 捕获到视频流,要注意的是 didOutputSampleBuffer 这个方法不是 didDropSampleBuffer 方法,后者只会触发一次,当时开始写的是 didDropSampleBuffer 方法,差了半天才发现方法调用错了。

2 在使用 rtmp 推流时,rmtp 地址要以 rtmp:// 开头,ip 地址要写实际 ip 地址,不要写成 localhost,同时要加上端口号,因为手机端上传时是无法识别 localhos t的。

这里后续会补充上一些坑点,有的需要贴代码,这里先列这么多。

  1. 业界支持

目前,腾讯云,百度云,阿里云都已经有了基于视频直播的解决方案,从视频录制到视频播放,推流,都有一系列的 sdk 可以使用,缺点就是需要收费,如果可以的话,自己实现一套也并不是难事哈。

demo地址:https://github.com/lvming6816077/LMVideoTest/

参考资料:http://www.nihaoshijie.com.cn/index.php/archives/615

适配器模式学习

目录

适配器模式:

主要分为三类:类的适配器模式,对象的适配器模式,接口的适配器模式.

优点:
1透明:通过适配器,客户端可以调用同一个接口,因而对客户端来说是透明的.
2.重用:复用了现存的类,解决了现存类和复用环境要求不一致的问题
3.低耦合:将目标类和适配类解耦,通过引入一个适配器类重用现有的适配器类,而无需修改原有的代码(遵循的是开闭原则)
Source类:
public class RunComputer {
public void useThribleTag(){
System.out.println(“使用三头电源”);
}
}

Adaptee接口:
public interface TagAdaptee {
//与Source类的方法同名
public void useThribleTag();
public void useTwoTag();
}

Adaptor类:
//继承Source类,并且实现目标适配器
//目标适配器应含Source中的方法
//这样就相对实现了Target中的方法
public class TransTagAdaptor1 extends RunComputer implements TagAdaptee{
@Override
public void useTwoTag() {
System.out.println(“转成两头电源”);
}
}

测试类:
TagAdaptee adaptee = new TransTagAdaptor1();
adaptee.useThribleTag();
adaptee.useTwoTag();

对象的适配器模式

基本思路和类适配器模式相同,只是将Adaptor类做了修改,改成持有Source类的实例,已达到解决兼容性的问题.
Adaptor类:
public class TransTagAdaptor implements TagAdaptee{
//持有Source的实例,就可以调用里面的方法
private RunComputer computer;
public TransTagAdaptor(RunComputer computer) {
super();
this.computer = computer;
}
@Override
public void useTwoTag() {
System.out.println(“转成使用两头电源”);
}
public void useThribleTag(){
computer.useThribleTag();
}
}

接口的适配器模式

大多时候我们接口中不止一个方法,会有很多的抽象方法,要写这些接口的实现就必须实现所有的方法,但是并不是所有的方法都会用到.这时借助一个抽象类,空实现所有的方法.这样我们只需和这抽象类打交道,不需要接触原始的接口.当我们用到哪些方法就重写那些方法.
Adaptee接口:
public interface TargetAdaptee {
public void method1();
public void useThribleTag();
public void useTwoTag();
}

Abstract类:
public abstract class AbstractTrans implements TargetAdaptee{
@Override
public void method1() {
}
@Override
public void useThribleTag() {
}
@Override
public void useTwoTag() {
}
}

AdaptorA:
public class TransTagAdaptor3 extends AbstractTrans{
public void useThribleTag(){
System.out.println(“任然使用三头电源”);
}
}

AdaptorB:
public class TransTagAdaptor4 extends AbstractTrans{
public void useTwoTag(){
System.out.println(“转成两头电源”);
}
}
总结

各个适配器的使用场景:
类适配器:当希望将一个类转换成满足另一个新接口的类时,可以使用此模式,创建一个类,继承原有的类,实现新的接口
对象适配器:当希望将一个对象转换成满足另一个新接口的对象时,可以使用此模式.创建一个包装类,持有(包装)一个原类的对象,在包装类的方法中,调用实例的方法即可
接口适配器:当不希望实现接口时同时实现其中所有的方法,可以使用此模式.创建一个抽象类,空实现所有的方法.需要使用时继承此抽象类,重写想要的方法

MarkDown

目录

##MaHua是什么?
一个在线编辑markdown文档的编辑器

向Mac下优秀的markdown编辑器mou致敬

##MaHua有哪些功能?

  • 方便的导入导出功能
    • 直接把一个markdown的文本文件拖放到当前这个页面就可以了
    • 导出为一个html格式的文件,样式一点也不会丢失
  • 编辑和预览同步滚动,所见即所得(右上角设置)
  • VIM快捷键支持,方便vim党们快速的操作 (右上角设置)
  • 强大的自定义CSS功能,方便定制自己的展示
  • 有数量也有质量的主题,编辑器和预览区域
  • 完美兼容Github的markdown语法
  • 预览区域代码高亮
  • 所有选项自动记忆

##有问题反馈
在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流

  • 邮件(dev.hubo#gmail.com, 把#换成@)
  • QQ: 287759234
  • weibo: @草依山
  • twitter: @ihubo

##捐助开发者
在兴趣的驱动下,写一个免费的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。
当然,有钱捧个钱场(右上角的爱心标志,支持支付宝和PayPal捐助),没钱捧个人场,谢谢各位。

##感激
感谢以下的项目,排名不分先后

##关于作者

1
2
3
4
var ihubo = {
nickName : "草依山",
site : "http://jser.me"
}

hexo搭建教程

Hexo简介
hexo是一个基于Node.js的静态博客程序,可以方便的生成静态网页托管在github和Heroku上。作者是来自台湾的@tommy351。

A fast, simple & powerful blog framework, powered by Node.js.
为什么我要使用Hexo:

之前使用过CSDN,博客园和jekyll博客,其中前两个不能算是这个博客吧,主要是使用别的提供的平台发博文,第三个jekyll,我记得是Ruby语言写的,是Github Page着力推荐的, 但其中有繁琐的git操作, 而且有一些资源加载的问题(主要是我不太懂Ruby)
最近在学习JS后端Node.js, 现在火的不行, 异步IO的机制, 所以在学习过程中发现了Hexo
Hexo更加简单优雅, 而且风格多变, 适合程序员搭建个人博客,而且支持多平台的搭建
使用的软硬件
Mac Pro #软件的安装基本都是基于brew
Node.js #v0.10.33
npm #2.1.6 包管理,类似于Python中的pip
下面正式讲述如何部署:

  1. Git安装和Github设置
    使用Mac电脑可以直brew安装,

brew install git #Mac电脑使用brew安装
sudo apt-get install git #Ubuntu系统使用这条命令安装
git操作和github上SSH设置请看这篇博文

使用Github Page搭建博客, 需要遵循一定的规则, 需要在github建立仓库,仓库名为Github用户.github.io, 更多详情请参考官方文档

  1. Node.js安装
    mac电脑可以直接通过brew安装

#安装命令
brew install node #如果我没记错的话,最新版的node.js的包中已经集成了npm包管理工具

使用以下命令验证是否安装成功
node -v
npm -v
Node.js的详细内容请参考Node.js学习笔记

  1. Hexo安装与设置
    Node, npm和Git都安装成功, 开始安装hexo,

npm install hexo -g #-g表示全局安装, npm默认为当前项目安装
Hexo使用命令:

hexo init #执行init命令初始化hexo到你指定的目录
hexo generate #自动根据当前目录下文件,生成静态网页
hexo server #运行本地服务,
浏览器输入http://localhost:4000就可以看到效果。

  1. 添加博文
    hexo new “postName” #新建博文,其中postName是博文题目
    博文会自动生成在博客目录下source/_posts\postName.md

#文件自动生成格式:
title: “It Starts with iGaze: Visual Attention Driven Networkingwith Smart Glasses” #博文题目
date: 2014-11-21 11:25:38 #生成时间

tags: Paper #标签, 多个标签使用格式[Paper1, Paper2, Paper3,…]

如果不想博文在首页全部显示, 并能出现阅读全文按钮效果, 需要在你想在首页显示的部分下添加