Nginx搭建flv视频点播服务器

Nginx搭建flv视频点播服务器

        前一段时间使用Nginx搭建的多媒体服务器只能在缓冲过的时间区域内拖放, 而不能拖放到未缓冲的地方. 这就带来了一个问题: 如果视频限速的速率很小, 那么客户端观看视频时肯定不流畅, 而且用户不能向前拖放, 用户体验很不好. 如果视频限速的速率很大或者不限速, 服务器是承受不了的, 特别是在某个热门视频高并发访问的情况下, 而且客户端浏览器也在快速的从服务器接收数据, 同样会造成客户端视频播放不流畅的问题, 对服务器的性能和网络带宽都是很大的挑战. 所以很有必要将实现视频服务器的点播功能, 这样既可以对视频进行限速, 避免大量不必要数据在网上的传送, 又可以改善用户体验.

        本文主要参考了 [1] 的实现, 期间会遇到各种意想不到问题, 然后从网上搜索到了解决方法. 本次搭建使用的Nginx版本是1.4.1, jwplayer的版本是6.6.

资料:

HTTP Live Streaming(缩写是 HLS)是一个由苹果公司提出的基于HTTP的流媒体 网络传输协议。
HLS只请求基本的HTTP报文,与实时传输协议(RTP)不同,HLS可以穿过任何允许HTTP数据通过的防火墙或者代理服务器。它也很容易使用内容分发网络来传输媒体流。

一 准备

搭建点播服务器需要如下几个模块:

  • nginx_mod_h264_streaming: 使nginx支持h264编码的视频
  • http_flv_module: 支持flv
  • http_mp4_module: 支持mp4
  • nginx-rtmp-module: 支持rtmp协议

其中http_flv_module和http_mp4_module两个模块是nginx自带的, 可以在编译的时候加上相应的选项.

nginx_mod_h264_streaming的下载地址: http://h264.code-shop.com/trac/wiki/Mod-H264-Streaming-Nginx-Version2

nginx-rtmp-module托管在GitHub上: https://github.com/arut/nginx-rtmp-module

注意在GitHub的"Build"部分有这样一句话:

Several versions of nginx (1.3.14 - 1.5.0) require http_ssl_module to be added as well:

1
./configure --add-module=<path-to-nginx-rtmp-module> --with-http_ssl_module

我用的nginx版本是1.4.1, 所以在configure的时候需要加上"--with-http_ssl_module"选项, 否则会出现错误:

1
2
3
4
5
src/http/ngx_http_request.c: 在函数‘ngx_http_set_virtual_server’中:
src/http/ngx_http_request.c:1992:9: 错误: 未知的类型名‘ngx_http_ssl_srv_conf_t’
src/http/ngx_http_request.c:1999:16: 错误: ‘ngx_http_ssl_module’未声明(在此函数内第一次使用)
src/http/ngx_http_request.c:1999:16: 附注: 每个未声明的标识符在其出现的函数内只报告一次
src/http/ngx_http_request.c:2001:17: 错误: 在非结构或联合中请求成员‘verify’

ssl的安装可以参考网上教程, 也可以参考 [1] . 注意Ubuntu环境下SSL库是libssl-dev:

sudo apt-get install libssl-dev

 

关于ffmpeg及其依赖库的安装, 请参考我的上一篇文章:http://www.cnblogs.com/wanghetao/p/3386311.html, 在此不再赘述.

   

 二 安装Nginx及其相关模块

(Nginx使用的是Perl正则表达式, 所以需要首先安装PCRE, 读者能够从网上找到PCRE的安装过程, 在此不赘述. )

# mkdir nginx

# cd nginx

# cp ../nginx-1.4.1.tar.gz ../nginx_mod_h264_streaming-2.2.7.tar.gz ../nginx-rtmp-module-master.zip ./

#  tar -zxvf nginx-1.4.1.tar.gz                                   (同样地将其余两个包解压缩)

