Giter VIP home page Giter VIP logo

q191201771 / lal Goto Github PK

View Code? Open in Web Editor NEW
2.6K 62.0 443.0 8.39 MB

🔥 Golang audio/video live streaming lib/client/server. support RTMP, RTSP(RTP/RTCP), HLS, HTTP[S]/WebSocket-FLV/TS, GB28181, H264/H265/AAC/G711/OPUS, relay, cluster, record, HTTP Notify/API/UI. 直播

Home Page: https://pengrl.com/lal

License: MIT License

Go 96.75% Shell 1.23% Makefile 0.06% Dockerfile 0.06% HTML 1.90%
rtmp aac h265-hevc h264-avc hls m3u8 rtsp rtp rtcp http-ts

lal's People

Contributors

abrar71 avatar asdfsx avatar benlocal avatar bigbao9494 avatar chekun avatar chenquan avatar cutelittledevil avatar evrins avatar fallowu avatar hustcoderhu avatar ixugo avatar jaesung9507 avatar jaysooong avatar joestarzxh avatar kookouse avatar koulerz avatar kuabhish avatar lih0820 avatar lio19 avatar q191201771 avatar robin-hzc avatar srcenchen avatar suizg avatar testwill avatar thewind296 avatar worldflyingct avatar wu-wenxiang avatar xianghan228 avatar zloydyadka avatar zsc714725 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lal's Issues

Standalone RTMP server

Hi,
I am looking for a solid RTMP server library. So far I have used https://github.com/nareix/joy4 but that one is unsupported for quite some time and so I am looking for some up-to-date highly optimized alternative. And I found your project and https://github.com/gwuhaolin/livego and so I wonder how does your RTMP implementation compare with livego's and if there is a chance you can refactor RTMP part of this project into standalone library? I read some issues with livego's performance so I wonder how your verison compares.

WebSocket-FLV, WebSocket-TS

目前已经有开源贡献者提交了WebSocket-FLV, WebSocket-TS的实现(包含简单的服务端握手部分,发送打包部分),并且已合并入master分支。

后续:

  1. pr中的大小写风格统一
  2. http和websocket发送http response header和handshake结果统一至发送函数中
  3. 学习websocket,将websocket部分重构至naza库中

nginx 代理 flv 流 电脑外网访问 502 错误

nginx.conf

location /live/ {
    proxy_pass http://127.0.0.1:19302/live/;
}

lal.conf

"httpflv": {
  "enable": true,
  "sub_listen_addr": ":19302",
  "enable_https": false,
  "https_addr": ":4433",
  "https_cert_file": "./conf/cert.pem",
  "https_key_file": "./conf/key.pem",
  "gop_num": 2
},

访问地址

正常
http://127.0.0.1/live/20210323-1-151124.flv

502 仅存在于浏览器中
http://192.168.1.6/live/20210323-1-151124.flv

可是如果是手机端访问 都是正常的

错误日志

2021/03/23 15:48:04 [error] 183771#0: *15926 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 192.168.1.7, server: _, request: "GET /live/20210323-1-151124.flv HTTP/1.1", upstream: "http://127.0.0.1:19302/live/20210323-1-151124.flv", host: "192.168.1.7"
nginx version: nginx/1.18.0
lal version; v0.19.1
Google Chrome: 91.0.4449.6
firefox: 86.0.1

性能测试

lalserver和常见的流媒体服务器做性能对比测试,包含:

  • rtmp n推
  • rtmp 1推n拉
  • rtmp n个1推1拉
  • rtmp n个瞬发建立
  • rtmp 延时
  • rtmp 秒开

能否增加动态拉取H264/H265 RTSP流!

能否增加在访问httpflv流时, 当对应流不存在时能动态去拉取H264/H265 RTSP流! 拉取成功后让刚刚请求的httpflv流能播放;
然后增加hook接口: OnStreamNotFound --当请求httpflv流不存在时触发, 然后让客户去拉流; OnPlay--给客户机会检查token; OnStreamNoneReader--当没有读者时,给客户自己决定是否关闭刚刚拉取的RTSP流. 多谢!

Undefined syscalls

go get github.com/q191201771/lal/...
# github.com/q191201771/lal/pkg/innertest
..\..\..\github.com\q191201771\lal\pkg\innertest\innertest.go:161:6: undefined: syscall.Kill
..\..\..\github.com\q191201771\lal\pkg\innertest\innertest.go:161:37: undefined: syscall.SIGUSR1

go version go1.15 windows/amd64

向lalserver推送rtsp h265流时报错

推流方式: ffmpeg -re -i wontcry.flv -c:a copy -c:v hevc -f rtsp rtsp://localhost:5544/live/test110

报错信息:
lalserver持续输出以下错误日志:
ERROR unknown nalu type. outerNALUType=0
ERROR invalid position. pos=0

现象描述:
只能通过rtsp从lalserver拉流,rtmp拉流失败

期望老板 rtsp的支持

