WebRTC系列文章:

本文聚焦于媒体服务器,汇总几个开源项目。

SRS

Simple Realtime Server缩写,官网,中文,国内最流行的开源(GitHub,28.5K Star,5.6K Fork)流媒体服务器项目,由腾讯云工程师winlin开发维护。国内开源流媒体领域的标杆项目,最初定位为简单高效的RTMP服务器,后来逐步扩展支持HTTP-FLV、HLS、WebRTC等多种协议。
img
目前最新稳定版6.0。

核心优势在于其卓越的性能和简洁的设计。采用单进程事件驱动架构,基于C++编写,能够处理高并发连接。支持RTMP推流和多种协议分发,单实例可支持数万并发连接。SRS的WebRTC延迟可控制在300毫秒以内,HTTP-FLV延迟在500毫秒左右。还提供丰富的集群功能,支持边缘推流、源站集群、负载均衡等部署模式。

原生支持WHIP协议推流和WHEP协议拉流,可作为SFU(Selective Forwarding Unit)实现多人通话。SRS的WebRTC实现针对低延迟进行优化,支持NACK(Negative Acknowledgment)丢包重传和TWCC(Transport Wide Congestion Control)拥塞控制。提供交互式直播功能,支持主播与观众之间的实时互动。

特性SRSZLMediakit
主要定位互联网直播、大规模集群、WebRTC深度集成安防监控、多协议全能转发、C++极致性能
优势场景互动直播、连麦、跨端极低延迟方案视频监控(国标GB28181)、多路转码分发
易用性文档非常详细(中文支持极好),社群活跃插件化程度高,作为一个C++库集成到项目中非常方便

ZLMediaKit

零声科技开源(GitHub,18.8K Star,4K Fork)基于C++11的高性能运营级流媒体服务框架,中文文档。

具有高性能、低延迟、多协议支持等特点,设计目标是为直播、监控、会议等场景提供一站式解决方案。

核心特性包括全面的协议支持和卓越的转码能力,支持RTMP推流、HLS分发、HTTP-FLV、RTSP、GB28181、SRT等多种协议,能够作为协议转换网关使用。内置FFmpeg支持,具备实时转码、转封装、录制等功能,可将不同协议的流进行相互转换。在延迟方面,WebRTC延迟可控制在500毫秒以内,最低可达100毫秒级别。

架构设计注重模块化和扩展性,采用插件化设计,可方便地集成新的协议支持。提供HTTP API和WebSocket接口,便于二次开发和系统集成。提供C++ SDK和Java SDK,降低在应用程序中集成流媒体功能的门槛。

实战

基于源码部署:

git clone https://github.com/ZLMediaKit/ZLMediaKit
cd ZLMediaKit
git submodule update --init
mkdir build
cd build
cmake ..
make -j4
# 启动
./MediaServer -d &

config.ini文件修改端口。

利用FFmpeg(或obs)进行推流测试:

ffmpeg -re -i "/path/to/test.mp4" -vcodec h264 -acodec aac -f flv rtmp://127.0.0.1/live/test

使用VLC进行播放rtmp://127.0.0.1/live/test,播放成功即为推流成功。

RTMP标准不支持H265,如果想让FFmpeg支持RTMP-H265,请按照此文章编译:https://github.com/ksvc/FFmpeg/wiki/hevcpush

Janus

即Janus Gateway,基于C语言的高性能开源(GitHub,8.9K Star,2.6K Fork)通用WebRTC网关服务器,专为实时通信应用而设计。最初由Meetecho公司开发,现已成为WebRTC生态系统中最流行和强大的媒体服务器之一。官方文档。

架构简洁灵活,支持多种部署模式。作为SFU,Janus可将一个发布者的媒体流转发给多个订阅者,支持多人视频会议场景。采用模块化架构,核心是轻量级服务器,负责处理WebRTC传输层,具体应用逻辑则通过插件系统来实现。

核心特性:通用网关设计,支持WebRTC、音频、视频、SCTP数据通道,支持多人视频会议和媒体路由,支持录制功能,将媒体流录制为文件,支持将RTSP、HTTP流转换为WebRTC,支持与传统VoIP系统集成,例如SIP网关。

