咸鱼

咸鱼是以盐腌渍后,晒干的鱼

0%

音视频推流协议RTSP和RTMP

这是两种常用的音视频推流协议,这里简单比较一下两种协议应用场景(本文适合Java、Android开发者)。

参考:

一、RTMP

Real Time Messaging Protocol(实时消息传输协议)是 Adobe 的私有协议,设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。

基本架构:采集端rtmp-client-> web服务器rtmp-server -> 播放端rtmp-client
特点:

RTMP特性

  1. 延迟较大
  2. 传输效率相对较低
  3. 底层采用TCP,网络环境较差下,采用RTMP保证了视频的传输质量
  4. 浏览器支持
  5. 一般需要一个流服务器中转

应用场景

  1. 网络直播(如斗鱼等平台)

二、RTSP

Real Time Streaming Protocol(实时流媒体协议)在网络环境比较稳定的情况下,传输效率是比较高,虽然实时性比较好,用在互联网上可能会丢包。网络摄像头常采用RTSP协议,比如海康的摄像头。
RTSP只是一个实时流媒体协议(应用层文本协议,类HTTP),RTSP只负责会话,如建立连接、播放暂停控制等。而RTP协议(实时传输协议)负载传输音视频数据,RTP又分为 rtp over tcp rtp over udp【RFC3984中文版】【RTP/RTCP协议与RTSP协议】

一般的cs架构如下:

  • 直播: 采集端rtps-client-> web服务器rtsp-server -> 播放端rtsp-client
  • 点播: web服务器rtsp-server -> 播放端rtsp-client
  • 监控: 采集端rtsp-server -> 播放端rtsp-client

RTSP特性

通常说的RTSP包括RTSP协议、RTP协议、RTCP协议

  • RTSP协议:负责服务器与客户端之间的请求与响应
  • RTP协议:负责传输媒体数据
  • RTCP协议:在RTP传输过程中提供传输信息
    来自RTSP协议讲解

特点:

  1. 实时性比较好
  2. 传输效率是比较高
  3. 底层采用RTP传输,RTP大多数采用UDP(也可以TCP),网络复杂环境下容易丢包
  4. 浏览器不支持

应用场景

  1. 网络摄像头、安防监控(如海康摄像头)
  2. IPTV

三、开源软件

Ⅰ、推流端

  1. 【rtmp-rtsp-stream-client-java】
    纯Java编写的RTSP和RTMP推流Client(推荐学习其源码),直接封装Android的Camera层,非常容易使用,支持Camera1和Camera2 API。
  2. 【yasea】 Android RTMP 推流 Client,它将摄像头YUV和麦克风PCM数据编码到H.264/AAC中,封装在FLV中。 依赖C库:libx264、libyuv、libenc
  3. 【JavaCV推流】
    JavaCV这个项目底层调用的ffmpeg,所以RTMP和RTSP都支持。
  4. OBS
    PC桌面RTMP推流开源软件,现在网红主播用的主流软件(跨平台)。

Ⅱ、服务端

  1. 【nginx-rtmp-module】
    国人写的项目,仅支持rtmp,目前(20200708) start 9.7K ,它nginx的一个插件,需要自己编译一次nginx。
  2. 【srs】
    国人写的这是C++项目,目前(20200708) start 8.9K ,项目介绍 ,支持RTMP/HLS/WebRTC/SRT/GB28181。新版本貌似RTSP也支持了?
  3. EasyDarwin
    国内公司写的Go项目,目前(20200708) start 4.1K ,高性能开源RTSP流媒体服务器,RTSP推模式转发、RTSP拉模式转发、录像、检索、回放、关键帧缓存、秒开画面、RESTful接口、WEB后台管理、分布式负载均衡。
  4. 【AndroidShow】
    国人写的Android App项目,通过MediaProjectionManager采集Android屏幕视频流,手机采集端做rtsp server,通过rtp over udp 传输视频流,但还没有实现音频,具体看作者的博客:【Android录屏直播】

    注:传输用的【spydroid-ipcamera】代码

  5. 【spydroid-ipcamera】
    这是法国人写的Android App项目,很久远的项目了,第一次提交是2013年,它可以将您手机变成网络摄像头(提供RTSP Server),项目不再维护,但是作者将这个项目独立为一个Java库:【libstreaming】。

    注: 【spydroid-ipcamera源码分析】

  6. 【libstreaming】
    从【spydroid-ipcamera】独立出来的 Android Java库,目前(20200708) start 2.9K 。

    注: 【示例代码:libstreaming-examples】

  7. live555
    c++编写的项目,RTSP点播服务器,不支持推/拉流转发。【Live555 搭建流媒体服务器】
  8. 【RTSP-Client-Server】
    国外的Java Swing项目,目前(20200708) start 376 ,源码很少和简单(项目没有用IDE创建,用命令行编译),可读性强,运行效果是client点播server的Mjpeg文件,不依赖第三方。
  9. 【rtsp-netty-server 】
    国人写的Java项目(Elicpse),目前(20200708) start 1 。 RTP数据部分依赖【libjitsi】的RawPacket类。

    注:【libjitsi】 实时音频/视频通信的高级Java媒体库,没有在mvnrepository发布,编译很麻烦,jitsi是做视频会议全套软件的。

  10. 【monibuca】国内公司写的Go项目,目前(20200721) start 209 ,Monibuca 引擎 + 插件 = 定制化流媒体服务器。官网,这是一个新的项目,看commit记录,是2020年提交的项目。

