一、RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。支持该协议的软件包括Adobe Media Server/Ultrant Media Server/red5等。

  RTMP(Real Time Messaging Protocol)实时消息传送协议是Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输 开发的开放协议。

  它有多种变种:
  1)RTMP工作在TCP之上,默认使用端口1935;
  2)RTMPE在RTMP的基础上增加了加密功能;
  3)RTMPT封装在HTTP请求之上,可穿透防火墙
  4)RTMPS类似RTMPT,增加了TLS/SSL的安全功能;
  二、上面介绍了RTMP协议主要用来干什么的,下面说明一下NGINX-RTMP主要的作用。我们在做视频流的推送的时候,一般都是采用rtmp的协议进行视频流的推送工作。而这里我们主要说道的是nginx提供的一套视频流的解决方案,主要插件为nginx-rtmp-module。他提供RTMP/HLS/MPEG-DASH这几种方式,下面我具体说一下安装部署过程,当然可以参考官方文档。
  三、我们来做种写一下实现过程,这里面涉及到很多的文档,需要自己动手查看官方文档等,下面的环境基本都是在linux上面完成。当然可以使用其他环境,根据自己需要修改
  1)安装nginx和nginx-rtmp-module模块
  1.   nginx下载地址:http://nginx.org/download/nginx-1.17.3.tar.gz
  2.   nginx-rtmp-module下载地址:https://github.com/arut/nginx-rtmp-module(直接使用git下载然后解压即可)
  
  解压
  1. # tar -zxf nginx-1.17.3.tar.gz
  2. # unzip nginx-rtmp-module-master.zip
  

  修改nginx-rtmp-module-master为nginx-rtmp-module

  1. # mv nginx-rtmp-module-master nginx-rtmp-module
  安装,官方提供的方式
  1. cd nginx-1.17.3
    ./configure --add-module=/usr/local/nginx-rtmp-module
  2. make
  3. make install

  少依赖的错误解决:

  1. apt-get install libpcre3 libpcre3-dev

  1. apt-get install openssl libssl-dev

  成功过后我们看见nginx依赖包有

  1. sudo apt-get install zlib1g-dev

  接下来就是执行上面的安装步骤,完成时在/usr/local/下面会产生一个nginx目录

  2)在nginx中配置rtmp服务

  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. rtmp {
  6. server {
  7.  
  8. listen 1935;
  9.  
  10. chunk_size 4000;
  11.  
  12. application play {
  13. play /usr/local/nginx/html/play;
  14. }
  15. application hls {
  16. live on;
  17. hls on;
  18. hls_path /usr/local/nginx/html/hls;
  19. hls_fragment 1s;
  20. hls_playlist_length 4s;
  21. }
  22. application live {
  23. live on;
  24. }
  25. }
  26. }
  27.  
  28. http {
  29. include mime.types;
  30. default_type application/octet-stream;
  31. sendfile on;
  32. keepalive_timeout 65;
  33. server {
  34. listen 8000;
  35. server_name localhost;
  36. location /stat {
  37. rtmp_stat all;
  38. rtmp_stat_stylesheet stat.xsl;
  39. }
  40. location /stat.xsl {
  41. # XML stylesheet to view RTMP stats.
  42. # Copy stat.xsl wherever you want
  43. # and put the full directory path here
  44. root /usr/local/nginx-rtmp-module;
  45. }
  46. location /hls {
  47. # Serve HLS fragments
  48. types {
  49. application/vnd.apple.mpegurl m3u8;
  50. video/mp2t ts;
  51. }
  52. root /usr/local/nginx/html;
  53. add_header Cache-Control no-cache;
  54. }
  55. }
  56. }

  说明:

  a、rtmp配置:

    play为视频播放配置,静态文件播放。

    hls为通过推送的方式,保存视频片段ts文件,通过m3u8来播放。

    live就只是单纯的视频流推送。

  其中hls的配置相对复杂,主要涉及延时优化的功能,一般采用如下配置:

  1. hls_fragment 1s;
  2. hls_playlist_length 4s;

  b、http配置:

      stat和stat.xsl主要访问视频推送概况,注意目录指向

    hls主要是配置视频流的访问(m3u8格式视频)

  3)启动:

  1. # ./sbin/nginx -c conf/nginx.conf

  4)测试(测试工具VLC):

  a、第一种,play

  链接:

  1. rtmp://192.168.5.23:1935/play/test.mp4

   b、第二种、hls这里我们需要一个推流软件obs来测试,obs下载

  根据推送的地址,我们有两种测试方式,一种为rtmp,一种为m3u8

  rtmp地址:

  1. rtmp://192.168.5.23:1935/hls/test

  可以看出现在是存在一些延迟,但是延迟不是很大可以接受。

  m3u8地址:

  1. http://192.168.5.23:8000/hls/test.m3u8

  这里可以看出延迟就很高了,如果对于延迟较小的方式这种方式就不是很适合了

  c、第三种方式,live(这种方式和rtmp的第一种是一样的,只是没有了hls的方式来缓存)

  链接:

  1. rtmp://192.168.5.23:1935/live/test

  四、上面只是对于视频流的推送做了很多配置,下面我们通过实例的方式来呈现工程中的应用。
  1)说一下架构,基本采用springboot,videojs实现。目录结构为
  

  2)springboot的配置基本没啥,主要是通过videojs提供的方式去实现流的读取

  m3u8(hls.html)

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>hls</title>
  6. <link href="css/video-js.css" rel="stylesheet">
  7. <script src="js/video.js"></script>
  8. <script src="js/hls/videojs-contrib-hls.js"></script>
  9.  
  10. </head>
  11. <body>
  12. <h1>hls</h1>
  13.  
  14. <!--常用-->
  15. <video class="video-js vjs-default-skin vjs-big-play-centered"
  16. controls preload="auto"
  17. width="460" height="256"
  18. data-setup='{}'>
  19. <source src="http://192.168.5.23:8000/hls/test.m3u8" type="application/x-mpegURL">
  20. </video>
  21.  
  22. <!--video-js标签-->
  23. <video-js class="vjs-default-skin vjs-big-play-centered"
  24. controls preload="auto"
  25. width="460" height="256"
  26. data-setup='{}'>
  27. <source src="http://192.168.5.23:8000/hls/test.m3u8" type="application/x-mpegURL">
  28. </video-js>
  29.  
  30. <!--选择器-->
  31. <video id="test"
  32. class="video-js vjs-default-skin vjs-big-play-centered"
  33. controls preload="auto"
  34. width="460" height="256">
  35. <source src="http://192.168.5.23:8000/hls/test.m3u8" type="application/x-mpegURL">
  36. </video>
  37.  
  38. <script>
  39. // {}和data-setup一样,function为回调函数
  40. var player = videojs("test", {
  41. "autoplay":true
  42. }, function (res) {
  43. console.log(res)
  44. });
  45. player.play();
  46. </script>
  47. </body>
  48. </html>

  m3u8(stream.html)

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset=utf-8 />
  5. <title>stream</title>
  6. <link href="css/video-js.css" rel="stylesheet">
  7. <script src="js/video.js"></script>
  8. <script src="js/stream/videojs-http-streaming.js"></script>
  9. </head>
  10. <body>
  11. <h1>stream</h1>
  12. <video class="video-js vjs-default-skin vjs-big-play-centered"
  13. controls preload="auto"
  14. width="1366" height="768"
  15. data-setup='{}'>
  16. <source src="http://192.168.5.23:8000/hls/test.m3u8" type="application/x-mpegURL">
  17. </video>
  18. </body>
  19. </html>

  rtmp(rtmp.html)

  1. <html lang="en">
  2. <head>
  3. <meta charset="UTF-8">
  4. <title>rtmp</title>
  5. <link href="css/video-js.css" rel="stylesheet">
  6. <script src="js/video.js"></script>
  7. <script src="js/rtmp/videojs-flash.min.js"></script>
  8. </head>
  9. <body>
  10. <h1>rtmp</h1>
  11. <video class="video-js vjs-default-skin vjs-big-play-centered"
  12. width="1366" height="768"
  13. data-setup='{"techOrder":["flash"], "autoplay":true}'>
  14. <source src="rtmp://192.168.5.23:1935/hls/test" type="rtmp/flv">
  15. </video>
  16. <script>
  17. videojs.options.flash.swf="js/rtmp/video-js.swf";
  18. </script>
  19. </body>
  20. </html>

  3)为了更加接近项目我这里使用了摄像头的来达到想过,实现方式通过ffmpeg进行摄像头流的推送

  ffmpeg安装

  1. # apt-get install ffmpeg

  rtsp推送方式:

  1. ffmpeg -rtsp_transport tcp -i 'rtsp://admin:admin1234@192.168.112.252:554/cam/realmonitor?channel=1&subtype=0' -stimeout '3000000' -vcodec copy -acodec copy -f flv -y 'rtmp://localhost:1935/hls/test'
  1. package com.cetc.ffmpeg;
  2.  
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.boot.CommandLineRunner;
  6. import org.springframework.stereotype.Component;
  7.  
  8. import java.io.BufferedReader;
  9. import java.io.IOException;
  10. import java.io.InputStreamReader;
  11.  
  12. @Component
  13. public class InitCamera implements CommandLineRunner{
  14.  
  15. private static Logger logger = LoggerFactory.getLogger(InitCamera.class);
  16.  
  17. @Override
  18. public void run(String... args) throws Exception {
  19. String shell =
          "ffmpeg -rtsp_transport tcp -i 'rtsp://admin:admin1234@192.168.112.252:554/cam/realmonitor?channel=1&subtype=0' -stimeout '3000000' -vcodec copy -acodec copy -f flv -y 'rtmp://localhost:1935/hls/test'";
  20. String[] cmd = new String[] {"sh", "-c", shell};
         ThreadLocal<String[]> threadLocal = new ThreadLocal<>();
  21. new Thread(new Runnable() {
  22.  
  23. @Override
  24. public void run() {
  25. threadLocal.set(cmd);
  26. while (true) {
  27. try {
  28. Process process = Runtime.getRuntime().exec(threadLocal.get());
  29. new Thread(() -> {
  30. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  31. String str;
  32. try {
  33. logger.info("start");
  34. while ((str = bufferedReader.readLine()) != null) {
  35. logger.info(str);
  36. }
  37. logger.info("exit");
  38. process.exitValue();
  39. } catch (IOException e) {
  40. e.printStackTrace();
  41. }
  42. }).start();
  43. process.waitFor();
  44. logger.info("ffmpeg restart");
  45. } catch (Exception e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. }
  50. }).start();
  51. }
  52. }

  4)通过springboot,maven插件打成jar包,运行

  1. java -jar spring-nginx-rtmp-1.0-SNAPSHOT.jar &

  5)测试结果

  特别说明:videojs这类视频流的方式不能使用本地html的测试方式,必须使用容器启动,比如(tomcat,node,jetty等)
  我这里使用的springboot框架,底层还是tomcat支持,请熟知。
  五、参考的相关文档
  1)nginx-rtmp-module安装及配置:https://github.com/arut/nginx-rtmp-module
  2)nginx-rtmp-module配置详情:https://github.com/arut/nginx-rtmp-module/wiki/Directives
  3)videojs:
    https://blog.videojs.com/ 官方博客
    https://docs.videojs.com/tutorial-options.html videojs的相关参数配置
  六、Javaweb端源码