rtsp进入lal;
从lal拉rtsp的流出来 ;

以及rtsp的流进来,rtmp的流出来(包括flv,hls);
and 从lal拉rtsp/rtmp/flv/hls; 无论 是从哪个协议过来的;

期望的结果是rtsp得到很好的支持.

谢谢老板 .

期望老板提供一些对外接口

接口清单 :

  1. cpu利用率
    2.内存利用率
    3.网络实时状态:进+出实时带宽 ,以字节为单位
    4.连接情况: flv,rtmp,hls,及其他格式的识别

5.流列表信息:

ID,	Appname,Streamname,IP:port,Audio(Codec,freq,channel) Video(codec,size,fps), StartTime(上线时间),PreStartTime(上次上线时间),Clients(正在读流的客户端个数),Op(禁止流,启用流)

6.系统信息
OS版本
体系框架(计算机的)
内存配置
cpu配置
系统开机时间、服务开启时间

config文件:
用户名,密码

RTSP疑问

func (s *UDPServer) RunLoop() error {
	for {
		b := make([]byte, udpMaxPacketLength)
		l, a, e := s.conn.ReadFromUDP(b)
		if e != nil && (l < 0 || l > udpMaxPacketLength) {
			nazalog.Errorf("ReadFromUDP length invalid. length=%d", l)
		}
		s.onReadUDPPacket(b[:l], a.String(), e)
	}
}
func (p *PubSession) onReadUDPPacket函数中固定偏移判断数据内容。
每次固定读取1500字节,如果发端每次发送数据小于MTU大小,比如每个包700如果出现包粘连,是否能正确处理?
如果发端就是小于1500字节RTP包,如果IP层丢失部分IP分片是否会导致后面数据全部错乱?

期望老板能提供一个flv的播放器

现在播放flv使用flvjs的各种魔改的版本,都存在共同的问题;
比如 断流播放; 追帧算法; ios下面的播放等;

期望老板能考虑下,使用wasm的方式提供 播放器,来解决从lal出来的流的播放的需求 ;

这方面主要应用在:

  1. web上面 ;
  2. 微信上面;
  3. H5的app上面;

期望老板提供webrtc的支持

这包括三个方面的webrtc支持;

  1. 使用webrtc推流到lal
  2. 从lal出来webrtc的视频流,使用video进行播放;
  3. 从其他webrtc的流拉回来播放;

这里面会使用stun/turn的协议,建议老板直接使用第三方的,有go的,也有c/C++的。 不建议老板自己实现这块。

RTSP 1080视频花屏

测试环境

  • 测试版本:lal_v0.19.1_linux,默认配置

出现问题

  • RTSP over udp 推流1080p视频:
    ffmpeg -re -stream_loop -1 -i "bbb_sunflower_1080p_30fps_normal.mp4" -an -vcodec copy -f rtsp rtsp://localhost:5544/live/test110
  • ffplay播放rtsp,看几秒钟后兔子出洞后花屏,每次重新播放花屏的时间和位置都一样。
  • 转rtmp播放或者改为rtsp over tcp推流均没有问题
  • RTSP over udp 推流小码流文件(source.200kbps.768x320.flv)没有这个问题

测试资源

  • bbb_sunflower_1080p_30fps_normal.mp4 国外
  • bbb_sunflower_1080p_30fps_normal.mp4 国内

HTTP_TS模块开发思路

httpTS模块开发:
1、和httpflv模块使用方法相同,客户端下载TS封装数据。
2、设计基本可以参考httpflv模块,创建一个新的httpts的package
类似flv模块,在Group struct中添加一个成员变量httptsSubSessionSet map[*httpts.SubSession]struct{}来保存所有的httpts客户端信息。
3、httpflv是直接在func (group *Group) broadcastRTMP函数中就完成数据转发,broadcastRTMP是Group的成员函数可以直接访问httpflvSubSessionSet。
httptsSubSessionSet需要在func (f *FragmentOP) writeFile函数中去遍历来完成转发,
这就需要在AddRTMPPullSession中创建NewMuxer时把httptsSubSessionSet的引用传递进去
最终还要在FragmentOP中引用,因为最终的TS数据转发会在func (f *FragmentOP) writeFile函数中实现

如何在提供rtmp server服务的同时将接收到的流push到其他rtmp或者rtsp

通过阅读源码,原本以为可以在实现ServerObserver接口的OnNewRTMPPubSession 方法,然后实现流的读取和push,但是发现并没有暴露io读取或者获取流的方法,所以没有希望能提供相应的方法。这个场景主要是用于多平台推流,比如:本地启动一个lalserver用于rtmp serer端,用obs推流到lalserver,然后lalserver同步到抖音、斗鱼、视频号等其他平台,因为目前obs只能支持一个流推送,所以希望lalserver启动的时候也能同步推流到其他平台的rtmp地址。

期望老板增加推拉流的密钥功能

目前直接推拉,都没有验证,也没有密钥。这知道地址的人,都可以推或者拉。
期望老板增加密钥的功能;