Ⅲ、播放端和拉流

  1. VLC
  2. ffplay
  3. ijkplayer
  4. JavaCV库拉流(底层调用的ffmpeg)
  5. 【code.google.com/p/rtsplib-java】这是一个纯Java实现的 RTSPClient 远古时代的库(Eclipse),只实现了RTSP部分的协议(PLAY等方法),可以基于它实现扩展其他方法。
  6. 【srysduedu123/rtsp-h264-client】 基于 rtsplib-java ,加了解析RTP和H264 。
  7. 【htwahzs/Rtsp-Android-Client】 不依赖其他库,纯java实现RTSP、RTP、RTCP和硬解码渲染,经测试能正常播放,出图速度比ijkpaler快 。但本身这个仓库只有纯Java类(完整),不是一个完整的Android项目,我fork了此项目,做成一个Demo【kevinvane/Rtsp-Android-Client】

四、利用开源软件搭建一套直播测试平台

  • rtsp-client推流: ffmpeg 推流 或者 rtmp-rtsp-stream-client-java (Android,集成到自己项目中推荐使用)
  • rtsp-server:ffmpeg的ffserver 或者 EasyDarwin (EasyDarwin rtsp端口554,web管理后台端口10008)
  • rtsp-play: ffmpeg的ffplay 、VCL或者 ijkplayer(移动端,集成到自己项目中推荐使用)

注:EasyDarwin有提供各个平台的软件,除了服务端好用,其他觉得有点难用,不推荐。

五、流视频录制并存储方案

  1. JavaCV从流服务器拉取音视频录制
    底层是调用的是ffmpeg拉流存储

  2. EasyDarwin的方案
    EasyDarwin自带录制功能,对外提供 RESTFUL API 详细文章 -> 【EasyDarwinGo录像功能发布】
    底层也是调用的是ffmpeg拉流存储的方案,这是它默认配置文件:

    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
    [rtsp]
    port=554

    ; rtsp 超时时间,包括RTSP建立连接与数据收发。
    timeout=28800

    ; 是否使能gop cache。如果使能,服务器会缓存最后一个I帧以及其后的非I帧,以提高播放速度。但是可能在高并发的情况下带来内存压力。
    gop_cache_enable=1

    ; 是否使能向服务器推流或者从服务器播放时验证用户名密码. [注意] 因为服务器端并不保存明文密码,所以推送或者播放时,客户端应该输入密码的md5后的值。
    ; password should be the hex of md5(original password)
    authorization_enable=0

    ; 是否使能推送的同事进行本地存储,使能后则可以进行录像查询与回放。
    save_stream_to_local=0

    ;easydarwin使用ffmpeg工具来进行存储。这里表示ffmpeg的可执行程序的路径
    ffmpeg_path=/Users/ze/Downloads/ffmpeg-20180719-9cb3d8f-macos64-shared/bin/ffmpeg

    ;本地存储所将要保存的根目录。如果不存在,程序会尝试创建该目录。
    m3u8_dir_path=/Users/ze/Downloads/EasyDarwinGoM3u8

    ;切片文件时长。本地存储时,将以该时间段为标准来生成ts文件(该时间+一个I帧间隔),单位秒。
    ;如果需要直播,这个值设小点,但是这样会产生很多ts文件;如果不需要直播,只要存储的话,可设大些。
    ts_duration_second=6

    ;key为拉流时的自定义路径,value为ffmpeg转码格式,比如可设置为-c:v copy -c:a copy,表示copy源格式;default表示使用ffmpeg内置的输出格式,会进行转码。