Live Video流媒体服务

  1. 直播流程

    视频采集>>编码>>推流>>拉流>>播放

  2. 视频格式

    MP4:不错
    webm:凑合
    ts(hls):苹果家的

  3. 协议

  • hls: video>>>m3u8—>切割成小的.ts. 小程序暂时不支持这种格式

    • 动态列表 :直播 m3u8内容在变动
    • 全量列表 :点播 完整的视频,m3u8包含全部ts信息
  • rtmp: 基于TCP, 实时消息传输协议, 向客户端推送通过flv格式

  • http-flv: 基于http, 低延时

  1. 播放器
  • flash,已进入历史的垃圾堆
  • h5播放器: video标签,常用dom属性:
    • src, width, height, controls, autoplay(移动端只有静音才能自动播放),muted(静音),loop
    • controlslist: 控制条(nodownload,nofullscreen….)
    • poster 贴图 preload预加载(可能无效)
    • volume 音量, 要在dom渲染后设置属性才有效, 0~1
    • video.currentTime 播放时间的控制,秒
    • video.src 控制播放源 video.currentSrc
  • video事件监听
    • loadstart 开始加载
    • durationchange 时长变化
    • loadedmetadata 拿到了元数据
    • lodeddata 没有足够的数据播放
    • progress 不停的加载数据
    • canplay 有数据继续播放
    • canplaythrough 有足够的数据能流畅的播放
    • play
    • pause
    • seeking 移动播放位置
    • seeked 拖动位置,加载数据结束, 可以播放了
    • waiting
    • playing
    • timeupdate 视频播放时间点变化
    • ended 视频播放到结束位置
    • error 播放出错
  1. 推流与拉流
  • nginx+ffmpeg流媒体服务器:

    –with-rtmp-module nginx_rtmp_module

    • rtmp配置:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      rtmp { #推流
      server {
      listen xxx;
      chunck_size 8000;
      }
      #rmtp 直播流配置
      application rtmplive{
      live on;
      max_connections 1024;
      }
      #hls 直播流配置
      application hls{
      live on;
      hls on;
      hls_path /home/xxx;
      hls_fragment 5s;#分片长度
      }
      }
      #....http协议里面配置
      http {
      #....
      server {
      location /hls{ #拉流通过这个地址
      types{ #响应头信息
      application/vnd.apple.mpegurl m3u8;
      video/mp2t ts;
      }
      root /home/xxx;
      add_header Cache-Control no-cache;
      }
      }
      }
    • 命令推流(rtmp协议):

      ffmpeg -re -i xxx.mp4 -vcodec libx264 -acodec aac -f flv rtmp://192.168.1.80:8080/rtmplive/rtmp
      rtmplive 对于nginx application配置, 后边url可以随便起. 默认端口1935

    • hls协议:

      ffmpeg -re -i xxx.mp4 -vcodec libx264 -acodec aac -f flv rtmp://192.168.1.80:8080/hls/stream
      safari浏览器 http: //192.168.1.80:9090/hls/stream.m3u8 (http拉流的端口号)

    • http-flv:

      flv封装单元是以tag来表示的,一个tag可以是音频tag或者视频tag,或者脚本tag及其其他类型
      flv: flvheader+[脚本tag(metadata)]+[第一个视频tag(h264_spspps)]+[第一个音频tag(aac_header)]+[第二个视频tag(h264第一个关键帧)]+ 后面就是音频和视频tag交互存在
      tag: TYPE[1byte] + body size[3byte] + timestamp [4byte] +streamID [3byte] +[body data]+[previousTagSize 4byte]
      nginx-http-flv-module: 第三方的nginx模块, 国人开发的, 应该是不错的,文档可以在github上看
      注意: 动态模块的话nginx配置文件要指定加载模块

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      推流: ffmpeg -re -i example.mp4 -vcodec copy -acodec copy -f flv rtmp://example.com[:port]/appname/streamname
      appname用于匹配rtmp配置块中的application块(更多详情见下文)。
      streamname可以随意指定。
      RTMP默认端口为1935,如果要使用其他端口,必须指定:port。

      拉流: http://example.com[:port]/dir?[port=xxx&]app=myapp&stream=mystream
      参数dir用于匹配http配置块中的location块
      HTTP默认端口为80, 如果使用了其他端口,必须指定:port。
      RTMP默认端口为1935,如果使用了其他端口,必须指定port=xxx。
      参数app用来匹配application块,但是如果请求的app出现在多个server块中,并且这些server块有相同的地址和端口配置,那么还需要用匹配主机名的server_name配置项来区分请求的是哪个application块,否则,将匹配第一个application块。
      参数stream用来匹配发布流的streamname。

      例子:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      http {
      ...
      server {
      listen 8080; #不是默认的80端口
      ...

      location /live {
      flv_live on;
      }
      }
      }
      rtmp {
      ...
      server {
      listen 1985; #不是默认的1935端口
      ...

      application myapp {
      live on;
      }
      }
      }
      1
      2
      3
      4
      http-flv: http://example.com:8080/live?port=1985&app=myapp&stream=mystream
      rmtp: rtmp://example.com[:port]/appname/streamname
      hls: http://example.com[:port]/dir/streamname.m3u8
      dash: http://example.com[:port]/dir/streamname.mpd
  • 直播源OBS推流

  1. ffmpeg
  • -r 帧率
  • -i 视频源
  • vcodec/acodec 编码格式, 可以写copy直接使用原格式
  • -f 输出格式
  1. 客户端播放器(h5)
  • video.js: 不错,装上hls插件可以跨浏览器支持
  • hls.js :小巧, UI部分方便自定义
  • flv.js: http-flv协议的, 哔哩出品
  1. 权限控制
  • nginx-rtmp-module模块的publish_notify指令
  • 开启publish_notify on;
  • notify参数:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    on_connect
    on_play
    on_publish
    on_done
    on_play_done
    on_publish_done
    on_record_done
    on_update
    ......

连接 播放 推流 断开…., 在推流的时候,通过on_publish http://xxx.com/my_auth进行权限控制
例如:

1
2
3
4
5
6
#设置直播的application名称是 myapp
application myapp{
live on; #live on表示开启直播模式
publish_notify on;
on_publish http://xxx.com/my_auth;
}

  • 权限验证的url参数

    流密钥的格式是:stream?pass=123456.
    不能用name参数, name是rtmp里的参数名. 其它参数名可以随便起pass=123456&check=123456
    notify_method可设置GET,默认是POST

  • on_publish

    这个指令设置了发布命令回调,如果这个地址返回HTTP 2XX代码继续RTMP连接
    如果返回HTTP重定向3XX ,则会重定向到指定rtmp地址上
    如果返回其他RTMP连接断开
    demo:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @RestController
    public class DemoController {

    @RequestMapping("/my_auth") //默认是post, nginx_rtmp可以修改为get方式
    public String auth(HttpServletRequest request, HttpServletResponse response,String pass) {
    try {
    if (passWord.equals("123456")){
    return "success";//验证成功的话,响应码是200,rtmp可以继续. 500会导致断开
    }else{
    response.setHeader("liveAuth","authCode error");
    response.setStatus(500);
    }
    } catch (Exception e) {
    response.setHeader("error","sys error");
    response.setStatus(500);
    }
    return "~~";
    }

    }

本文标题:Live Video流媒体服务

文章作者:啪啪啪的指针

发布时间:2018年09月02日 - 16:09

最后更新:2018年09月06日 - 10:09

原始链接:https://www.bootvue.com/2018/09/02/live/

转载说明: 转载请保留原文链接及作者。