密钥的功能有这样几个坑:

  1. 如果密钥是配置在服务器端,所有的人使用同样的加密算法,会导致一旦泄露,整个服务器涉及的都需要修改这个密码。 那影响范围相当大。
  2. 如果密钥是配置在客户端,则同样出现上面的问题。 客户端通过url来配置访问密钥,这很容易被不同的用户猜到。

研究了sas以及其他的密钥处理,期望老板考虑这样做密钥:

  1. 服务端可以配置多个密钥。 这样每个密钥可以用在不同的场合;这个并不难实现,解密的时候根据密钥头或者请求参数,appname等方式来判断使用哪个密钥;
  2. 客户端的播放地址,通过不同的密钥进行播放解密。

这样就可以解决密钥的安全性问题。

上面描述太操蛋了,估计老板理解有问题。

看老板的产品设计吧。

读取rtsp转发到rtstp服务器

最近项目需要将摄像头的rtsp图像读取出来转发至云端rtsp服务器。希望您可以添加这部分功能谢谢!

rtmp拉流问题(部分rtmp出错)

在拉流 rtmp://218.3.205.46/live/xwzh_sd 时候显示错误:

PS D:\Work\fork\lal> go run .\app\demo\pullrtmp\pullrtmp.go -i rtmp://218.3.205.46/live/xwzh_sd -o jnxw_sd.flv
2020/12/25 19:47:30.077850 INFO [RTMPPULL1] lifecycle new rtmp ClientSession. session=0xc000146000 - client_session.go:102
2020/12/25 19:47:30.082881 INFO [RTMPPULL1] > W Handshake C0+C1. - client_session.go:271
2020/12/25 19:47:36.124649 DEBUG naza connection close. err=EOF, conn=0xc00018a000 - connection.go:405
2020/12/25 19:47:36.131628 ERROR assert failed. excepted=, but actual=lal.rtmp: client session timeout - pullrtmp.go:91
2020/12/25 19:47:36.132639 DEBUG EOF - pullrtmp.go:93

RTSP-H265拉流问题

使用pullrtsp.go与pullrtsp2pushrtmp.go两个demo进行测试

1.大华网络摄像头 H265的rtsp流拉流错误

日志:

2020/12/21 11:35:00.029883  INFO [RTSPPULL1] lifecycle new rtsp PullSession. session=0xc00014e000 - client_pull_session.go:80
2020/12/21 11:35:00.029883 DEBUG [RTSPPULL1] > tcp connect. - client_pull_session.go:182
2020/12/21 11:35:00.033872 DEBUG [RTSPPULL1] > write options. - client_pull_session.go:199
2020/12/21 11:35:00.040853 DEBUG [RTSPPULL1] < read response. 200 - client_pull_session.go:207
2020/12/21 11:35:00.040853 DEBUG [RTSPPULL1] > write describe. - client_pull_session.go:214
2020/12/21 11:35:00.085734 DEBUG [RTSPPULL1] < read response. code=200, body=v=0
o=- 2252316233 2252316233 IN IP4 0.0.0.0
s=Media Server
c=IN IP4 0.0.0.0
t=0 0
a=control:*
a=packetization-supported:DH
a=rtppayload-supported:DH
a=range:npt=now-
m=video 0 RTP/AVP 98
a=control:trackID=0
a=framerate:25.000000
a=rtpmap:98 H265/90000
a=fmtp:98 profile-id=1;sprop-sps=QgEBAWAAAAMAsAAAAwAAAwBaoAWCAJBY2uSTL5A=;sprop-pps=RAHA8vA8kA==;sprop-vps=QAEMAf//AWAAAAMAsAAAAwAAAwBarAk=
a=recvonly
 - client_pull_session.go:222
2020/12/21 11:35:00.085734 ERROR lal.sdp: fxxk - pullrtsp.go:64

原因初步定位

image

2.简单修改第一个问题后,尝试拉流,继续出现异常

日志

2020/12/21 11:33:43.594242  INFO [RTSPPULL1] lifecycle new rtsp PullSession. session=0xc00014e000 - client_pull_session.go:80
2020/12/21 11:33:43.595239 DEBUG [RTSPPULL1] > tcp connect. - client_pull_session.go:182
2020/12/21 11:33:43.600226 DEBUG [RTSPPULL1] > write options. - client_pull_session.go:199
2020/12/21 11:33:43.630146 DEBUG [RTSPPULL1] < read response. 200 - client_pull_session.go:207
2020/12/21 11:33:43.630146 DEBUG [RTSPPULL1] > write describe. - client_pull_session.go:214
2020/12/21 11:33:43.721901 DEBUG [RTSPPULL1] < read response. code=200, body=v=0
o=- 2252316157 2252316157 IN IP4 0.0.0.0
s=Media Server
c=IN IP4 0.0.0.0
t=0 0
a=control:*
a=packetization-supported:DH
a=rtppayload-supported:DH
a=range:npt=now-
m=video 0 RTP/AVP 98
a=control:trackID=0
a=framerate:25.000000
a=rtpmap:98 H265/90000
a=fmtp:98 profile-id=1;sprop-sps=QgEBAWAAAAMAsAAAAwAAAwBaoAWCAJBY2uSTL5A=;sprop-pps=RAHA8vA8kA==;sprop-vps=QAEMAf//AWAAAAMAsAAAAwAAAwBarAk=
a=recvonly
 - client_pull_session.go:222
