java实现超低延迟 webrtc 直播

3 篇文章 1 订阅
2 篇文章 0 订阅

java实现超低延迟 webrtc 直播


通过转化 RTSP/ RTMP 视频流为 webrtc 推送到云端,实现超低延迟的视频直播,涉及到许多计算机网络的知识,这里就不深入讲解,感兴趣的可以自行研究。

环境描述

软件环境

  • JDK 1.8
  • kurento
  • RabbitMQ
  • coturn

硬件环境

  • 海康摄像头
  • 腾讯/阿里云 centos7

定义、首字母缩写词和缩略词

  • NAT (Network Address Translator)
  • STUN (Simple Traversal of UDP Through NAT): NAT会话穿越应用程序
  • TURN (Traversal Using Relays around NAT)
  • ICE (Interactive Connectivity Establishment): 互动式连接建立

目标

摄像头连接局域网,服务器拉取摄像头 RTSP 流,通过广域网推送到流媒体服务器,浏览器实时播放摄像头影像。如果网络环境运行,实现 P2P 的视频传输。基于JAVA进行消息交互。

主要流程

sequenceDiagram
A - 信令服务: connect
B - 信令服务: connect
A - A: 创建 Offer
A - stun/turn: bing request
A - 信令服务: 发送 SDP Offer
信令服务 - B: 发送 SDP Offer
B - B: 创建 Answer
B - stun/turn: bing request
B - 信令服务: 发送 SDP Answer
信令服务 - A: 发送 SDP Answer
stun/turn - A: OnICECandidate
A - 信令服务: 发送 candidate
信令服务 - B: 发送 candidate
stun/turn - B: OnICECandidate
B - 信令服务: 发送 candidate
信令服务 - A: 发送 candidate
A ->> B: 音视频传输

信令服务器 – RabbitMQ

可以手动写一个 socket 服务进行SDP等消息交互,由于前端可以直接连接 MQ 服务,这里就直接使用 MQ 服务进行消息交互,不再手写信令服务,感兴趣的人可以自行手写 java 版的信令服务项目。

消息传输使用 RabbitMQ 中的 topic 模式进行消息传输。主要的消息类型

  • start:开启视频流推送,传输 SDP (Answer/Offer)消息
  • iceCandidate:获取
  • heart:设备心跳消息
  • stop:停止视频流推送
  • reload:重载视频流
  • list:获取摄像头列表

一方手机到所有候选者后,通过信令传给对方;同样,另一方收到候选者后,也做收集工作;当双方拿到全部列表后,将候选者进行配对

Kurento

kurento 已经完成 STUN/TURN 协议的交互,无需自己进行协议解析。

// todo

Coturn 搭建

  • libevent 版本 2.1.12 (2021年2月14日)

  • coturn 版本 3.2.5.9 (2021年2月14日)

安装所需依赖

$ yum install gcc -y
$ yum install openssl openssl-libs libevent2 libevent-devel 
# 如果libevent2安装失败
$ wget https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz
$ tar xvfz libevent-2.1.12-stable.tar.gz
$ cd libevent-2.1.12-stable && ./configure make && make install && cd ..

安装 coturn

$ wget https://github.com/coturn/rfc5766-turn-server/archive/3.2.5.9.tar.gz
$ tar zxf 3.2.5.9.tar.gz
$ cd rfc5766-turn-server-3.2.5.9
$ ./configure && make && make install

配置

$ find / -name turnserver.conf
/usr/local/turnserver/etc/turnserver.conf
/usr/local/turnserver/share/examples/turnserver/etc/turnserver.conf
/root/coturn/turnserver-4.5.0.8/examples/etc/turnserver.conf
$ vim /usr/local/turnserver/etc/turnserver.conf
relay-device=eth0
listening-ip=172.17.0.13
listening-port=3478
tls-listening-port=5349
external-ip=121.*.*.153
relay-threads=50
lt-cred-mech
cert=/usr/local/turnserver/etc/webrtc.mufeng.info_chain.crt
pkey=/usr/local/turnserver/etc/webrtc.mufeng.info_key.key
pidfile="/var/run/turnserver.pid"
user=liurui:***
cli-password=qwerty
min-port=40000
max-port=60000
realm=webrtc.mufeng.info

部分参数说明

  • external-ip:外网ip

  • listening-ip:内网ip

测试工具

https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

image-20210214121228250

附页

NAT种类
  1. 全锥型(Full Cone)

  2. 受限锥型(Restricted Cone), 或者说是IP受限锥型

  3. 端口受限锥型(Port Restricted Cone), 或者说是IP + PORT受限锥型

  4. 对称型(Symmetric)

NAT 穿透原理

STUN 试探每种组合进行打洞

全锥形客户端2P2P
全锥形全锥形
全锥形对称型
全锥形受限制锥形
全锥形端口端口受限锥形
受限制锥形对称型
受限制锥形受限制锥形
受限制锥形端口端口受限锥形
端口端口受限锥形端口端口受限锥形
端口端口受限锥形对称型无法打通
对称型对称型无法打通
ICE

candidate 类型

  • 主机候选者(Host candidate):本机所有 IP 和指定端口
  • 反射候选者(Reflexive Candidate):STUN/TURN
  • 中继候选者(Relay Candidate):TURN
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Java实现WebRTC,你可以使用WebRTCJava库,例如jitsi/webrtc或者libjitsi。 以下是一个简单的示例代码,展示了如何在Java中使用WebRTC创建一个简单的视频通话应用程序: 1. 首先,你需要添加WebRTCJava库到你的项目中。你可以使用Maven或Gradle来管理依赖。例如,如果你使用Maven,可以在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.jitsi</groupId> <artifactId>libjitsi</artifactId> <version>1.0-20181030.161332-6</version> </dependency> ``` 2. 创建一个Java类,例如VideoCallApp,用于启动和管理视频通话。 ```java import org.jitsi.service.neomedia.*; import org.jitsi.service.neomedia.device.*; import org.jitsi.service.neomedia.format.*; import org.jitsi.service.neomedia.rtp.*; import org.jitsi.util.*; public class VideoCallApp { private static final String LOCAL_IP = "your_local_ip_address"; private static final int LOCAL_PORT = 5000; private static final String REMOTE_IP = "remote_ip_address"; private static final int REMOTE_PORT = 5000; public static void main(String[] args) throws Exception { System.setProperty(ConfigurationService.PNAME_PREFERRED_AUDIO_CODECS, "opus"); System.setProperty(ConfigurationService.PNAME_PREFERRED_VIDEO_CODECS, "VP8"); LibJitsi.start(); MediaService mediaService = LibJitsi.getMediaService(); MediaStreamFactory mediaStreamFactory = mediaService.getMediaStreamFactory(); MediaStream mediaStream = mediaStreamFactory.createMediaStream( new MediaDeviceImpl(LOCAL_IP, LOCAL_PORT), new MediaDeviceImpl(REMOTE_IP, REMOTE_PORT)); mediaStream.setDirection(MediaDirection.SENDRECV); mediaStream.start(); Thread.sleep(10000); mediaStream.stop(); LibJitsi.stop(); } } ``` 在上面的示例中,我们首先设置了一些常量,指定本地和远程IP地址以及端口号。然后,我们使用LibJits

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值