nginx-rtmp之直播视频流的推送的更多相关文章

  1. 【Nginx】如何格式化日志并推送到远程服务器?看完原来很简单!!

    写在前面 Nginx作为最常用的反向代理和负载均衡服务器,被广泛的应用在众多互联网项目的前置服务中,很多互联网项目直接将Nginx服务器作为整个项目的流量入口.这就使得我们可以通过对Nginx服务器日 ...

  2. 三、Windows下用FFmpeg+nginx+rtmp搭建直播环境 实现推流、拉流

    一.环境 1.开发环境:windows 2.开发工具:FFmpeg.nginx.nginx-rmtp-module (链接:https://pan.baidu.com/s/119d2GeMzddas_ ...

  3. 升级NGINX支持HTTP/2服务端推送

    内容概览 NGINX从1.13.9版本开始支持HTTP/2服务端推送,上周找时间升级了下NGINX,在博客上试验新的特性. 升级工作主要包括: 升级NGINX 修改NGINX配置 修改wordpres ...

  4. iOS开发之利用IJKPlayer+nginx+rtmp搭建直播的推流和拉流

    最近项目中想实现直播的功能,所以研究了一段时间的直播功能,当然也是在别人的基础上不断的学习实现的,所以记录一下,希望对大家有所帮助. 直播拉流功能: 这里使用了开源的IJKPlayer第三框架,ijk ...

  5. Centos7 搭建Nginx+rtmp+hls直播推流服务器

    1 准备工具 使用yum安装git [root~]# yum -y install git 下载nginx-rtmp-module,官方github地址 // 通过git clone 的方式下载到服务 ...

  6. RTSP安防摄像机(海康大华宇视等)如何推送到RTMP流媒体服务器进行直播

    方案介绍 目前互联网直播的CDN和标准RTMP流媒体服务器通常只能接收RTMP格式的音视频推流.目前市场上有一些自带RTMP推流的摄像机和编码器,可以直接在其rtmp推流配置里面配置推送到RTMP流媒 ...

  7. Ubuntu中使用Nginx+rtmp搭建流媒体直播服务

    一.背景 本篇文章是继上一篇文章<Ubuntu中使用Nginx+rtmp模块搭建流媒体视频点播服务>文章而写,在上一篇文章中我们搭建了一个点播服务器,在此基础上我们再搭建一个直播服务器, ...

  8. EasyRTMP视频直播推送H264 sps解析错误导致播放画面拉伸问题解决

    EasyRTMP是将H264流以及AAC流以RTMP协议推送到RTMP服务器上进行直播.EasyRTMP推送库中会从H264流中提取中SPS.PPS进行解析,开发的时候遇到过有些SPS解析有误,获取到 ...

  9. Android平台摄像头/屏幕/外部数据采集及RTMP推送接口设计描述

    好多开发者提到,为什么大牛直播SDK的Android平台RTMP推送接口怎么这么多?不像一些开源或者商业RTMP推送一样,就几个接口,简单明了. 不解释,以Android平台RTMP推送模块常用接口, ...

随机推荐

  1. mysql addtime() 函数

    mysql> select addtime('1997-12-31 23:59:52' , '1 1:1:1'); +-------------------------------------- ...

  2. OpenFOAM——平行平板间具有相对运动(库埃特流)

    本算例翻译整理自:http://the-foam-house5.webnode.es/products/chapter-1-plane-parallel-plates-case/ 这个算例研究了一个距 ...

  3. 多线程 fork/join 并行计算

    1. 什么是Fork/Join框架 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 我们再通过 ...

  4. Hadoop综合大作业总评

    作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/3363 1.把python爬取的数据传到linux 2.把数据的逗号代替为  ...

  5. 剑指offer:数组中的逆序对

    题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%100 ...

  6. Android 系统属性-SystemProperties详解***

    创建与修改android属性用Systemproperties.set(name, value),获取android属性用Systemproperties.get(name),需要注意的是androi ...

  7. Python推荐一整套开发工具

    原文:https://sourcery.ai/blog/python-best-practices/ 在开始一个新的Python项目时,很容易不做规划直接进入编码环节.花费少量时间,用最好的工具设置项 ...

  8. 测量MySQL的表达式和函数的速度

    测量MySQL的表达式和函数的速度,可以调用benchmark()函数.语法格式是benchmark(loop_count,expr).运行的返回值是0,但是mysql会打印一行显示语句大概要执行多长 ...

  9. uploadifive 1.1.2 动态传参

    之前用过Flash版本的uploadify,写过一篇关于uploadify动态传参的文章(点击打开链接).后来有了HTML5版本的上传控件,叫uploadifive,测试着用了一下,效果还不错.这里主 ...

  10. linux中环境变量和系统加载环境变量的顺序

    一.系统环境变量: /etc/profile :这个文件预设了几个重要的变量,例如PATH, USER, LOGNAME, MAIL, INPUTRC, HOSTNAME, HISTSIZE, uma ...