2020/12/21 11:33:43.722898 DEBUG [RTSPPULL1] > write setup. - client_pull_session.go:257
2020/12/21 11:33:43.756807 DEBUG [RTSPPULL1] < read response. code=200, ctx={Version:RTSP/1.0 StatusCode:200 Reason:OK Headers:map[CSeq:3 Session:377976728209;timeout=60 Transport:RTP/AVP/UDP;unicast;client_port=8000-8001;server_port=33634-33635;ssrc=42D34B52 x-Dynamic-Rate:1] Body:[]} - client_pull_session.go:265
2020/12/21 11:33:43.756807 DEBUG [RTSPPULL1] > write play. - client_pull_session.go:302
2020/12/21 11:33:43.804679 DEBUG [RTSPPULL1] < read response. 200 - client_pull_session.go:310
2020/12/21 11:33:43.881474 ERROR unknown nalu type. outerNALUType=32 - rtp_unpacker_hevc.go:76
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR unknown nalu type. outerNALUType=33 - rtp_unpacker_hevc.go:76
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR unknown nalu type. outerNALUType=34 - rtp_unpacker_hevc.go:76
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR unknown nalu type. outerNALUType=39 - rtp_unpacker_hevc.go:76
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.881474 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.883469 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246
2020/12/21 11:33:43.883469 ERROR invalid position. pos=0 - rtp_unpacker_avc.go:246

3.尝试H264的rtsp流,pullRtsp的demo未成功,flv文件为空

####日志:

2020/12/21 11:35:57.517690 DEBUG [RTSPPULL1] > write setup. - client_pull_session.go:257
2020/12/21 11:35:57.549604 DEBUG [RTSPPULL1] < read response. code=200, ctx={Version:RTSP/1.0 StatusCode:200 Reason:OK Headers:map[CSeq:3 Session:378110526422;timeout=60 Transport:RTP/AVP/UDP;unicast;client_port=8000-8001;server_port=23722-23723;ssrc=0B15E296 x-Dynamic-Rate:1] Body:[]} - client_pull_session.go:265
2020/12/21 11:35:57.549604 DEBUG [RTSPPULL1] > write setup. - client_pull_session.go:257
2020/12/21 11:35:57.557583 DEBUG [RTSPPULL1] < read response. code=200, ctx={Version:RTSP/1.0 StatusCode:200 Reason:OK Headers:map[CSeq:4 Session:378110526422;timeout=60 Transport:RTP/AVP/UDP;unicast;client_port=8002-8003;server_port=0-0;ssrc=0B15E296 x-Dynamic-Rate:1] Body:[]} - client_pull_session.go:265
2020/12/21 11:35:57.557583 DEBUG [RTSPPULL1] > write play. - client_pull_session.go:302
2020/12/21 11:35:57.590494 DEBUG [RTSPPULL1] < read response. 200 - client_pull_session.go:310
2020/12/21 11:36:02.435543  WARN video queue full, drop front packet. - avpacket_queue.go:59
2020/12/21 11:36:02.468453  WARN video queue full, drop front packet. - avpacket_queue.go:59
2020/12/21 11:36:02.509344  WARN video queue full, drop front packet. - avpacket_queue.go:59
2020/12/21 11:36:02.547243  WARN video queue full, drop front packet. - avpacket_queue.go:59

生成的文件只有flv的头信息,1kb

image

4.rtsp没有做保活,即每分钟发送rtsp保活请求,导致网络摄像头的rtsp自动断开

5.rtsp的setup请求异常

日志

2020/12/21 11:41:46.685167  INFO [RTSPPULL1] lifecycle new rtsp PullSession. session=0xc00014e000 - client_pull_session.go:80
2020/12/21 11:41:46.685167 DEBUG [RTSPPULL1] > tcp connect. - client_pull_session.go:182
2020/12/21 11:41:46.689156 DEBUG [RTSPPULL1] > write options. - client_pull_session.go:199
2020/12/21 11:41:46.702122 DEBUG [RTSPPULL1] < read response. 200 - client_pull_session.go:207
2020/12/21 11:41:46.702122 DEBUG [RTSPPULL1] > write describe. - client_pull_session.go:214
2020/12/21 11:41:46.745007 DEBUG [RTSPPULL1] < read response. code=200, body=v=0
o=- 2252310609 2252310609 IN IP4 0.0.0.0
s=Media Server
c=IN IP4 0.0.0.0
t=0 0
a=control:*
a=packetization-supported:DH
a=rtppayload-supported:DH
a=range:npt=now-
m=video 0 RTP/AVP 96
a=control:trackID=0
a=framerate:25.000000
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=4D002A;sprop-parameter-sets=Z00AKp2oHgCJ+WbgICAoAAAfQAAGGoQgAA==,aO48gAA=
a=recvonly
m=audio 0 RTP/AVP 97
a=control:trackID=1
a=rtpmap:97 MPEG4-GENERIC/48000
a=fmtp:97 streamtype=5;profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1188
a=recvonly
 - client_pull_session.go:222