# cd nginx-1.4.1

# ./configure --prefix=/usr/local/nginx --add-module=../nginx_mod_h264_streaming-2.2.7 --add-module=../nginx-rtmp-module-master/ --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_stub_status_module --with-cc-opt="-I/usr/local/ffmpeg2/include" --with-ld-opt="-L/usr/local/ffmpeg2/lib"

# make

这个时候出现了错误:

1
2
3
4
5
6
7
8
9
10
../nginx_mod_h264_streaming-2.2.7/src/mp4_reader.c: 在函数‘esds_read’中:
../nginx_mod_h264_streaming-2.2.7/src/mp4_reader.c:377:16: 错误: 变量‘stream_priority’被设定但未被使用 [-Werror=unused-but-set-variable]
../nginx_mod_h264_streaming-2.2.7/src/mp4_reader.c:376:12: 错误: 变量‘stream_id’被设定但未被使用 [-Werror=unused-but-set-variable]
../nginx_mod_h264_streaming-2.2.7/src/mp4_reader.c: 在函数‘stsd_parse_vide’中:
../nginx_mod_h264_streaming-2.2.7/src/mp4_reader.c:529:22: 错误: 变量‘level_indication’被设定但未被使用 [-Werror=unused-but-set-variable]
../nginx_mod_h264_streaming-2.2.7/src/mp4_reader.c:528:22: 错误: 变量‘profile_compatibility’被设定但未被使用 [-Werror=unused-but-set-variable]
../nginx_mod_h264_streaming-2.2.7/src/mp4_reader.c:527:22: 错误: 变量‘profile_indication’被设定但未被使用 [-Werror=unused-but-set-variable]
../nginx_mod_h264_streaming-2.2.7/src/mp4_reader.c:526:22: 错误: 变量‘configuration_version’被设定但未被使用 [-Werror=unused-but-set-variable]
cc1: all warnings being treated as errors
make[1]: *** [objs/addon/src/mp4_reader.o] 错误 1

 # vim objs/Makefile (修改objs/Makefile文件, 去掉其中的"-Werror"), 然后就能够正常编译了.

# make

# make install

至此nginx安装成功了.

 

三 修改nginx配置文件nginx.conf, 配置虚拟主机

这一部分请参考 [1] , 其中比较传神的地方是限速功能的实现. 使用一个端口提供视频文件视频文件的访问以及并发访问量和限速功能(比如8081), 然后从另一个端口配置虚拟主机, 在网页中使用http协议对8081的视频文件进行访问.

 

四 flv文件转码和元数据的注入

使用ffmpeg转码后的flv文件需要注入元数据(metadata)之后才能实现拖放, metadata中主要是关键帧. 我使用yamdi实现元数据的注入. yamdi为flv文件增加了很多metadata信息,比如创建者、是否有关键帧、是否有视频、是否有音频,视频高度和宽度等等。而yamdi加入的meta数据中,最有效的要数关键帧。被注入了关键帧的flv可以实现像土豆网、优酷网等大型视频网站一样的“拖进度”,提前拖到缓冲还未加载到的位置开始播放。另一个可用的工具是flvtool2, 网上一个文章提供了两者的用法和比较: http://blog.csdn.net/zhangxh1013/article/details/5896482.

yamdi的安装也很简单:

(1) 下载: http://yamdi.sourceforge.net/

(2) # tar -zxvf yamdi-1.9.tar.gz

(3) # cd yamdi-1.9

(4) # make & make install

元数据注入:

1
yamdi -i input.flv -o output.flv

 