核心特点是其模块化架构和插件系统,核心Janus进程只负责基本的WebRTC握手和转发,所有业务功能通过插件实现。这种设计使得Janus非常灵活,开发者可针对不同场景选择或开发相应的插件。官方插件包括视频房间(Video Room)、音频房间(Audio Room)、SIP网关、视频录制等。

Janus的部署相对复杂,需要手动编译安装,配置文件也较为繁琐。使用JSON格式的配置,需要对WebRTC有较深入的理解才能正确部署。Janus的性能表现稳定,支持大规模并发,但在低延迟优化方面不如LiveKit等新一代产品。Janus适合需要深度定制或有特殊功能需求的场景。

应用场景,参考官方demo

  1. 视频会议系统:可构建类似Zoom的多人视频会议应用,支持屏幕共享,聊天等功能;
  2. 直播流媒体:可将传统流媒体协议如RTMP、RTSP等转换为WebRTC,实现低延迟直播体验;
  3. IP摄像头监控:将网络摄像头的视频流通过WebRTC在浏览器中显示,实现实时监控系统;
  4. 在线教育平台:创建互动课堂,包含白板、文件共享等功能;
  5. 游戏串流:可将游戏画面通过WebRTC低延迟传输。

实战

基于源码安装

git clone https://github.com/meetecho/janus-gateway.git
cd janus-gateway
sh autogen.sh
./configure --prefix=/opt/janus
make
sudo make install
# 启动
/opt/janus/bin/janus
/opt/janus/bin/janus -c janus.jcfg # 指定配置文件

janus.jcfg示例:

{
	"general": {
		"configs_folder": "/opt/janus/etc/janus",
		"plugins_folder": "/opt/janus/lib/janus/plugins"
	},
	"nat": {
		"stun_server": "stun.l.google.com",
		"stun_port": 19302
	},
	"media": {
		"ipv6": false,
		"enable_media_delivery_stats": true
	},
	"plugins": {
		"janus.plugin.videocall": {
			"enabled": true,
			"admin_key": "mysecretkey"
		}
	},
	"transports": {
		"janus.transport.websockets": {
			"enabled": true,
			"ws": true,
			"ws_port": 8188
		}
	}
}

提供janus.js和adapter.js

https://webrtc.github.io/adapter/adapter-latest.js

<!DOCTYPE html>
<html>
<head>
	<title>Janus 视频聊天室</title>
	<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
	<script src="janus.js"></script>