2020/12/21 11:41:46.746005 DEBUG [RTSPPULL1] > write setup. - client_pull_session.go:257
2020/12/21 11:41:46.752986 DEBUG [RTSPPULL1] < read response. code=451, ctx={Version:RTSP/1.0 StatusCode:451 Reason:Parameter Not Understood Headers:map[CSeq:3 Session:378459737223] Body:[]} - client_pull_session.go:265
2020/12/21 11:41:46.752986 ERROR lal.rtsp: fxxk - pullrtsp.go:64

Debugger finished with exit code 0

经vlc抓包对比分析,定位问题如下

image

与vlc对比临时修正测试成功

image

附VLC播放抓包明细

image

OPTIONS rtsp://192.168.7.85:554/cam/realmonitor?channel=1&subtype=1 RTSP/1.0
CSeq: 2
User-Agent: LibVLC/3.0.11 (LIVE555 Streaming Media v2016.11.28)

RTSP/1.0 200 OK
CSeq: 2
Server: Rtsp Server/3.0
Public: OPTIONS, DESCRIBE, ANNOUNCE, SETUP, PLAY, RECORD, PAUSE, TEARDOWN, SET_PARAMETER, GET_PARAMETER

--------------------------------------

DESCRIBE rtsp://192.168.7.85:554/cam/realmonitor?channel=1&subtype=1 RTSP/1.0
CSeq: 3
User-Agent: LibVLC/3.0.11 (LIVE555 Streaming Media v2016.11.28)
Accept: application/sdp

RTSP/1.0 200 OK
CSeq: 3
x-Accept-Dynamic-Rate: 1
Content-Base: rtsp://192.168.7.85:554/cam/realmonitor?channel=1&subtype=1/
Cache-Control: must-revalidate
Content-Length: 419
Content-Type: application/sdp

v=0
o=- 2252316863 2252316863 IN IP4 0.0.0.0
s=Media Server
c=IN IP4 0.0.0.0
t=0 0
a=control:*
a=packetization-supported:DH
a=rtppayload-supported:DH
a=range:npt=now-
m=video 0 RTP/AVP 98
a=control:trackID=0
a=framerate:25.000000
a=rtpmap:98 H265/90000
a=fmtp:98 profile-id=1;sprop-sps=QgEBAWAAAAMAsAAAAwAAAwBaoAWCAJBY2uSTL5A=;sprop-pps=RAHA8vA8kA==;sprop-vps=QAEMAf//AWAAAAMAsAAAAwAAAwBarAk=
a=recvonly

--------------------------------------

SETUP rtsp://192.168.7.85:554/cam/realmonitor?channel=1&subtype=1/trackID=0 RTSP/1.0
CSeq: 4
User-Agent: LibVLC/3.0.11 (LIVE555 Streaming Media v2016.11.28)
Transport: RTP/AVP;unicast;client_port=54934-54935

RTSP/1.0 200 OK
CSeq: 4
Session: 378682809165;timeout=60
Transport: RTP/AVP/UDP;unicast;client_port=54934-54935;server_port=26884-26885;ssrc=331AFDA4
x-Dynamic-Rate: 1

--------------------------------------

PLAY rtsp://192.168.7.85:554/cam/realmonitor?channel=1&subtype=1/ RTSP/1.0
CSeq: 5
User-Agent: LibVLC/3.0.11 (LIVE555 Streaming Media v2016.11.28)
Session: 378682809165
Range: npt=0.000-

RTSP/1.0 200 OK
CSeq: 5
Session: 378682809165
Range: npt=0.000000-
RTP-Info: url=trackID=0;seq=64932;rtptime=64932

--------------------------------------

GET_PARAMETER rtsp://192.168.7.85:554/cam/realmonitor?channel=1&subtype=1/ RTSP/1.0
CSeq: 6
User-Agent: LibVLC/3.0.11 (LIVE555 Streaming Media v2016.11.28)
Session: 378682809165

RTSP/1.0 200 OK
CSeq: 6
Session: 378682809165

期望老板考虑对CDN的支持和验证