输出的文件使用ffmpeg查看, 可以看到这样的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Metadata:
   creator         : m_8efd9a8eb9c1c7434e76fc0e27052f91_md Tudou, Inc.
   metadatacreator : Tudou Metadata Injector for FLV - Version 1.0
   hasKeyframes    : true
   hasVideo        : true
   hasAudio        : true
   hasMetadata     : true
   canSeekToEnd    : false
   datasize        : 14485828
   videosize       : 13399710
   audiosize       : 1041346
   lasttimestamp   : 251
   lastkeyframetimestamp: 245
   lastkeyframelocation: 14458306
   encoder         : Lavf55.12.100

 这说明元数据注入成功, 并且输出文件中含有关键帧.

当然, 在ffmpeg转码的同时也可以向flv文件中加入关键帧, 只需加入 "-keyint_min" 参数. ffmpeg文档中对此的解释是:

1
2
3
‘keyint_min integer (encoding,video)’
    Set minimum interval between IDR-frames.      (设定IDR帧之间的最小间隔)

 

但是用ffmpeg转码的方法添加元数据仍然不能对视频随意拖放, 用ffmpeg可以看到转码后的视频的元数据信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ffmpeg -i output.flv
......
 Metadata:
    creator         : m_8efd9a8eb9c1c7434e76fc0e27052f91_md Tudou, Inc.
    metadatacreator : Tudou Metadata Injector for FLV - Version 1.0
    hasKeyframes    : true
    hasVideo        : true
    hasAudio        : true
    hasMetadata     : true
    canSeekToEnd    : false
    datasize        : 14485828
    videosize       : 13399710
    audiosize       : 1041346
    lasttimestamp   : 251
    lastkeyframetimestamp: 245
    lastkeyframelocation: 14458306
    encoder         : Lavf55.12.100

 它与使用yamdi方法产生的结果的位于区别是"canSeekToEnd"为false, 为什么这样的flv视频不能拖放还有待于以后研究.

 

五 jwplayer播放器的设定

通过以上四个步骤, flv视频点播服务器已经基本搭建成功了. 下面要使用jwplayer播放视频, 检验以上的设置是否成功. 编写以下PHP文档并在浏览器中打开:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE heml>
<html>
    <head>
        <script type="text/javascript" src="jwplayer/jwplayer.js"></script>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    </head>
     
    <body>       
        <div id="myElement">Loading the page...</div>
        <script type="text/javascript">
            var file_name = "<?php echo  $_GET['id']; ?>";
            jwplayer("myElement").setup({
                file: "http://localhost:82/" + file_name,
                // image: "data/myposter.jpg",
                title: file_name,
            });
        </script>
    </body>
</html>

  

 浏览器中输入URL:

1
http://localhost/videoplayer/?id=output.flv

 满怀激动地心情, 结果还是失望了: 视频仍然不能拖放!!! 为什么会这样呢? 原因是jwplayer的设定不正确. 需要向jwplayer中添加SEEK功能, 告诉它要对文件进行seek, 这是通过"starttime"参数实现的. 可以参考: http://www.longtailvideo.com/support/jw-player/28855/pseudo-streaming-in-flash. 对于不同编码和不同视频格式的文件, "starttime"的值各不相同. 对于h264编码的flv格式文件, "starttiem"设为"start".

 

修改完成后, 在浏览器中再次输入URL, 尝试拖动进度条, 成功了!!! 真的很高兴..来个高清大图给乃们瞧瞧.

参考文献:

[1] http://5iqiong.blog.51cto.com/2999926/1132639

分类: ffmpeg与multimedia

转载于:https://www.cnblogs.com/archoncap/p/4988907.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编码拾遗

1 #!/usr/bin/env python32 #-*- coding:utf-8 -*-3 4 Administrator 5 2018/8/16 6 7 8 # fopen("demo","r",encoding"utf8")9 # dataf.read() 10 # print(data) 11 # f.close() 12 13 14 # print("沈哲子") 15 16 s"中国&qu…

mybatis 不生效 参数_Mybatis-日志配置

日志Mybatis 的内置日志工厂提供日志功能&#xff0c;内置日志工厂将日志交给以下其中一种工具作代理&#xff1a;SLF4JApache Commons LoggingLog4j 2Log4jJDK loggingMyBatis 内置日志工厂基于运行时自省机制选择合适的日志工具。它会使用第一个查找得到的工具(按上文列举的顺…

