SRS是一个开源的(MIT协议 )简单高效的实时视频服务器,支持RTMP、WebRTC、HLS、HTTP-FLV、SRT、MPEG-DASH和GB28181等协议。 SRS媒体服务器和FFmpeg 、OBS 、VLC 、 WebRTC 等客户端配合使用,提供流的接收和分发 的能力,是一个典型的发布 (推流)和订阅(播放)服务器模型。 SRS支持互联网广泛应用的音视频协议转换,比如可以将RTMP 或SRT , 转成HLS 或HTTP-FLV 或WebRTC 等协议。
k8s安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 相关设置: Container Image: ossrs/srs:5 Command/Args: 命令: ./objs/srs -c conf/flv/rtmp2rtc.conf Environments: CANDIDATE: iexxk.com TZ: Asia/Shanghai Container Ports(Host端口): 1935 默认推流端口,地面站那边修改不了,导致只能用host进行映射暴露 数据卷: 配置目录: /usr/local/srs/conf/flv 数据目录:/usr/local/srs/srs_dvr_data NodePort端口映射: 1935 8080 1985 30353
nginx代理
1 2 3 4 5 6 7 8 9 10 11 upstream ossrs_server { server ossrs:8080 ; } location /view-live/ { rewrite ^/view-live/(.*) /$1 break ; proxy_pass http://ossrs_server; proxy_set_header Host $host ; proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; }
流程
虚拟ip处需要映射
Web: 外网ip80/443绑定节点的ingress的80/443
Ossrs: 外网ip1935绑定k8s里面的ossrs服务的Container Ports(Host端口)1935或者nodeport,不采用nodeport是因为要内网外网都要能访问ossrs,关键是内网对外网域名做了隔离,因此这里用本机的hosts映射(可以升级到dns下发)
graph LR
G[OBS推流]-->C
C[域名] -->|解析| A[移动光猫]
A -->|LAN| B(飞塔防火墙)
B -->|虚拟ip| E[K8S的Ingress]
E -->|域名匹配| F[前端web/nginx]
F -->|nginx代理|U[ossrs]
C-->|hosts映射节点ip|E
V[VLC]-->|web flv拉流|U
K[IOS]-->|ios webrtc拉流|U
测试
安装obs,用srs在线的测试工具 也可以。
在来源->加号->浏览器->url
里面输入要直播的网址https://www.baidu.com/s?word=在线时间
在控制按钮->设置->直播->
服务:自定义
服务器:rtmp://iexxk.com/drone/
推码流:1
点击开始直播
播放:
内网测试(ok):
内网域名测试(ok):
外网测试:
webrtc和WHEP区别
WHEP:可以代理,但是也无法将一个域名根据环境解析为内网ip和外网ip,内网和外网是通过dns解析的,只能解析一个。在rtc里面启用保留域名,也无法解决,candidate
里面会出现2个域名一个ip,优先还是走的ip
1 2 3 4 5 6 7 8 rtc_server { enabled on; listen 30353; # UDP port # @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate candidate $CANDIDATE; # 启用保留域名 keep_api_domain on; }
webrtc:直接连接,延迟更低,必须开放1985,无法修改
使用webrtc时,需要在web前端(nginx)做个代理,并要将该端口映射到外网1985上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 upstream ossrs_webrtc { server ossrs:1985 ; } server { listen 1985 ssl; server_name iexxk.com; ssl_certificate /etc/nginx/cert/iexxk.com.pem; ssl_certificate_key /etc/nginx/cert/iexxk.com.key; location /rtc/v1/play/ { proxy_pass http://ossrs_webrtc; proxy_http_version 1 .1 ; proxy_set_header Upgrade $http_upgrade ; proxy_set_header Connection "upgrade" ; proxy_set_header Host $host ; proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $scheme ; } }
常见问题
在内网无法访问外网域名的时候,虽然通过host映射到内网,但是webrtc播放的时候还是解析成了外网ip
使用webrtc播放时可以在浏览器控制台能看到如下信息
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 33 34 35 36 37 38 39 40 41 42 43 44 Got answer: v=0 o =SRS/5.0.213(Bee) 140129754604224 2 IN IP4 0.0.0.0 s =SRSPlaySession t =0 0 a =ice-lite a =group:BUNDLE 0 1 a =msid-semantic: WMS drone/1 m =audio 9 UDP/TLS/RTP/SAVPF 111 c =IN IP4 0.0.0.0 a =ice-ufrag:881501t3 a =ice-pwd:d11em20o3z9k02c97228yq5937ptj776 a =fingerprint:sha-256 35:65:58:9A:E6:78:8F:D5:E6:F1:8F:E5:74:AD:A4:1E:3A:DF:B4:CE:21:3C:C9:CB:4A:9D:25:7A:87:53:FB:47 a =setup:passive a =mid:0 a =extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 a =sendonly a =rtcp-mux a =rtcp-rsize a =rtpmap:111 opus/48000/2 a =rtcp-fb:111 transport-cc a =ssrc:10186 cname:2yaj11875760968e a =ssrc:10186 label:audio-803h25y4 a =candidate:0 1 udp 2130706431 172.16.10.44 30353 typ host generation 0 a =candidate:1 1 udp 2130706431 iexxk.com 30353 typ host generation 0 m =video 9 UDP/TLS/RTP/SAVPF 106 c =IN IP4 0.0.0.0 a =ice-ufrag:881501t3 a =ice-pwd:d11em20o3z9k02c97228yq5937ptj776 a =fingerprint:sha-256 35:65:58:9A:E6:78:8F:D5:E6:F1:8F:E5:74:AD:A4:1E:3A:DF:B4:CE:21:3C:C9:CB:4A:9D:25:7A:87:53:FB:47 a =setup:passive a =mid:1 a =extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 a =sendonly a =rtcp-mux a =rtcp-rsize a =rtpmap:106 H264/90000 a =rtcp-fb:106 transport-cc a =rtcp-fb:106 nack a =rtcp-fb:106 nack pli a =fmtp:106 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f a =ssrc:10187 cname:2yaj11875760968e a =ssrc:10187 label:video-29515r30 a =candidate:0 1 udp 2130706431 172.16.10.44 30353 typ host generation 0 a =candidate:1 1 udp 2130706431 iexxk.com 30353 typ host generation 0
注意最后两行
1 2 3 4 5 6 7 8 9 使用内网ip的时候,输出如下信息 a =candidate:0 1 udp 2130706431 172.16.10.102 30353 typ host generation 0 a =candidate:1 1 udp 2130706431 iexxk.com 30353 typ host generation 0 使用内网域名的时候,输出如下信息,内网做了dns解析,假域名能解析到内网主机 a =candidate:0 1 udp 2130706431 172.16.10.44 30353 typ host generation 0 a =candidate:1 1 udp 2130706431 iexxk.com 30353 typ host generation 0 使用外网域名的时候,输出如下信息,17.176.159.182这个域名刚好在内网无法访问,因此内网无法播放外网地址 a =candidate:0 1 udp 2130706431 17.176.159.182 30353 typ host generation 0 a =candidate:1 1 udp 2130706431 exxk.com 30353 typ host generation 0
真域名做了host映射,但是似乎不会从host拿,应该是从dns里面拿取了
从下图可以知道,是通过1985的接口,拿到了udp的端口数据。
配置 rtmp2rtc.conf
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 listen 1935 ;max_connections 1000 ;daemon off ;srs_log_tank console;http_server { enabled on ; listen 8080 ; dir ./objs/nginx/html; } http_api { enabled on ; listen 1985 ; } stats { network 0 ; } rtc_server { enabled on ; listen 30353 ; candidate $CANDIDATE ; } vhost __defaultVhost__ { rtc { enabled on ; rtmp_to_rtc on ; rtc_to_rtmp on ; } http_remux { enabled on ; mount [vhost]/[app]/[stream].flv; } hls { enabled on ; hls_path ./objs/nginx/html; hls_fragment 10 ; hls_window 20 ; hls_wait_keyframe off ; } tcp_nodelay on min_latency on ; play { gop_cache off ; queue_length 10 ; mw_latency 100 ; } publish { mr off ; } dvr { enabled on ; dvr_apply all; dvr_plan session; dvr_path ./srs_dvr_data/[app]/[stream]/[2006 ]-[01 ]-[02 ]/[timestamp].[2006 ]-[01 ]-[02 ]_[15 ].[04 ].[05 ]_[999 ].mp4; dvr_duration 30 ; dvr_wait_keyframe on ; time_jitter full; } }
realtime.flv.conf
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 33 34 35 36 37 38 39 40 41 42 43 44 45 listen 1935 ;max_connections 1000 ;daemon off ;srs_log_tank console;http_server { enabled on ; listen 18080 ; dir ./objs/nginx/html; } vhost __defaultVhost__ { http_remux { enabled on ; mount [vhost]/[app]/[stream].flv; } hls { enabled on ; hls_path ./objs/nginx/html; hls_fragment 10 ; hls_window 20 ; hls_wait_keyframe off ; } tcp_nodelay on min_latency on ; play { gop_cache off ; queue_length 10 ; mw_latency 100 ; } publish { mr off ; } dvr { enabled on ; dvr_apply all; dvr_plan session; dvr_path ./srs_dvr_data/[app]/[stream]/[2006 ]-[01 ]-[02 ]/[timestamp].[2006 ]-[01 ]-[02 ]_[15 ].[04 ].[05 ]_[999 ].mp4; dvr_duration 30 ; dvr_wait_keyframe on ; time_jitter full; } }