我验证过使用阿里云的CDN, 播放FLV的时候,似乎并没有效果。
比如:
https://www.abc.com/abc.flv这个地址是原地址;
使用ali cdn处理好, 访问 https://www.abc.com/abc.flv 会到阿里云的CDN上面。
但是操蛋的事情是:
https://www.abc.com/abc.flv 这个地址从CDN有多少路访问,CDN的服务器,就有多少路到源站服务器。造成CDN虽然用了,但是并没有产生效果。没起到CDN的效果;
效率过alicdn的客服,得到的答复是: flv文件的过期时间太短, 所以一有请求,就直接回源了。
后来我尝试把flv的播放时延增加到30秒, 倒是起了一点效果。 这时请求的cdn流量不会全部转发到源站了。

但是新的问题出来了 :
flvplayer做了追帧算法,如果有缓存,会通过倍速的方式吃掉缓存,这又造成了虽然缓存了30秒,但是这30秒马上被追帧算法给吃掉了。

所以老板你要考虑CDN的话,还要考虑播放器。 这是一个大头的现实情况 。

【开脑洞】用go直接编写移动端的推拉流库

gomobile可将go程序编译成Android和iOS库,gomobile安装和使用比较容易,具体可参考。
https://github.com/golang/go/wiki/Mobile#building-and-deploying-to-android-1
这样就可以在服务端和客户端共用一些相同功能性的代码,比如rtmp等数据流的解析,传输处理。这样整体项目的整体性更好。也将go语言的便捷性使用扩大,替代C/C++编写移动底层库,降低编译和使用难度。

这边推荐一个im类型项目,它的Android客户端就是这么干的,gomobile编译出.aar给Android使用,可供参考。
https://github.com/dearcode/candy

当然这只是个建议,还不知道是否真的可行,大神有兴趣可以尝试尝试!

rtmp花屏

push with rtsp, and pull use rtmp , 花屏,感觉新来的rtmp流第一帧不是关键帧

需求池


  • pcmu #165
    • 整理支持情况的文档
  • gb28181 ps 打包
  • rtp
  • rtsp
    • rtsp客户端解析url可能存在bug的case #101
  • rtmp
  • httpflv
    • HTTP-FLV流不存在返回404并关闭 #212
  • hls
    • AES-128加密 #158
    • HTTP[S]/WebSocket[s]-fMP4 #124
    • fmp4, LL-HLS #159
    • 类似ffmpeg中append_list参数 #127
    • #EXT-X-DISCONTINUITY #133
  • mp3,mp4 #131
  • SRT #36 【协助社区合并到lalext中】
  • web可视化
  • HTTP-API And HTTP-Notify
  • config
    • gop缓存全局配置项,以及各协议配置项,以及单条流可独立控制 #125
  • demo
    • pullrtmp2pushrtmp 支持一个push断开时,只是自己重连,不断开其他push #155
    • h264 -> push to rtmp #240
  • 傻瓜式一键集群化
    • Kubernetes cluster #195
  • 未知

# 协议相关

QUIC #81
A. 等待排期

KCP #80
A: 等待排期

rtmfp #24
A: 不熟悉,需求场景太少,目前不会做

rtmps?
A: client端已支持,server端没见过这种需求场景,暂时不做

nack #10
A. 等待排期

rtsp udp端口复用 #69

测试并完善各传输协议对只有音频或只有视频的支持 #56
A: 通过社区反馈支持情况来完善。

所有http协议支持https #76
A: 剩下几个不紧急的

所有out发送协议支持合并发送 #84

# relay

Q. 1 rtmp pub to multi rtmp push(接收1路rtmp,转推多路rtmp的转推工具) #52
A. 等待排期

# API

Q. HTTP API接口获取宿主机的硬件、软件信息以及实时使用率情况 #15
A. 目前只提供流相关的信息,其他外围信息建议使用其他做方式获取

Q. 建议…可以做一个web后台监管系统 #26

  1. 分布式集群管理,一键添加或删除流服务器节点
  2. 实时监控播放正在推流内容,类似于监控室画面
  3. 根据时间段,播放量等可过滤直播回放视频列表
    A. 1由业务模块实现管理。2由业务方实现监控播放。3目前只提供直播和录制,不提供点播。

# 鉴权

Q. 通过HTTP Notify做同步鉴权 #31
A. 目前已支持1. HTTP Notify+HTTP API做异步鉴权,2. simple auth配置鉴权。所以这个优先级比较低。

# 录制

Q. MP4存储 #14 #108
A. 有空会做

# 涉及编解码

Q. 截图 #14
A. 涉及到编解码,不会放入lalserver主体中

# 播放器

Q. web播放器 #19 #22
A. 不熟悉

# 其他

Q. 支持移动端编译 #34
A. 不熟悉

# Fix

Q. 花屏 #38
A. 保证所有情况的每个GOP都从I帧开始发送(即使是推流端推送的数据有问题),该功能需要可配置

# 长期任务

测试覆盖率 #57

# 整理timeout label的issue

RTSP转RTMP压测崩溃

测试环境

  • 系统: ubuntu 20.04
  • 内存:16G
  • CPU: 4.01 GHz 四核Intel Core i7
  • 网络: 127.0.0.1本地循环网络
  • 测试客户端:srs-bench
  • 测试版本:lal_v0.19.1_linux从release中下载。默认参数