PS通过滤色实现简单的图片拼合

素材如下&#xff1a; 素材一&#xff1a; 雪山 素材二&#xff1a; 月亮 效果&#xff1a; 实现步骤 1、在PS中打开雪山素材一 2、将月亮素材直接拖入雪山所在的图层中 3、锁定置入素材的高宽比&#xff08;点击一下链状按钮&#xff09; 4、调整月亮到合适大小合适位置 5、…

预处理:主成分分析与白化

主成分分析 引言 主成分分析&#xff08;PCA&#xff09;是一种能够极大提升无监督特征学习速度的数据降维算法。更重要的是&#xff0c;理解PCA算法&#xff0c;对实现白化算法有很大的帮助&#xff0c;很多算法都先用白化算法作预处理步骤。 假设你使用图像来训练算法&#x…

swagger 修改dto注解_Web服务开发:Spring集成Swagger,3步自动生成API文档

目录&#xff1a;1&#xff0c;Spring Boot集成Swagger2&#xff0c;Swagger接口文档页面3&#xff0c;常见问题和解决方法在Sping开发REST接口服务时&#xff0c;API文档是不可缺少的一个重要部分。Swagger框架定义了完整的REST接口文档规范&#xff0c;提供了强大的页面测试功…

WPF自定义控件之列表滑动特效 PowerListBox

列表控件是应用程序中常见的控件之一&#xff0c;对其做一些绚丽的视觉特效&#xff0c;可以让软件增色不少。 本人网上看过一个视频&#xff0c;是windows phone 7系统上的一个App的列表滚动效果&#xff0c;效果非常炫 现在在WPF上用ListBox重现此效果 首先我们来分析一下&am…

CnosDB如何确保多步操作的最终一致性?

背景 在时序数据库中&#xff0c;资源的操作是一个复杂且关键的任务。这些操作通常涉及到多个步骤&#xff0c;每个步骤都可能会失败&#xff0c;导致资源处于不一致的状态。例如&#xff0c;一个用户可能想要在CnosDB集群中删除一个租户&#xff0c;这个操作可能需要删除租户…

颈椎前路caspar撑开器_“骨质增生”导致的颈椎病怎么破?

来源&#xff1a;《脊柱外科微创手术精要》作者&#xff1a;中日友好医院 邹海波此文是区别于颈椎间盘软性突出诊治一文&#xff0c;主要针对“骨质增生”导致的颈椎病(Spondylosis)进行介绍。传统的颈椎前路手术主要为颈椎病而设计。一度认为对颈椎病采用前路手术的主要好处在…

Struts2整合Freemarker生成静态页面

2019独角兽企业重金招聘Python工程师标准>>> 这是生成静态页面的预览&#xff1a; 其对应的模板文件&#xff1a; <table style"text-align:center;FONT-SIZE: 11pt; WIDTH: 600px; FONT-FAMILY: 宋体; BORDER-COLLAPSE: collapse" borderColor#3399ff…

快速幂、矩阵快速幂、快速乘法

快速幂 快速幂是我们经常用到的一种算法&#xff0c;快速幂顾名思义就是快速的幂运算。我们在很多题目中都会遇到幂运算&#xff0c;但是在指数很大的时候&#xff0c;我们如果用for或者是pow就会超时&#xff0c;这时候就用到了快速幂。 快速幂的原理就是&#xff0c;当求b^p的…

vue 前端显示图片加token_手摸手,带你用vue撸后台 系列二(登录权限篇)

完整项目地址&#xff1a;vue-element-adminhttps://github.com/PanJiaChen/vue-element-admin前言拖更有点严重&#xff0c;过了半个月才写了第二篇教程。无奈自己是一个业务猿&#xff0c;每天被我司的产品虐的死去活来&#xff0c;之前又病了一下休息了几天&#xff0c;大家…