</head>
<body>
	<div>
		<h2>本地视频</h2>
		<video id="local-video" autoplay muted playsinline></video>
	</div>
	<div>
		<h2>远程视频</h2>
		<video id="remote-video" autoplay playsinline></video>
	</div>
	<div>
		<button id="start-call">开始通话</button>
		<button id="end-call" disabled>结束通话</button>
	</div>
	<script>
	//Janus 服务器地址
	const server = "ws://localhost:8188/";
	// 初始化变量
	let janus = null;
	let videocall = null;
	let localStream = null;
	let remoteStream = null;
	// 初始化 Janus
	function initJanus() {
	    Janus.init({
	        debug: true,
	        callback: function() {
	            // 连接到 Janus 服务器
	            janus = new Janus({
	                server: server,
	                success: function() {
	                    console.log("连接到 Janus 服务器成功");
	                    attachVideoCallPlugin();
	                },
	                error: function(error) {
	                    console.error("连接失败:", error);
	                }
	            });
	        }
	    });
	}
	// 连接 VideoCall 插件
	function attachVideoCallPlugin() {
	    janus.attach({
	        plugin: "janus.plugin.videocall",
	        success: function(pluginHandle) {
	            videocall = pluginHandle;
	            console.log("VideoCall 插件连接成功");
	            // 监听来电
	            videocall.onmessage = function(msg, jsep) {
	                console.log("收到消息:", msg);
	                if (jsep) {
	                    // 处理 SDP 提议
	                    videocall.createAnswer({
	                        jsep: jsep,
	                        media: { audio: true, video: true },
	                        success: function(jsep) {
	                            videocall.send({ message: { accept: true } });
	                        }
	                    });
	                }
	            };
	            // 监听远程流
	            videocall.onremotestream = function(stream) {
	                console.log("收到远程流");
	                remoteStream = stream;
	                document.getElementById('remote-video').srcObject = stream;
	            };
	        },
	        error: function(error) {
	            console.error("插件连接失败:", error);
	        }
	    });
	}
	// 开始通话
	document.getElementById('start-call').onclick = function() {
	    if (!videocall) return;
	    // 获取本地媒体流
	    navigator.mediaDevices.getUserMedia({ 
	        audio: true, 
	        video: true 
	    }).then(function(stream) {
	        localStream = stream;
	        document.getElementById('local-video').srcObject = stream;
	        // 注册为可接听状态
	        videocall.send({ message: { request: "register", username: "user_" + Date.now() } });
	        document.getElementById('start-call').disabled = true;
	        document.getElementById('end-call').disabled = false;
	    }).catch(function(error) {
	        console.error("获取媒体设备失败:", error);
	    });
	};
	// 结束通话
	document.getElementById('end-call').onclick = function() {
	    if (localStream) {
	        localStream.getTracks().forEach(track => track.stop());
	    }
	    if (videocall) {
	        videocall.hangup();
	    }
	    document.getElementById('start-call').disabled = false;
	    document.getElementById('end-call').disabled = true;
	};
	// 页面加载时初始化
	window.onload = initJanus;
	</script>
</body>
</html>

MediaSoup

官网,面向WebRTC的开源(GitHub,7.3K Star,1.2K Fork)SFU/MCU媒体服务器,采用Node.js作为控制层,C++作为媒体处理层的设计。设计理念是提供高性能和高度可定制的WebRTC媒体处理能力,核心库可直接嵌入到Node.js应用。

架构分为三层:

  • 应用层使用JavaScript/TypeScript开发业务逻辑;
  • 核心层(mediasoup)处理WebRTC连接和媒体路由;
  • 工作者层(mediasoup-worker)使用C++实现高效的媒体转发。

这种分层设计兼顾开发效率和运行性能。

在SFU领域有着重要地位,被广泛应用于需要大规模视频会议或直播推流的场景。支持SVC(Scalable Video Coding)和Simulcast,可根据订阅者的带宽条件发送不同质量的视频流。还提供完整的Recorder插件,支持会议录制。文档完善,社区活跃,是构建自研视频会议系统的热门选择。

LiveKit

另起一篇,参考LiveKit简介、实战。

zlm4j

基于ZLMediaKit C语言API的开源(Gitee,692 Star,213 Fork)Java封装,几行代码搭建流媒体服务器。官方飞书文档。

Springboot秒集成-视频推拉流

功能

  • 流媒体服务:支持HTTP、RTSP、RTMP端口自定义,兼容ZLMediaKit配置
  • 推流:支持RTSP、RTMP、RTC、SRT、GB28181、WebRTC协议,支持推流鉴权
  • 拉流:支持RTSP、RTMP、FLV、HLS、FMP4等协议输出
  • 代理功能:支持拉流接入,具备鉴权、按需拉流、自动关流、流量统计
  • 录制功能:支持MP4、FLV、M3U8格式,支持MP4分片控制
  • 事件回调:支持流上下线、推拉流、录制完成、无人观看、RTSP鉴权等回调

FreeSWITCH

Logo

火山引擎视频云技术社区,是面向 AI 音视频开发者的技术交流平台。这里汇聚源自抖音、豆包等亿级 DAU 产品的 RTC、直播、点播、AI 媒体处理、音视频互动技术,提供接入指南、最佳实践、性能调优、场景案例、Demo 代码、开源项目、白皮书和 API 文档。社区汇聚官方工程师与一线开发者,为 AI 视频通话、数字人、AI 视频处理等应用的开发与落地提供技术支持。

更多推荐