重现步骤

  • rtsp推流使用udp或者tcp方式都可以
    ffmpeg -re -stream_loop -1 -i "bbb_sunflower_1080p_30fps_normal.mp4" -an -vcodec copy -rtsp_transport tcp -f rtsp rtsp://localhost:5544/live/livestream
  • srs-bench压测500路,等待全部加载完成。然后 srs-bench 界面ctrl+c 结束压测,出现崩溃。压测100路不会出现,有时候压测1000路,加载过程中直接崩溃。崩溃都是同一个异常,不太懂代码,看上去是map并发问题。
    sb_rtmp_load -c 1000 -r rtmp://127.0.0.1:1935/live/livestream
    错误日志:
    fatal error: concurrent map iteration and map write2021/03/18 12:12:13.671875 DEBUG [GROUP1] [RTMPPUBSUB75] del rtmp SubSession from group. - group.go:668
    lal.log

推流端网线断开或直接掉电,服务端无法快速检测到

func (c *ChunkComposer) RunLoop(reader io.Reader, cb OnCompleteMessage)
对io.ReadAtLeast的调用需要正常TCP超时才能结束,时间比较久
超时后err := session.RunLoop()返回,回到func (server *Server) handleTCPConnect
再执行server.obs.OnDelRTMPPubSession(session)

lal设计上的一些疑问

这两天看了一下lal代码真的是非常棒的项目,但是也有一些疑问,下面主要是我阅读代码的一些记录疑问在记录当中,这样看起来应该更能表达出我的问题(这些疑问我自己修改后工作正常,见第8点):

group 创建过程:

doPublish  -->  func (sm *ServerManager) NewRTMPPubSessionCB
	--> func (sm *ServerManager) getOrCreateGroup(appName string, streamName string)
		根据appName,streamName来判断是否存在,不存在则创建新的group,创建协程执行
                    go group.RunLoop()
		这里有2个疑问:
			group.RunLoop()中无有效动作,只是阻塞等待退出事件 <-group.exitChan,这样设计好
                           像没有意义还浪费一个协程??
		      难道设计时预留来想专门用这个group协程来执行OnReadRTMPAVMsg处理流数据转发流
                          数据??但是对OnReadRTMPAVMsg的调用是在NewServerSession协程中直接调用的(没
                          有使用channel,group中也没有创建接收msg的channel),具体分析见第5点。

doPlay -->  func (sm *ServerManager) NewRTMPSubSessionCB
		根据appName,streamName来判断是否存在,不存在则创建新的group,创建协程执行
                    go group.RunLoop()
		疑问:
			如果存在group就会对相同group再创建一个协程执行group.RunLoop(),doPublish和
                           doPlay都会生成新协程来执行同一个group的group.RunLoop(),为什么这样设计??这
                           样会有N+1个协程(N个播放,1个推流)一个播放请求过来会产生3个协程:
                               代表连接的NewServerSession、connection中专门发数据协程、group中这个阻塞协程
		播放请求时生成的group协程完全是多余的,有处理读数据的NewServerSession和处理写数据
                    的connection协程。

5、 关于 connection 数据写操作:
当一个流有N个播放端时存在一种情况,推流的ServerSession(对应一个协程)
需要在收到一个数据时要求极短时间内把数据写入N个connection(通过channel写),写入后才能接收下一个数据,这个过程是
同步的所有操作都在同一个ServerSession中完成,也就是ServerSession接收流的协程需要收到chunk数据转成msg再调用OnReadRTMPAVMsg
来转封装和向N个connection转发数据,播流端的数量和channel的效率会决定推流端的ServerSession能否处理得过来。
接收推流的协程把chunk转成msg,在OnReadRTMPAVMsg中复制一份msg.Payload,再到broadcastRTMP函数中把msg转成chunk数据。

8、效率修改
为什么一定要在OnReadRTMPAVMsg中复制一份数据,不复制效率不是更高??(修改成不复制数据测试正常)
func (f *FragmentOP) WriteFrame函数中不需要在循环内每次packet := make([]byte, 188),在循环外或者直接使用成员变量就不用每次去分配内存了。
group创建过程中提到的协程问题修改后正常工作

v0.19.0程序会卡死

测试环境

  • 系统: ubuntu 20.04
  • 内存:16G
  • CPU: 4.01 GHz 四核Intel Core i7
  • 网络: 127.0.0.1本地循环网络
  • 测试客户端:srs-bench
  • 测试版本:lal_v0.19.0_linux从release中下载。参数修改:"gop_num": 0 和关闭 hls
  • 测试方法:推流1路,通过srs-bench 播放100路RTMP
    srs-bench推流命令:srs-bench/objs/sb_rtmp_publish -i doc/source.200kbps.768x320.flv -c 1 -r rtmp://127.0.0.1:1935/live/livestream srs-bench压测命令:srs-bench/objs/sb_rtmp_load -c 100 -r rtmp://127.0.0.1:1935/live/livestream`