注释工具_苹果已购丨Notability丨功能强大而简单易用的笔记及PDF注释工具

点击上方“天泽黑科技”右上角“...”点选“设为星标”点击加星★ 贴近你心 ❤今天给大家购买效率类排行第3名的 Notability &#xff01;大家在桌面 App store 登陆我的账号&#xff0c;搜索下载即可&#xff01;荣获 iPad、iPhone 和 Mac 的 Apple「编」爱新 App 殊荣&#x…

第四章 大网高级   NSSA

STUB、完全stub、NSSA、完全nssa实验要求&#xff1a;1、配置IP地址2、配置OSPF多区域3、配置 stub 末梢区域4、配置完全stub末梢区域5、配置 nssa 非纯末梢区域6、配置完全nssa非纯末梢区域7、配置两种协议相互注入重分发8、实现全网互通一、配置OSPF多区域二、配置rip v2三、…

[AlwaysOn Availability Groups] 健康模型 Part 2 ——扩展

[AlwaysOn Availability Groups] 健康模型 Part 2 ——扩展 健康模型扩展 第一部分已经介绍了AlwayOn健康模型的概述。现在是创建一个自己的PBM策略&#xff0c;然后设置为制定的归类。创建这些策略&#xff0c;创建之后修改一下配置&#xff0c;dashboard就会自动评估这些策略…

665. Non-decreasing Array - LeetCode

Question 665. Non-decreasing Array Solution 题目大意&#xff1a; 思路&#xff1a;当前判断2的时候可以将当前元素2变为4&#xff0c;也可以将上一个元素4变为2&#xff0c;再判断两变化后是否满足要求。 Java实现&#xff1a; public boolean checkPossibility(int[] nums…

如何制作印章_如何用Photoshop制作个性印章/文字图片

带印章和文字的图片&#xff0c;不仅可以作为个人的标签&#xff0c;更能直接表达照片的意境&#xff0c;让片子与众不同。那么&#xff0c;怎样才能给照片加印章和文字呢&#xff1f;或许方法有很多&#xff0c;甚至有多款App也可以直接做效果。但想要做出精细的效果&#xff…

麒麟810处理器_麒麟810性能实测:对比骁龙845骁龙730,谁更强?

随着荣耀9X、Nova5i Pro一众新机发布&#xff0c;采用7nm工艺制程的全新麒麟810进入了我们的视野。以手机处理器性能划分产品定位向来是最为直接的方法&#xff0c;在搭载麒麟810的荣耀9X将价格下探到1399元后&#xff0c;这枚网友口中“拳打845&#xff0c;脚踢730”的中端神u…

打造全键盘操作的PDF阅读器

其实我只想要一个非常简单的PDF阅读器&#xff0c;不要很花哨的功能&#xff0c;只要能够&#xff1a; 速度够快&#xff0c;不要翻一页等半天&#xff1b;全键盘操作&#xff0c;不想在鼠标和键盘之间来回倒腾&#xff1b;可以改变背景色&#xff0c;深夜的白光好刺眼&#xf…

mysql 导出dmp文件_一文带你了解MySQL主从复制(Master-Slave)

1.复制概述Mysql内建的复制功能是构建大型&#xff0c;高性能应用程序的基础。将Mysql的数据分布到多个系统上去&#xff0c;这种分布的机制&#xff0c;是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上&#xff0c;并重新执行一遍来实现的。复制过程中一个服务器充当…

iOS开发学无止境 - NSFileManager文件操作的十个小功能

&#xff08;配图的小故事还记得嘛&#xff09; NSFileManager是一个单列类&#xff0c;也是一个文件管理器。可以通过NSFileManager创建文件夹、创建文件、写文件、读文件内容等等基本功能。 下面将介绍NSFileManager文件操作的十个小功能。我们在Documents里面进行举例&#…