出现问题

  • ffplay 直接播放一路没有问题.
  • srs-bench 加载完100路几秒后,推流端和播放端就会卡住。使用ffplay播放不了,像是死锁的感觉,程序没有崩溃。
  • srs-bench 有时候压测10路都会出现
  • lal_v0.18.0_linux 版本不会出现

日志需要更多的级别

需要在debug级别之下提供一个更详细的trace级别的日志。
该级别的日志甚至可以打印收发包的dump。
业务方使用lal出现问题时,可以打开trace日志,提供给我定位问题。


naza v0.18.5已新增trace日志级别

rtsp没有音频导致推流失败的问题

利用ffmpeg推送NVR的RTSP流,RTSP流视频是H264,没有音频,lalserver接收推流报错,如下图所示:
image
9924cf8e5ab0eda7905205a84987a85

沟通后大致原因是:在lal上做了个音视频重排序,没有音频的流,可能就没法返回了。
请帮忙解决更新下,3Q。

calcHeader可以修改地方

func calcHeader(header *Header, prevHeader *Header, out []byte)函数可以修改的地方:
func calcHeader(header *Header, prevHeader *Header, out []byte) int {
var index int = 0

// 计算fmt和timestamp
fmt := uint8(0)
var timestamp uint32
if prevHeader == nil {
	timestamp = header.TimestampAbs
} else {

	//修改后.一个MSG内MsgStreamID一定是相同的,同时使用固定fmt3,原始的那几个判断条件执行后fmt始终为3
	fmt = 3
	if header.TimestampAbs > maxTimestampInMessageHeader {
		timestamp = header.TimestampAbs
	} else {
		timestamp = header.TimestampAbs - prevHeader.TimestampAbs
	}

	//修改前
	//if header.MsgStreamID == prevHeader.MsgStreamID {
	//	fmt++
	//	if header.MsgLen == prevHeader.MsgLen && header.MsgTypeID == prevHeader.MsgTypeID {
	//		fmt++
	//		if header.TimestampAbs == prevHeader.TimestampAbs {
	//			fmt++
	//		}
	//	}
	//	if header.TimestampAbs > maxTimestampInMessageHeader {
	//		timestamp = header.TimestampAbs
	//	} else {
	//		timestamp = header.TimestampAbs - prevHeader.TimestampAbs
	//	}
	//} else {
	//	timestamp = header.TimestampAbs
	//}
}

建议…可以做一个web后台监管系统

1.实时更新推拉流的客户端数量,ip,带宽流量等
2.分布式集群管理,一键添加或删除流服务器节点
3.实时监控播放正在推流内容,类似于监控室画面
4.根据时间段,播放量等可过滤直播回放视频列表
等等以及其他需要监管的数据信息。

WARN [HLSMUXER117] force fragment split.

Hls fragments stopped after alot of warnings.

WARN [HLSMUXER117] force fragment split. fragTS=5887080, ts=32262660 - muxer.go:197

2020/12/10 06:17:04.654147  WARN [HLSMUXER117] force fragment split. fragTS=220818150, ts=100316700 - muxer.go:197
2020/12/10 06:17:04.655346  WARN [HLSMUXER117] force fragment split. fragTS=100316700, ts=220822020 - muxer.go:197
2020/12/10 06:17:04.656969  WARN [HLSMUXER117] force fragment split. fragTS=220822020, ts=100319760 - muxer.go:197
2020/12/10 06:17:04.658761  WARN [HLSMUXER117] force fragment split. fragTS=100319760, ts=220825800 - muxer.go:197
2020/12/10 06:17:04.660818 DEBUG naza connection close. err=EOF, conn=0xc0000b8140 - connection.go:405
2020/12/10 06:17:04.660855  INFO [RTMPPUBSUB336] rtmp loop done. err=EOF - server.go:69
2020/12/10 06:17:04.660860 DEBUG naza connection recv exitChan and exit write loop. conn=0xc0000b8140 - connection.go:367
2020/12/10 06:17:04.660863 DEBUG [GROUP116] [RTMPPUBSUB336] del rtmp PubSession from group. - group.go:653
2020/12/10 06:17:04.660874  INFO [HLSMUXER117] lifecycle dispose hls muxer. - muxer.go:110

期望增加HTTPS证书的支持

目前只能使用HTTP连接过去播放FLV;
这有 个致命的问题,在HTTPS的页面上面,是不允许 加载HTTP协议的,这造成无法使用;

其他老板可以增加自定义证书的功能,自己上传HTTPS证书,支持HTTPS播放FLV;

目前折衷的解决办法是: 使用nginx反向代理 HTTP协议,然后输出HTTPS协议的流,这样一来,增加了代理的时间,同时加大延时,而且使用复杂度增加;Nginx上面有这块很好的功能,但是并不是所有人都使用Linux,使用Windows的时候,并不能很好的解决这个问题。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.