diff --git a/.gitignore b/.gitignore index 16d5dd4..6fc0873 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,20 @@ /.idea /.vscode -/SECRET.md -profile.out -coverage.html -/coverage.txt +lal_record logs testdata /bin /release -/.trash -/playground /tmp +/playground +profile.out +coverage.html +/coverage.txt +delay.txt +/.trash +/SECRET.md /TODO.md /pre-commit.sh /conf/self.conf.json @@ -23,5 +25,3 @@ testdata *.aac *.h264 *.flv -lal_record -delay.txt diff --git a/Makefile b/Makefile index 6f2c427..4f40838 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ image: .PHONY: clean clean: - rm -rf ./bin ./release ./logs ./lal_record + rm -rf ./bin ./lal_record ./logs coverage.txt .PHONY: all all: build test diff --git a/go.mod b/go.mod index a7d6921..427de17 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module github.com/q191201771/lal go 1.14 -require github.com/q191201771/naza v0.29.0 +require github.com/q191201771/naza v0.30.0 diff --git a/go.sum b/go.sum index 69af1bb..96cd5c5 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -github.com/q191201771/naza v0.29.0 h1:VvvJfYVkmQjszOXqhYyf2gGOCPl69woLCSWxNF0T//I= -github.com/q191201771/naza v0.29.0/go.mod h1:n+dpJjQSh90PxBwxBNuifOwQttywvSIN5TkWSSYCeBk= +github.com/q191201771/naza v0.30.0 h1:tfy1O0QRl3O80mH8PSAd2FhpZ5eL7coQtCF0HzjEO4Y= +github.com/q191201771/naza v0.30.0/go.mod h1:n+dpJjQSh90PxBwxBNuifOwQttywvSIN5TkWSSYCeBk= diff --git a/pkg/aac/aac_test.go b/pkg/aac/aac_test.go index a698bee..86344d8 100644 --- a/pkg/aac/aac_test.go +++ b/pkg/aac/aac_test.go @@ -16,8 +16,6 @@ import ( "github.com/q191201771/lal/pkg/aac" - "github.com/q191201771/naza/pkg/nazalog" - "github.com/q191201771/naza/pkg/assert" ) @@ -90,5 +88,5 @@ func TestMakeAudioDataSeqHeader(t *testing.T) { func TestSequenceHeaderContext(t *testing.T) { var shCtx aac.SequenceHeaderContext shCtx.Unpack(goldenSh) - nazalog.Debugf("%+v", shCtx) + aac.Log.Debugf("%+v", shCtx) } diff --git a/pkg/aac/var.go b/pkg/aac/var.go new file mode 100644 index 0000000..c56fe02 --- /dev/null +++ b/pkg/aac/var.go @@ -0,0 +1,13 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package aac + +import "github.com/q191201771/naza/pkg/nazalog" + +var Log = nazalog.GetGlobalLogger() diff --git a/pkg/avc/avc.go b/pkg/avc/avc.go index d44a0f6..eadab0b 100644 --- a/pkg/avc/avc.go +++ b/pkg/avc/avc.go @@ -11,10 +11,8 @@ package avc import ( "io" - "github.com/q191201771/naza/pkg/nazabytes" - "github.com/q191201771/naza/pkg/nazalog" - "github.com/q191201771/lal/pkg/base" + "github.com/q191201771/naza/pkg/nazabytes" "github.com/q191201771/naza/pkg/nazaerrors" @@ -36,7 +34,7 @@ var ( NaluStartCode3 = []byte{0x0, 0x0, 0x1} NaluStartCode4 = []byte{0x0, 0x0, 0x0, 0x1} - // aud nalu + // AudNalu aud nalu AudNalu = []byte{0x00, 0x00, 0x00, 0x01, 0x09, 0xf0} ) @@ -498,7 +496,7 @@ func IterateNaluAvcc(nals []byte, handler func(nal []byte)) error { // length为0的直接过滤掉 if length == 0 { - nazalog.Warnf("avcc nalu length equal 0. nals=%s", nazabytes.Prefix(nals, 128)) + Log.Warnf("avcc nalu length equal 0. nals=%s", nazabytes.Prefix(nals, 128)) continue } handler(nals[pos:epos]) @@ -507,7 +505,7 @@ func IterateNaluAvcc(nals []byte, handler func(nal []byte)) error { // 最后一个 if length == 0 { - nazalog.Warnf("avcc nalu length equal 0. nals=%s", nazabytes.Prefix(nals, 128)) + Log.Warnf("avcc nalu length equal 0. nals=%s", nazabytes.Prefix(nals, 128)) continue } handler(nals[pos:epos]) diff --git a/pkg/avc/avc_test.go b/pkg/avc/avc_test.go index 4f79c53..636b1d5 100644 --- a/pkg/avc/avc_test.go +++ b/pkg/avc/avc_test.go @@ -18,8 +18,6 @@ import ( "github.com/q191201771/naza/pkg/nazabits" "github.com/q191201771/naza/pkg/nazaerrors" - "github.com/q191201771/naza/pkg/nazalog" - "github.com/q191201771/lal/pkg/avc" "github.com/q191201771/naza/pkg/assert" @@ -36,7 +34,7 @@ func TestParseNaluType(t *testing.T) { assert.Equal(t, out, actual) b := avc.ParseNaluTypeReadable(in) - nazalog.Debug(b) + avc.Log.Debug(b) } } @@ -60,7 +58,7 @@ func TestParseSliceType(t *testing.T) { b, err := avc.ParseSliceTypeReadable(item.in) assert.Equal(t, nil, err) - nazalog.Debug(b) + avc.Log.Debug(b) } } @@ -138,7 +136,7 @@ func TestParseSps(t *testing.T) { err = avc.ParseSps(nil, &ctx) assert.Equal(t, true, nazaerrors.Is(err, nazabits.ErrNazaBits)) assert.IsNotNil(t, err) - nazalog.Debugf("error expected not nil, actual=%+v", err) + avc.Log.Debugf("error expected not nil, actual=%+v", err) err = avc.ParseSps(goldenSps2, &ctx) assert.Equal(t, nil, err) diff --git a/pkg/avc/beta.go b/pkg/avc/beta.go index 6662d26..4016561 100644 --- a/pkg/avc/beta.go +++ b/pkg/avc/beta.go @@ -18,14 +18,13 @@ import ( "github.com/q191201771/naza/pkg/bele" "github.com/q191201771/naza/pkg/nazabits" "github.com/q191201771/naza/pkg/nazabytes" - "github.com/q191201771/naza/pkg/nazalog" ) func ParseSps(payload []byte, ctx *Context) error { br := nazabits.NewBitReader(payload) var sps Sps if err := parseSpsBasic(&br, &sps); err != nil { - nazalog.Errorf("parseSpsBasic failed. err=%+v, payload=%s", err, hex.Dump(nazabytes.Prefix(payload, 128))) + Log.Errorf("parseSpsBasic failed. err=%+v, payload=%s", err, hex.Dump(nazabytes.Prefix(payload, 128))) return err } ctx.Profile = sps.ProfileIdc @@ -37,16 +36,16 @@ func ParseSps(payload []byte, ctx *Context) error { if err := parseSpsGamma(&br, &sps); err != nil { // 注意,这里不将错误返回给上层,因为可能是Beta自身解析的问题 - nazalog.Errorf("parseSpsGamma failed. err=%+v, payload=%s", err, hex.Dump(nazabytes.Prefix(payload, 128))) + Log.Errorf("parseSpsGamma failed. err=%+v, payload=%s", err, hex.Dump(nazabytes.Prefix(payload, 128))) } - nazalog.Debugf("sps=%+v", sps) + Log.Debugf("sps=%+v", sps) ctx.Width = (sps.PicWidthInMbsMinusOne+1)*16 - (sps.FrameCropLeftOffset+sps.FrameCropRightOffset)*2 ctx.Height = (2-uint32(sps.FrameMbsOnlyFlag))*(sps.PicHeightInMapUnitsMinusOne+1)*16 - (sps.FrameCropTopOffset+sps.FrameCropBottomOffset)*2 return nil } -// 尝试解析PPS所有字段,实验中,请勿直接使用该函数 +// TryParsePps 尝试解析PPS所有字段,实验中,请勿直接使用该函数 func TryParsePps(payload []byte) error { // ISO-14496-10.pdf // 7.3.2.2 Picture parameter set RBSP syntax @@ -55,7 +54,7 @@ func TryParsePps(payload []byte) error { return nil } -// 尝试解析SeqHeader所有字段,实验中,请勿直接使用该函数 +// TryParseSeqHeader 尝试解析SeqHeader所有字段,实验中,请勿直接使用该函数 // // @param rtmp message的payload部分或者flv tag的payload部分 // 注意,包含了头部2字节类型以及3字节的cts @@ -94,7 +93,7 @@ func TryParseSeqHeader(payload []byte) error { b, err = br.ReadBytes(2) dcr.PpsLength = bele.BeUint16(b) - nazalog.Debugf("%+v", dcr) + Log.Debugf("%+v", dcr) // 5 + 5 + 1 + 2 var ctx Context diff --git a/pkg/avc/var.go b/pkg/avc/var.go new file mode 100644 index 0000000..da4a061 --- /dev/null +++ b/pkg/avc/var.go @@ -0,0 +1,13 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package avc + +import "github.com/q191201771/naza/pkg/nazalog" + +var Log = nazalog.GetGlobalLogger() diff --git a/pkg/base/base.go b/pkg/base/base.go index 9107df9..0750bcb 100644 --- a/pkg/base/base.go +++ b/pkg/base/base.go @@ -14,7 +14,6 @@ import ( "time" "github.com/q191201771/naza/pkg/bininfo" - "github.com/q191201771/naza/pkg/nazalog" ) // base包提供被其他多个package依赖的基础内容,自身不依赖任何package @@ -23,9 +22,7 @@ import ( var startTime string -// ReadableNowTime -// -// TODO(chef): refactor 使用ReadableNowTime +// ReadableNowTime 当前时间,可读字符串形式 // func ReadableNowTime() string { return time.Now().Format("2006-01-02 15:04:05.999") @@ -33,13 +30,13 @@ func ReadableNowTime() string { func LogoutStartInfo() { dir, _ := os.Getwd() - nazalog.Infof(" start: %s", startTime) - nazalog.Infof(" wd: %s", dir) - nazalog.Infof(" args: %s", strings.Join(os.Args, " ")) - nazalog.Infof(" bininfo: %s", bininfo.StringifySingleLine()) - nazalog.Infof(" version: %s", LalFullInfo) - nazalog.Infof(" github: %s", LalGithubSite) - nazalog.Infof(" doc: %s", LalDocSite) + Log.Infof(" start: %s", startTime) + Log.Infof(" wd: %s", dir) + Log.Infof(" args: %s", strings.Join(os.Args, " ")) + Log.Infof(" bininfo: %s", bininfo.StringifySingleLine()) + Log.Infof(" version: %s", LalFullInfo) + Log.Infof(" github: %s", LalGithubSite) + Log.Infof(" doc: %s", LalDocSite) } func init() { diff --git a/pkg/base/http_server_test.go b/pkg/base/http_server_test.go index 81397ca..a64b926 100644 --- a/pkg/base/http_server_test.go +++ b/pkg/base/http_server_test.go @@ -16,11 +16,11 @@ func TestHttpServerManager(t *testing.T) { //var err error // //var fnFlv = func(writer http.ResponseWriter, request *http.Request) { - // nazalog.Debugf("> fnFlv") + // Log.Debugf("> fnFlv") //} // //var fnTs = func(writer http.ResponseWriter, request *http.Request) { - // nazalog.Debugf("> fnTs") + // Log.Debugf("> fnTs") //} // //sm := NewHttpServerManager() diff --git a/pkg/base/http_sub_session.go b/pkg/base/http_sub_session.go index 85ac970..62c12dd 100644 --- a/pkg/base/http_sub_session.go +++ b/pkg/base/http_sub_session.go @@ -11,7 +11,6 @@ package base import ( "net" "strings" - "time" "github.com/q191201771/naza/pkg/connection" ) @@ -43,7 +42,7 @@ func NewHttpSubSession(option HttpSubSessionOption) *HttpSubSession { stat: StatSession{ Protocol: option.Protocol, SessionId: option.Uk, - StartTime: time.Now().Format("2006-01-02 15:04:05.999"), + StartTime: ReadableNowTime(), RemoteAddr: option.Conn.RemoteAddr().String(), }, } @@ -118,7 +117,7 @@ func (session *HttpSubSession) StreamName() string { case ProtocolHttpts: suffix = ".ts" default: - Logger.Warnf("[%s] acquire stream name but protocol unknown.", session.Uk) + Log.Warnf("[%s] acquire stream name but protocol unknown.", session.Uk) } return strings.TrimSuffix(session.UrlCtx.LastItemOfPath, suffix) } diff --git a/pkg/base/log.go b/pkg/base/log.go index a88161c..cfa74e1 100644 --- a/pkg/base/log.go +++ b/pkg/base/log.go @@ -15,6 +15,7 @@ import ( ) type LogDump struct { + log nazalog.Logger debugMaxNum int debugCount int @@ -24,14 +25,15 @@ type LogDump struct { // // @param debugMaxNum: 日志最小级别为debug时,使用debug打印日志次数的阈值 // -func NewLogDump(debugMaxNum int) LogDump { +func NewLogDump(log nazalog.Logger, debugMaxNum int) LogDump { return LogDump{ + log: log, debugMaxNum: debugMaxNum, } } func (ld *LogDump) ShouldDump() bool { - switch nazalog.GetOption().Level { + switch ld.log.GetOption().Level { case nazalog.LevelTrace: return true case nazalog.LevelDebug: @@ -52,5 +54,5 @@ func (ld *LogDump) ShouldDump() bool { // 这个hex.Dump调用 // func (ld *LogDump) Outf(format string, v ...interface{}) { - nazalog.Out(nazalog.GetOption().Level, 3, fmt.Sprintf(format, v...)) + ld.log.Out(ld.log.GetOption().Level, 3, fmt.Sprintf(format, v...)) } diff --git a/pkg/base/merge_writer.go b/pkg/base/merge_writer.go index 5356074..2313ff2 100644 --- a/pkg/base/merge_writer.go +++ b/pkg/base/merge_writer.go @@ -10,8 +10,6 @@ package base import ( "net" - - "github.com/q191201771/naza/pkg/nazalog" ) // TODO(chef): feat 通过时间戳(目前是数据大小)来设定合并阈值 @@ -47,7 +45,7 @@ func NewMergeWriter(onWritev OnWritev, size int) *MergeWriter { // 注意,函数调用结束后,`b`内存块会被内部持有 // func (w *MergeWriter) Write(b []byte) { - nazalog.Debugf("[%p] MergeWriter::Write. len=%d", w, len(b)) + Log.Debugf("[%p] MergeWriter::Write. len=%d", w, len(b)) w.bs = append(w.bs, b) w.currSize += len(b) if w.currSize >= w.size { @@ -58,7 +56,7 @@ func (w *MergeWriter) Write(b []byte) { // Flush 强制将内部缓冲的数据全部回调排空 // func (w *MergeWriter) Flush() { - nazalog.Debugf("[%p] MergeWriter::Flush.", w) + Log.Debugf("[%p] MergeWriter::Flush.", w) if w.currSize > 0 { w.flush() } @@ -74,7 +72,7 @@ func (w *MergeWriter) flush() { n += len(v) ns = append(ns, len(v)) } - nazalog.Debugf("[%p] MergeWriter::flush. len=%d(%v)", w, n, ns) + Log.Debugf("[%p] MergeWriter::flush. len=%d(%v)", w, n, ns) w.onWritev(w.bs) w.currSize = 0 w.bs = nil diff --git a/pkg/base/rtmp_t.go b/pkg/base/rtmp_t.go index 53056e4..92b5136 100644 --- a/pkg/base/rtmp_t.go +++ b/pkg/base/rtmp_t.go @@ -9,7 +9,7 @@ package base const ( - // spec-rtmp_specification_1.0.pdf + // RtmpTypeIdAudio spec-rtmp_specification_1.0.pdf // 7.1. Types of Messages RtmpTypeIdAudio uint8 = 8 RtmpTypeIdVideo uint8 = 9 @@ -32,7 +32,7 @@ const ( RtmpUserControlPingRequest uint8 = 6 RtmpUserControlPingResponse uint8 = 7 - // spec-video_file_format_spec_v10.pdf + // RtmpFrameTypeKey spec-video_file_format_spec_v10.pdf // Video tags // VIDEODATA // FrameType UB[4] @@ -63,7 +63,7 @@ const ( RtmpAvcInterFrame = RtmpFrameTypeInter<<4 | RtmpCodecIdAvc RtmpHevcInterFrame = RtmpFrameTypeInter<<4 | RtmpCodecIdHevc - // spec-video_file_format_spec_v10.pdf + // RtmpSoundFormatAac spec-video_file_format_spec_v10.pdf // Audio tags // AUDIODATA // SoundFormat UB[4] diff --git a/pkg/base/rtprtcp_t.go b/pkg/base/rtprtcp_t.go index 7e7710e..6735944 100644 --- a/pkg/base/rtprtcp_t.go +++ b/pkg/base/rtprtcp_t.go @@ -9,7 +9,7 @@ package base const ( - // 注意,一般情况下,AVC使用96,AAC使用97,HEVC使用98 + // RtpPacketTypeAvcOrHevc 注意,一般情况下,AVC使用96,AAC使用97,HEVC使用98 // 但是我还遇到过: // HEVC使用96 // AVC使用105 diff --git a/pkg/base/signal_unix.go b/pkg/base/signal_unix.go index c949f2b..b6da107 100644 --- a/pkg/base/signal_unix.go +++ b/pkg/base/signal_unix.go @@ -14,8 +14,6 @@ import ( "os" "os/signal" "syscall" - - log "github.com/q191201771/naza/pkg/nazalog" ) // RunSignalHandler 监听SIGUSR1和SIGUSR2信号并回调 @@ -26,6 +24,6 @@ func RunSignalHandler(cb func()) { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGUSR1, syscall.SIGUSR2) s := <-c - log.Infof("recv signal. s=%+v", s) + Log.Infof("recv signal. s=%+v", s) cb() } diff --git a/pkg/base/stat.go b/pkg/base/stat.go index 3bc43ed..bb03f79 100644 --- a/pkg/base/stat.go +++ b/pkg/base/stat.go @@ -9,14 +9,14 @@ package base const ( - // StatGroup.AudioCodec + // AudioCodecAac StatGroup.AudioCodec AudioCodecAac = "AAC" - // StatGroup.VideoCodec + // VideoCodecAvc StatGroup.VideoCodec VideoCodecAvc = "H264" VideoCodecHevc = "H265" - // StatSession.Protocol + // ProtocolRtmp StatSession.Protocol ProtocolRtmp = "RTMP" ProtocolRtsp = "RTSP" ProtocolHttpflv = "HTTP-FLV" diff --git a/pkg/base/var.go b/pkg/base/var.go index 215e6e6..c480b2b 100644 --- a/pkg/base/var.go +++ b/pkg/base/var.go @@ -10,6 +10,4 @@ package base import "github.com/q191201771/naza/pkg/nazalog" -var ( - Logger = nazalog.GetGlobalLogger() -) +var Log = nazalog.GetGlobalLogger() diff --git a/pkg/base/version.go b/pkg/base/version.go index 7ea6741..ac72ce5 100644 --- a/pkg/base/version.go +++ b/pkg/base/version.go @@ -15,7 +15,7 @@ import "strings" // 另外,我们也在本文件提供另外一些信息 // 并且将这些信息打入可执行文件、日志、各协议中的标准版本字段中 -// 版本,该变量由外部脚本修改维护 +// LalVersion 版本,该变量由外部脚本修改维护 const LalVersion = "v0.27.1" var ( @@ -24,57 +24,57 @@ var ( LalGithubSite = "https://github.com/q191201771/lal" LalDocSite = "https://pengrl.com/lal" - // e.g. lal v0.12.3 (github.com/q191201771/lal) + // LalFullInfo e.g. lal v0.12.3 (github.com/q191201771/lal) LalFullInfo = LalLibraryName + " " + LalVersion + " (" + LalGithubRepo + ")" - // e.g. 0.12.3 + // LalVersionDot e.g. 0.12.3 LalVersionDot string - // e.g. 0,12,3 + // LalVersionComma e.g. 0,12,3 LalVersionComma string ) var ( - // 植入rtmp握手随机字符串中 + // LalRtmpHandshakeWaterMark 植入rtmp握手随机字符串中 // e.g. lal v0.12.3 (github.com/q191201771/lal) LalRtmpHandshakeWaterMark string - // 植入rtmp server中的connect result信令中 + // LalRtmpConnectResultVersion 植入rtmp server中的connect result信令中 // 注意,有两个object,第一个object中的fmsVer我们保持通用公认的值,在第二个object中植入 // e.g. 0,12,3 LalRtmpConnectResultVersion string - // e.g. lal0.12.3 + // LalRtmpPushSessionConnectVersion e.g. lal0.12.3 LalRtmpPushSessionConnectVersion string - // e.g. lal0.12.3 + // LalRtmpBuildMetadataEncoder e.g. lal0.12.3 LalRtmpBuildMetadataEncoder string - // e.g. lal/0.12.3 + // LalHttpflvPullSessionUa e.g. lal/0.12.3 LalHttpflvPullSessionUa string - // e.g. lal0.12.3 + // LalHttpflvSubSessionServer e.g. lal0.12.3 LalHttpflvSubSessionServer string - // e.g. lal0.12.3 + // LalHlsM3u8Server e.g. lal0.12.3 LalHlsM3u8Server string - // e.g. lal0.12.3 + // LalHlsTsServer e.g. lal0.12.3 LalHlsTsServer string - // e.g. lal0.12.3 + // LalRtspOptionsResponseServer e.g. lal0.12.3 LalRtspOptionsResponseServer string - // e.g. lal0.12.3 + // LalHttptsSubSessionServer e.g. lal0.12.3 LalHttptsSubSessionServer string - // e.g. lal0.12.3 + // LalHttpApiServer e.g. lal0.12.3 LalHttpApiServer string - // e.g. lal/0.12.3 + // LalRtspPullSessionUa e.g. lal/0.12.3 LalRtspPullSessionUa string - // e.g. lal 0.12.3 + // LalPackSdp e.g. lal 0.12.3 LalPackSdp string ) diff --git a/pkg/base/websocket.go b/pkg/base/websocket.go index 046824e..5ba564e 100644 --- a/pkg/base/websocket.go +++ b/pkg/base/websocket.go @@ -16,7 +16,7 @@ import ( "github.com/q191201771/naza/pkg/bele" ) -// The WebSocket Protocol +// WsOpcode The WebSocket Protocol // https://tools.ietf.org/html/rfc6455 // // 0 1 2 3 @@ -59,7 +59,8 @@ const ( Wso_Continuous WsOpcode = iota //连续消息片断 Wso_Text //文本消息片断, Wso_Binary //二进制消息片断, - //非控制消息片断保留的操作码, + + // Wso_Rsv3 非控制消息片断保留的操作码, Wso_Rsv3 Wso_Rsv4 Wso_Rsv5 @@ -68,7 +69,8 @@ const ( Wso_Close //连接关闭, Wso_Ping //心跳检查的ping, Wso_Pong //心跳检查的pong, - //为将来的控制消息片断的保留操作码 + + // Wso_RsvB 为将来的控制消息片断的保留操作码 Wso_RsvB Wso_RsvC Wso_RsvD diff --git a/pkg/hevc/hevc.go b/pkg/hevc/hevc.go index 95afea4..4fa5db5 100644 --- a/pkg/hevc/hevc.go +++ b/pkg/hevc/hevc.go @@ -173,7 +173,7 @@ func ParseVpsSpsPpsFromSeqHeaderWithoutMalloc(payload []byte) (vps, sps, pps []b if payload[0] != 0x1c || payload[1] != 0x00 || payload[2] != 0 || payload[3] != 0 || payload[4] != 0 { return nil, nil, nil, nazaerrors.Wrap(base.ErrHevc) } - //nazalog.Debugf("%s", hex.Dump(payload)) + //Log.Debugf("%s", hex.Dump(payload)) if len(payload) < 33 { return nil, nil, nil, nazaerrors.Wrap(base.ErrHevc) diff --git a/pkg/hevc/var.go b/pkg/hevc/var.go new file mode 100644 index 0000000..9a2674c --- /dev/null +++ b/pkg/hevc/var.go @@ -0,0 +1,13 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package hevc + +import "github.com/q191201771/naza/pkg/nazalog" + +var Log = nazalog.GetGlobalLogger() diff --git a/pkg/hls/m3u8.go b/pkg/hls/m3u8.go index 8ea5159..568f6a4 100644 --- a/pkg/hls/m3u8.go +++ b/pkg/hls/m3u8.go @@ -59,7 +59,7 @@ func updateTargetDurationInM3u8(content []byte, currDuration int) ([]byte, error return content, nil } -// @param content 传入m3u8文件内容 +// CalcM3u8Duration @param content 传入m3u8文件内容 // // @return durationSec m3u8中所有ts的时间总和。注意,使用的是m3u8文件中描述的ts时间,而不是读取ts文件中实际音视频数据的时间。 // diff --git a/pkg/hls/muxer.go b/pkg/hls/muxer.go index e496aa6..d7bc1e8 100644 --- a/pkg/hls/muxer.go +++ b/pkg/hls/muxer.go @@ -17,8 +17,6 @@ import ( "github.com/q191201771/lal/pkg/mpegts" "github.com/q191201771/lal/pkg/base" - - "github.com/q191201771/naza/pkg/nazalog" ) // TODO chef: 转换TS流的功能(通过回调供httpts使用)也放在了Muxer中,好处是hls和httpts可以共用一份TS流。 @@ -27,8 +25,11 @@ import ( type MuxerObserver interface { OnPatPmt(b []byte) - // @param rawFrame TS流,回调结束后,内部不再使用该内存块 - // @param boundary 新的TS流接收者,应该从该标志为true时开始发送数据 + // OnTsPackets + // + // @param rawFrame: TS流,回调结束后,内部不再使用该内存块 + // + // @param boundary: 新的TS流接收者,应该从该标志为true时开始发送数据 // OnTsPackets(rawFrame []byte, boundary bool) } @@ -70,10 +71,14 @@ type Muxer struct { observer MuxerObserver fragment Fragment - opened bool videoCc uint8 audioCc uint8 + // 初始值为false,调用openFragment时设置为true,调用closeFragment时设置为false + // 整个对象关闭时设置为false + // 中途切换Fragment时,调用close后会立即调用open + opened bool + fragTs uint64 // 新建立fragment时的时间戳,毫秒 * 90 recordMaxFragDuration float64 @@ -120,29 +125,31 @@ func NewMuxer(streamName string, enable bool, config *MuxerConfig, observer Muxe m.makeFrags() streamer := NewStreamer(m) m.streamer = streamer - nazalog.Infof("[%s] lifecycle new hls muxer. muxer=%p, streamName=%s", uk, m, streamName) + Log.Infof("[%s] lifecycle new hls muxer. muxer=%p, streamName=%s", uk, m, streamName) return m } func (m *Muxer) Start() { - nazalog.Infof("[%s] start hls muxer.", m.UniqueKey) + Log.Infof("[%s] start hls muxer.", m.UniqueKey) m.ensureDir() } func (m *Muxer) Dispose() { - nazalog.Infof("[%s] lifecycle dispose hls muxer.", m.UniqueKey) + Log.Infof("[%s] lifecycle dispose hls muxer.", m.UniqueKey) m.streamer.FlushAudio() if err := m.closeFragment(true); err != nil { - nazalog.Errorf("[%s] close fragment error. err=%+v", m.UniqueKey, err) + Log.Errorf("[%s] close fragment error. err=%+v", m.UniqueKey, err) } } -// @param msg 函数调用结束后,内部不持有msg中的内存块 +// FeedRtmpMessage @param msg 函数调用结束后,内部不持有msg中的内存块 // func (m *Muxer) FeedRtmpMessage(msg base.RtmpMsg) { m.streamer.FeedRtmpMessage(msg) } +// ----- implement StreamerObserver of Streamer ------------------------------------------------------------------------ + func (m *Muxer) OnPatPmt(b []byte) { m.patpmt = b if m.observer != nil { @@ -150,50 +157,38 @@ func (m *Muxer) OnPatPmt(b []byte) { } } -func (m *Muxer) OnFrame(streamer *Streamer, frame *mpegts.Frame) { - var boundary bool +func (m *Muxer) OnFrame(streamer *Streamer, frame *mpegts.Frame, boundary bool) { var packets []byte if frame.Sid == mpegts.StreamIdAudio { - // 为了考虑没有视频的情况也能切片,所以这里判断spspps为空时,也建议生成fragment - boundary = !streamer.VideoSeqHeaderCached() + // TODO(chef): 为什么音频用pts,视频用dts if err := m.updateFragment(frame.Pts, boundary); err != nil { - nazalog.Errorf("[%s] update fragment error. err=%+v", m.UniqueKey, err) + Log.Errorf("[%s] update fragment error. err=%+v", m.UniqueKey, err) return } - + // TODO(chef): 有updateFragment的返回值判断,这里的判断可以考虑删除 if !m.opened { - nazalog.Warnf("[%s] OnFrame A not opened. boundary=%t", m.UniqueKey, boundary) + Log.Warnf("[%s] OnFrame A not opened. boundary=%t", m.UniqueKey, boundary) return } - - //nazalog.Debugf("[%s] WriteFrame A. dts=%d, len=%d", m.UniqueKey, frame.DTS, len(frame.Raw)) + //Log.Debugf("[%s] WriteFrame A. dts=%d, len=%d", m.UniqueKey, frame.DTS, len(frame.Raw)) } else { - //nazalog.Debugf("[%s] OnFrame V. dts=%d, len=%d", m.UniqueKey, frame.Dts, len(frame.Raw)) - // 收到视频,可能触发建立fragment的条件是: - // 关键帧数据 && - // ((没有收到过音频seq header) || -> 只有视频 - // (收到过音频seq header && fragment没有打开) || -> 音视频都有,且都已ready - // (收到过音频seq header && fragment已经打开 && 音频缓存数据不为空) -> 为什么音频缓存需不为空? - // ) - boundary = frame.Key && (!streamer.AudioSeqHeaderCached() || !m.opened || !streamer.AudioCacheEmpty()) if err := m.updateFragment(frame.Dts, boundary); err != nil { - nazalog.Errorf("[%s] update fragment error. err=%+v", m.UniqueKey, err) + Log.Errorf("[%s] update fragment error. err=%+v", m.UniqueKey, err) return } - + // TODO(chef): 有updateFragment的返回值判断,这里的判断可以考虑删除 if !m.opened { - nazalog.Warnf("[%s] OnFrame V not opened. boundary=%t, key=%t", m.UniqueKey, boundary, frame.Key) + Log.Warnf("[%s] OnFrame V not opened. boundary=%t, key=%t", m.UniqueKey, boundary, frame.Key) return } - - //nazalog.Debugf("[%s] WriteFrame V. dts=%d, len=%d", m.UniqueKey, frame.Dts, len(frame.Raw)) + //Log.Debugf("[%s] WriteFrame V. dts=%d, len=%d", m.UniqueKey, frame.Dts, len(frame.Raw)) } mpegts.PackTsPacket(frame, func(packet []byte) { if m.enable { if err := m.fragment.WriteFile(packet); err != nil { - nazalog.Errorf("[%s] fragment write error. err=%+v", m.UniqueKey, err) + Log.Errorf("[%s] fragment write error. err=%+v", m.UniqueKey, err) return } } @@ -206,13 +201,19 @@ func (m *Muxer) OnFrame(streamer *Streamer, frame *mpegts.Frame) { } } +// --------------------------------------------------------------------------------------------------------------------- + func (m *Muxer) OutPath() string { return m.outPath } -// 决定是否开启新的TS切片文件(注意,可能已经有TS切片,也可能没有,这是第一个切片) +// --------------------------------------------------------------------------------------------------------------------- + +// updateFragment 决定是否开启新的TS切片文件(注意,可能已经有TS切片,也可能没有,这是第一个切片) +// +// @param boundary: 调用方认为可能是开启新TS切片的时间点 // -// @param boundary 调用方认为可能是开启新TS切片的时间点 +// @return: 理论上,只有文件操作失败才会返回错误 // func (m *Muxer) updateFragment(ts uint64, boundary bool) error { discont := true @@ -231,7 +232,7 @@ func (m *Muxer) updateFragment(ts uint64, boundary bool) error { // maxfraglen := uint64(m.config.FragmentDurationMs * 90 * 10) if (ts > m.fragTs && ts-m.fragTs > maxfraglen) || (m.fragTs > ts && m.fragTs-ts > negMaxfraglen) { - nazalog.Warnf("[%s] force fragment split. fragTs=%d, ts=%d", m.UniqueKey, m.fragTs, ts) + Log.Warnf("[%s] force fragment split. fragTs=%d, ts=%d", m.UniqueKey, m.fragTs, ts) if err := m.closeFragment(false); err != nil { return err @@ -279,7 +280,11 @@ func (m *Muxer) updateFragment(ts uint64, boundary bool) error { return nil } -// @param discont 不连续标志,会在m3u8文件的fragment前增加`#EXT-X-DISCONTINUITY` +// openFragment +// +// @param discont: 不连续标志,会在m3u8文件的fragment前增加`#EXT-X-DISCONTINUITY` +// +// @return: 理论上,只有文件操作失败才会返回错误 // func (m *Muxer) openFragment(ts uint64, discont bool) error { if m.opened { @@ -314,6 +319,10 @@ func (m *Muxer) openFragment(ts uint64, discont bool) error { return nil } +// closeFragment +// +// @return: 理论上,只有文件操作失败才会返回错误 +// func (m *Muxer) closeFragment(isLast bool) error { if !m.opened { // 注意,首次调用closeFragment时,有可能opened为false @@ -343,7 +352,7 @@ func (m *Muxer) closeFragment(isLast bool) error { if frag.filename != "" { filenameWithPath := PathStrategy.GetTsFileNameWithPath(m.outPath, frag.filename) if err := fslCtx.Remove(filenameWithPath); err != nil { - nazalog.Warnf("[%s] remove stale fragment file failed. filename=%s, err=%+v", m.UniqueKey, filenameWithPath, err) + Log.Warnf("[%s] remove stale fragment file failed. filename=%s, err=%+v", m.UniqueKey, filenameWithPath, err) } } } @@ -371,7 +380,7 @@ func (m *Muxer) writeRecordPlaylist() { content = bytes.TrimSuffix(content, []byte("#EXT-X-ENDLIST\n")) content, err = updateTargetDurationInM3u8(content, int(m.recordMaxFragDuration)) if err != nil { - nazalog.Errorf("[%s] update target duration failed. err=%+v", m.UniqueKey, err) + Log.Errorf("[%s] update target duration failed. err=%+v", m.UniqueKey, err) return } @@ -400,7 +409,7 @@ func (m *Muxer) writeRecordPlaylist() { } if err := writeM3u8File(content, m.recordPlayListFilename, m.recordPlayListFilenameBak); err != nil { - nazalog.Errorf("[%s] write record m3u8 file error. err=%+v", m.UniqueKey, err) + Log.Errorf("[%s] write record m3u8 file error. err=%+v", m.UniqueKey, err) } } @@ -438,7 +447,7 @@ func (m *Muxer) writePlaylist(isLast bool) { } if err := writeM3u8File(buf.Bytes(), m.playlistFilename, m.playlistFilenameBak); err != nil { - nazalog.Errorf("[%s] write live m3u8 file error. err=%+v", m.UniqueKey, err) + Log.Errorf("[%s] write live m3u8 file error. err=%+v", m.UniqueKey, err) } } @@ -447,9 +456,9 @@ func (m *Muxer) ensureDir() { return } //err := fslCtx.RemoveAll(m.outPath) - //nazalog.Assert(nil, err) + //Log.Assert(nil, err) err := fslCtx.MkdirAll(m.outPath, 0777) - nazalog.Assert(nil, err) + Log.Assert(nil, err) } // --------------------------------------------------------------------------------------------------------------------- diff --git a/pkg/hls/path_strategy.go b/pkg/hls/path_strategy.go index 69643fd..a629290 100644 --- a/pkg/hls/path_strategy.go +++ b/pkg/hls/path_strategy.go @@ -43,17 +43,17 @@ type IPathRequestStrategy interface { GetRequestInfo(urlCtx base.UrlContext, rootOutPath string) RequestInfo } -// 落盘策略 +// IPathWriteStrategy 落盘策略 type IPathWriteStrategy interface { - // 获取单个流对应的文件根路径 + // GetMuxerOutPath 获取单个流对应的文件根路径 GetMuxerOutPath(rootOutPath string, streamName string) string - // 获取单个流对应的m3u8文件路径 + // GetLiveM3u8FileName 获取单个流对应的m3u8文件路径 // // @param outPath: func GetMuxerOutPath的结果 GetLiveM3u8FileName(outPath string, streamName string) string - // 获取单个流对应的record类型的m3u8文件路径 + // GetRecordM3u8FileName 获取单个流对应的record类型的m3u8文件路径 // // live m3u8和record m3u8的区别: // live记录的是当前最近的可播放内容,record记录的是从流开始时的可播放内容 @@ -61,12 +61,12 @@ type IPathWriteStrategy interface { // @param outPath: func GetMuxerOutPath的结果 GetRecordM3u8FileName(outPath string, streamName string) string - // 获取单个流对应的ts文件路径 + // GetTsFileNameWithPath 获取单个流对应的ts文件路径 // // @param outPath: func GetMuxerOutPath的结果 GetTsFileNameWithPath(outPath string, fileName string) string - // ts文件名的生成策略 + // GetTsFileName ts文件名的生成策略 GetTsFileName(streamName string, index int, timestamp int) string } @@ -77,7 +77,7 @@ const ( recordM3u8FileName = "record.m3u8" ) -// 默认的路由,落盘策略 +// DefaultPathStrategy 默认的路由,落盘策略 // // 每个流在下以流名称生成一个子目录,目录下包含: // @@ -136,7 +136,7 @@ func (dps *DefaultPathStrategy) GetRequestInfo(urlCtx base.UrlContext, rootOutPa return } -// / +// GetMuxerOutPath / func (*DefaultPathStrategy) GetMuxerOutPath(rootOutPath string, streamName string) string { return filepath.Join(rootOutPath, streamName) } diff --git a/pkg/hls/path_strategy_test.go b/pkg/hls/path_strategy_test.go index e8d7525..b68b738 100644 --- a/pkg/hls/path_strategy_test.go +++ b/pkg/hls/path_strategy_test.go @@ -11,8 +11,6 @@ package hls_test import ( "testing" - "github.com/q191201771/naza/pkg/nazalog" - "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/hls" @@ -48,7 +46,7 @@ func TestDefaultPathStrategy_GetRequestInfo(t *testing.T) { for k, v := range golden { ctx, err := base.ParseUrl(k, -1) - nazalog.Assert(nil, err) + hls.Log.Assert(nil, err) out := dps.GetRequestInfo(ctx, rootOutPath) assert.Equal(t, v, out) } diff --git a/pkg/hls/queue.go b/pkg/hls/queue.go index f3dbede..08b3fa9 100644 --- a/pkg/hls/queue.go +++ b/pkg/hls/queue.go @@ -13,8 +13,11 @@ import ( "github.com/q191201771/lal/pkg/mpegts" ) +// Queue +// // 缓存流起始的一些数据,判断流中是否存在音频、视频,以及编码格式 // 一旦判断结束,该队列变成直进直出,不再有实际缓存 +// type Queue struct { maxMsgSize int data []base.RtmpMsg @@ -26,14 +29,14 @@ type Queue struct { } type IQueueObserver interface { - // 该回调一定发生在数据回调之前 + // OnPatPmt 该回调一定发生在数据回调之前 // TODO(chef) 这里可以考虑换成只通知drain,由上层完成FragmentHeader的组装逻辑 OnPatPmt(b []byte) OnPop(msg base.RtmpMsg) } -// @param maxMsgSize 最大缓存多少个包 +// NewQueue @param maxMsgSize 最大缓存多少个包 func NewQueue(maxMsgSize int, observer IQueueObserver) *Queue { return &Queue{ maxMsgSize: maxMsgSize, @@ -45,7 +48,7 @@ func NewQueue(maxMsgSize int, observer IQueueObserver) *Queue { } } -// @param msg 函数调用结束后,内部不持有该内存块 +// Push @param msg 函数调用结束后,内部不持有该内存块 func (q *Queue) Push(msg base.RtmpMsg) { if q.done { q.observer.OnPop(msg) diff --git a/pkg/hls/server_handler.go b/pkg/hls/server_handler.go index 1409c30..bdf5c05 100644 --- a/pkg/hls/server_handler.go +++ b/pkg/hls/server_handler.go @@ -12,8 +12,6 @@ import ( "net/http" "github.com/q191201771/lal/pkg/base" - - "github.com/q191201771/naza/pkg/nazalog" ) type ServerHandler struct { @@ -29,14 +27,14 @@ func NewServerHandler(outPath string) *ServerHandler { func (s *ServerHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { urlCtx, err := base.ParseUrl(base.ParseHttpRequest(req), 80) if err != nil { - nazalog.Errorf("parse url. err=%+v", err) + Log.Errorf("parse url. err=%+v", err) return } s.ServeHTTPWithUrlCtx(resp, urlCtx) } func (s *ServerHandler) ServeHTTPWithUrlCtx(resp http.ResponseWriter, urlCtx base.UrlContext) { - //nazalog.Debugf("%+v", req) + //Log.Debugf("%+v", req) // TODO chef: // - check appname in URI path @@ -45,17 +43,17 @@ func (s *ServerHandler) ServeHTTPWithUrlCtx(resp http.ResponseWriter, urlCtx bas filetype := urlCtx.GetFileType() ri := PathStrategy.GetRequestInfo(urlCtx, s.outPath) - //nazalog.Debugf("%+v", ri) + //Log.Debugf("%+v", ri) if filename == "" || (filetype != "m3u8" && filetype != "ts") || ri.StreamName == "" || ri.FileNameWithPath == "" { - nazalog.Warnf("invalid hls request. url=%+v, request=%+v", urlCtx, ri) + Log.Warnf("invalid hls request. url=%+v, request=%+v", urlCtx, ri) resp.WriteHeader(404) return } content, err := ReadFile(ri.FileNameWithPath) if err != nil { - nazalog.Warnf("read hls file failed. request=%+v, err=%+v", ri, err) + Log.Warnf("read hls file failed. request=%+v, err=%+v", ri, err) resp.WriteHeader(404) return } diff --git a/pkg/hls/streamer.go b/pkg/hls/streamer.go index 6e730ed..57a6ff6 100644 --- a/pkg/hls/streamer.go +++ b/pkg/hls/streamer.go @@ -18,23 +18,24 @@ import ( "github.com/q191201771/lal/pkg/mpegts" "github.com/q191201771/naza/pkg/bele" "github.com/q191201771/naza/pkg/nazabytes" - "github.com/q191201771/naza/pkg/nazalog" ) type StreamerObserver interface { - // @param b const只读内存块,上层可以持有,但是不允许修改 + // OnPatPmt @param b const只读内存块,上层可以持有,但是不允许修改 OnPatPmt(b []byte) + // OnFrame + // // @param streamer: 供上层获取streamer内部的一些状态,比如spspps是否已缓存,音频缓存队列是否有数据等 // - // @param frame: 各字段含义见mpegts.Frame结构体定义 + // @param frame: 各字段含义见 mpegts.Frame 结构体定义 // frame.CC 注意,回调结束后,Streamer会保存frame.CC,上层在TS打包完成后,可通过frame.CC将cc值传递给Streamer // frame.Raw 回调结束后,这块内存可能会被内部重复使用 // - OnFrame(streamer *Streamer, frame *mpegts.Frame) + OnFrame(streamer *Streamer, frame *mpegts.Frame, boundary bool) } -// 输入rtmp流,回调转封装成Annexb格式的流 +// Streamer 输入rtmp流,回调转封装成Annexb格式的流 type Streamer struct { UniqueKey string @@ -47,6 +48,8 @@ type Streamer struct { audioCacheFirstFramePts uint64 // audioCacheFrames中第一个音频帧的时间戳 TODO chef: rename to DTS audioCc uint8 videoCc uint8 + + opened bool } func NewStreamer(observer StreamerObserver) *Streamer { @@ -62,13 +65,15 @@ func NewStreamer(observer StreamerObserver) *Streamer { return streamer } -// @param msg msg.Payload 调用结束后,函数内部不会持有这块内存 +// FeedRtmpMessage @param msg msg.Payload 调用结束后,函数内部不会持有这块内存 // // TODO chef: 可以考虑数据有问题时,返回给上层,直接主动关闭输入流的连接 func (s *Streamer) FeedRtmpMessage(msg base.RtmpMsg) { s.calcFragmentHeaderQueue.Push(msg) } +// ----- implement IQueueObserver of Queue ----------------------------------------------------------------------------- + func (s *Streamer) OnPatPmt(b []byte) { s.observer.OnPatPmt(b) } @@ -82,6 +87,34 @@ func (s *Streamer) OnPop(msg base.RtmpMsg) { } } +// --------------------------------------------------------------------------------------------------------------------- + +// FlushAudio +// +// 吐出音频数据的三种情况: +// 1. 收到音频或视频时,音频缓存队列已达到一定长度 +// 2. 打开一个新的TS文件切片时 +// 3. 输入流关闭时 +// +func (s *Streamer) FlushAudio() { + if s.audioCacheFrames == nil { + return + } + + var frame mpegts.Frame + frame.Cc = s.audioCc + frame.Dts = s.audioCacheFirstFramePts + frame.Pts = s.audioCacheFirstFramePts + frame.Key = false + frame.Raw = s.audioCacheFrames + frame.Pid = mpegts.PidAudio + frame.Sid = mpegts.StreamIdAudio + s.onFrame(&frame) + s.audioCc = frame.Cc + + s.audioCacheFrames = nil +} + func (s *Streamer) AudioSeqHeaderCached() bool { return s.ascCtx != nil } @@ -94,12 +127,14 @@ func (s *Streamer) AudioCacheEmpty() bool { return s.audioCacheFrames == nil } +// ----- private ------------------------------------------------------------------------------------------------------- + func (s *Streamer) feedVideo(msg base.RtmpMsg) { // 注意,有一种情况是msg.Payload为 27 02 00 00 00 // 此时打印错误并返回也不影响 // if len(msg.Payload) <= 5 { - nazalog.Errorf("[%s] invalid video message length. header=%+v, payload=%s", s.UniqueKey, msg.Header, hex.Dump(msg.Payload)) + Log.Errorf("[%s] invalid video message length. header=%+v, payload=%s", s.UniqueKey, msg.Header, hex.Dump(msg.Payload)) return } @@ -114,12 +149,12 @@ func (s *Streamer) feedVideo(msg base.RtmpMsg) { var err error if msg.IsAvcKeySeqHeader() { if s.spspps, err = avc.SpsPpsSeqHeader2Annexb(msg.Payload); err != nil { - nazalog.Errorf("[%s] cache spspps failed. err=%+v", s.UniqueKey, err) + Log.Errorf("[%s] cache spspps failed. err=%+v", s.UniqueKey, err) } return } else if msg.IsHevcKeySeqHeader() { if s.spspps, err = hevc.VpsSpsPpsSeqHeader2Annexb(msg.Payload); err != nil { - nazalog.Errorf("[%s] cache vpsspspps failed. err=%+v", s.UniqueKey, err) + Log.Errorf("[%s] cache vpsspspps failed. err=%+v", s.UniqueKey, err) } return } @@ -134,7 +169,7 @@ func (s *Streamer) feedVideo(msg base.RtmpMsg) { // msg中可能有多个NALU,逐个获取 nals, err := avc.SplitNaluAvcc(msg.Payload[5:]) if err != nil { - nazalog.Errorf("[%s] iterate nalu failed. err=%+v, header=%+v, payload=%s", err, s.UniqueKey, msg.Header, hex.Dump(nazabytes.Prefix(msg.Payload, 32))) + Log.Errorf("[%s] iterate nalu failed. err=%+v, header=%+v, payload=%s", err, s.UniqueKey, msg.Header, hex.Dump(nazabytes.Prefix(msg.Payload, 32))) return } for _, nal := range nals { @@ -146,7 +181,7 @@ func (s *Streamer) feedVideo(msg base.RtmpMsg) { nalType = hevc.ParseNaluType(nal[0]) } - //nazalog.Debugf("[%s] naltype=%d, len=%d(%d), cts=%d, key=%t.", s.UniqueKey, nalType, nalBytes, len(msg.Payload), cts, msg.IsVideoKeyNalu()) + //Log.Debugf("[%s] naltype=%d, len=%d(%d), cts=%d, key=%t.", s.UniqueKey, nalType, nalBytes, len(msg.Payload), cts, msg.IsVideoKeyNalu()) // 过滤掉原流中的sps pps aud // sps pps前面已经缓存过了,后面有自己的写入逻辑 @@ -176,7 +211,7 @@ func (s *Streamer) feedVideo(msg base.RtmpMsg) { case avc.NaluTypeIdrSlice: if !spsppsSent { if out, err = s.appendSpsPps(out); err != nil { - nazalog.Warnf("[%s] append spspps by not exist.", s.UniqueKey) + Log.Warnf("[%s] append spspps by not exist.", s.UniqueKey) return } } @@ -190,7 +225,7 @@ func (s *Streamer) feedVideo(msg base.RtmpMsg) { case hevc.NaluTypeSliceIdr, hevc.NaluTypeSliceIdrNlp, hevc.NaluTypeSliceCranut: if !spsppsSent { if out, err = s.appendSpsPps(out); err != nil { - nazalog.Warnf("[%s] append spspps by not exist.", s.UniqueKey) + Log.Warnf("[%s] append spspps by not exist.", s.UniqueKey) return } } @@ -227,30 +262,30 @@ func (s *Streamer) feedVideo(msg base.RtmpMsg) { frame.Pid = mpegts.PidVideo frame.Sid = mpegts.StreamIdVideo - s.observer.OnFrame(s, &frame) + s.onFrame(&frame) s.videoCc = frame.Cc } func (s *Streamer) feedAudio(msg base.RtmpMsg) { if len(msg.Payload) < 3 { - nazalog.Errorf("[%s] invalid audio message length. len=%d", s.UniqueKey, len(msg.Payload)) + Log.Errorf("[%s] invalid audio message length. len=%d", s.UniqueKey, len(msg.Payload)) return } if msg.Payload[0]>>4 != base.RtmpSoundFormatAac { return } - //nazalog.Debugf("[%s] hls: feedAudio. dts=%d len=%d", s.UniqueKey, msg.Header.TimestampAbs, len(msg.Payload)) + //Log.Debugf("[%s] hls: feedAudio. dts=%d len=%d", s.UniqueKey, msg.Header.TimestampAbs, len(msg.Payload)) if msg.Payload[1] == base.RtmpAacPacketTypeSeqHeader { if err := s.cacheAacSeqHeader(msg); err != nil { - nazalog.Errorf("[%s] cache aac seq header failed. err=%+v", s.UniqueKey, err) + Log.Errorf("[%s] cache aac seq header failed. err=%+v", s.UniqueKey, err) } return } if !s.AudioSeqHeaderCached() { - nazalog.Warnf("[%s] feed audio message but aac seq header not exist.", s.UniqueKey) + Log.Warnf("[%s] feed audio message but aac seq header not exist.", s.UniqueKey) return } @@ -269,29 +304,6 @@ func (s *Streamer) feedAudio(msg base.RtmpMsg) { s.audioCacheFrames = append(s.audioCacheFrames, msg.Payload[2:]...) } -// 吐出音频数据的三种情况: -// 1. 收到音频或视频时,音频缓存队列已达到一定长度 -// 2. 打开一个新的TS文件切片时 -// 3. 输入流关闭时 -func (s *Streamer) FlushAudio() { - if s.audioCacheFrames == nil { - return - } - - var frame mpegts.Frame - frame.Cc = s.audioCc - frame.Dts = s.audioCacheFirstFramePts - frame.Pts = s.audioCacheFirstFramePts - frame.Key = false - frame.Raw = s.audioCacheFrames - frame.Pid = mpegts.PidAudio - frame.Sid = mpegts.StreamIdAudio - s.observer.OnFrame(s, &frame) - s.audioCc = frame.Cc - - s.audioCacheFrames = nil -} - func (s *Streamer) cacheAacSeqHeader(msg base.RtmpMsg) error { var err error s.ascCtx, err = aac.NewAscContext(msg.Payload[2:]) @@ -306,3 +318,27 @@ func (s *Streamer) appendSpsPps(out []byte) ([]byte, error) { out = append(out, s.spspps...) return out, nil } + +func (s *Streamer) onFrame(frame *mpegts.Frame) { + var boundary bool + + if frame.Sid == mpegts.StreamIdAudio { + // 为了考虑没有视频的情况也能切片,所以这里判断spspps为空时,也建议生成fragment + boundary = !s.VideoSeqHeaderCached() + } else { + // 收到视频,可能触发建立fragment的条件是: + // 关键帧数据 && + // ( + // (没有收到过音频seq header) || 说明 只有视频 + // (收到过音频seq header && fragment没有打开) || 说明 音视频都有,且都已ready + // (收到过音频seq header && fragment已经打开 && 音频缓存数据不为空) 说明 为什么音频缓存需不为空? + // ) + boundary = frame.Key && (!s.AudioSeqHeaderCached() || !s.opened || !s.AudioCacheEmpty()) + } + + if boundary { + s.opened = true + } + + s.observer.OnFrame(s, frame, boundary) +} diff --git a/pkg/hls/var.go b/pkg/hls/var.go index ce5b146..55bd457 100644 --- a/pkg/hls/var.go +++ b/pkg/hls/var.go @@ -8,12 +8,17 @@ package hls -import "github.com/q191201771/naza/pkg/mock" +import ( + "github.com/q191201771/naza/pkg/mock" + "github.com/q191201771/naza/pkg/nazalog" +) var ( PathStrategy IPathStrategy = &DefaultPathStrategy{} Clock = mock.NewStdClock() + + Log = nazalog.GetGlobalLogger() ) var ( diff --git a/pkg/httpflv/bench_test.go b/pkg/httpflv/bench_test.go index c58f3c3..2c66f57 100644 --- a/pkg/httpflv/bench_test.go +++ b/pkg/httpflv/bench_test.go @@ -12,15 +12,13 @@ import ( "os" "testing" - "github.com/q191201771/naza/pkg/nazalog" - "github.com/q191201771/naza/pkg/assert" ) func BenchmarkFlvFileReader(b *testing.B) { const flvFile = "testdata/test.flv" if _, err := os.Lstat(flvFile); err != nil { - nazalog.Warnf("lstat %s error. err=%+v", flvFile, err) + Log.Warnf("lstat %s error. err=%+v", flvFile, err) return } @@ -38,13 +36,13 @@ func BenchmarkFlvFileReader(b *testing.B) { } r.Dispose() } - //nazalog.Debug(tmp) + //Log.Debug(tmp) } func BenchmarkCloneTag(b *testing.B) { const flvFile = "testdata/test.flv" if _, err := os.Lstat(flvFile); err != nil { - nazalog.Warnf("lstat %s error. err=%+v", flvFile, err) + Log.Warnf("lstat %s error. err=%+v", flvFile, err) return } diff --git a/pkg/httpflv/client_pull_session.go b/pkg/httpflv/client_pull_session.go index 5aeb507..4469844 100644 --- a/pkg/httpflv/client_pull_session.go +++ b/pkg/httpflv/client_pull_session.go @@ -22,7 +22,6 @@ import ( "github.com/q191201771/naza/pkg/nazahttp" "github.com/q191201771/naza/pkg/connection" - "github.com/q191201771/naza/pkg/nazalog" ) type PullSessionOption struct { @@ -65,11 +64,11 @@ func NewPullSession(modOptions ...ModPullSessionOption) *PullSession { uniqueKey: uk, option: option, } - nazalog.Infof("[%s] lifecycle new httpflv PullSession. session=%p", uk, s) + Log.Infof("[%s] lifecycle new httpflv PullSession. session=%p", uk, s) return s } -// @param tag: 底层保证回调上来的Raw数据长度是完整的(但是不会分析Raw内部的编码数据) +// OnReadFlvTag @param tag: 底层保证回调上来的Raw数据长度是完整的(但是不会分析Raw内部的编码数据) type OnReadFlvTag func(tag Tag) // Pull 阻塞直到和对端完成拉流前,握手部分的工作,或者发生错误 @@ -83,7 +82,7 @@ type OnReadFlvTag func(tag Tag) // @param onReadFlvTag 读取到 flv tag 数据时回调。回调结束后,PullSession 不会再使用这块 数据。 // func (session *PullSession) Pull(rawUrl string, onReadFlvTag OnReadFlvTag) error { - nazalog.Debugf("[%s] pull. url=%s", session.uniqueKey, rawUrl) + Log.Debugf("[%s] pull. url=%s", session.uniqueKey, rawUrl) var ( ctx context.Context @@ -116,32 +115,32 @@ func (session *PullSession) WaitChan() <-chan error { // --------------------------------------------------------------------------------------------------------------------- -// 文档请参考: interface ISessionUrlContext +// Url 文档请参考: interface ISessionUrlContext func (session *PullSession) Url() string { return session.urlCtx.Url } -// 文档请参考: interface ISessionUrlContext +// AppName 文档请参考: interface ISessionUrlContext func (session *PullSession) AppName() string { return session.urlCtx.PathWithoutLastItem } -// 文档请参考: interface ISessionUrlContext +// StreamName 文档请参考: interface ISessionUrlContext func (session *PullSession) StreamName() string { return session.urlCtx.LastItemOfPath } -// 文档请参考: interface ISessionUrlContext +// RawQuery 文档请参考: interface ISessionUrlContext func (session *PullSession) RawQuery() string { return session.urlCtx.RawQuery } -// 文档请参考: interface IObject +// UniqueKey 文档请参考: interface IObject func (session *PullSession) UniqueKey() string { return session.uniqueKey } -// 文档请参考: interface ISessionStat +// UpdateStat 文档请参考: interface ISessionStat func (session *PullSession) UpdateStat(intervalSec uint32) { currStat := session.conn.GetStat() rDiff := currStat.ReadBytesSum - session.prevConnStat.ReadBytesSum @@ -152,7 +151,7 @@ func (session *PullSession) UpdateStat(intervalSec uint32) { session.prevConnStat = currStat } -// 文档请参考: interface ISessionStat +// GetStat 文档请参考: interface ISessionStat func (session *PullSession) GetStat() base.StatSession { connStat := session.conn.GetStat() session.stat.ReadBytesSum = connStat.ReadBytesSum @@ -160,7 +159,7 @@ func (session *PullSession) GetStat() base.StatSession { return session.stat } -// 文档请参考: interface ISessionStat +// IsAlive 文档请参考: interface ISessionStat func (session *PullSession) IsAlive() (readAlive, writeAlive bool) { currStat := session.conn.GetStat() if session.staleStat == nil { @@ -201,13 +200,13 @@ func (session *PullSession) pullContext(ctx context.Context, rawUrl string, onRe if statusCode == "301" || statusCode == "302" { url = headers.Get("Location") if url == "" { - nazalog.Warnf("[%s] redirect but Location not found. headers=%+v", session.uniqueKey, headers) + Log.Warnf("[%s] redirect but Location not found. headers=%+v", session.uniqueKey, headers) errChan <- nil return } _ = session.conn.Close() - nazalog.Debugf("[%s] redirect to %s", session.uniqueKey, url) + Log.Debugf("[%s] redirect to %s", session.uniqueKey, url) continue } @@ -243,7 +242,7 @@ func (session *PullSession) connect(rawUrl string) (err error) { return } - nazalog.Debugf("[%s] > tcp connect. %s", session.uniqueKey, session.urlCtx.HostWithPort) + Log.Debugf("[%s] > tcp connect. %s", session.uniqueKey, session.urlCtx.HostWithPort) var conn net.Conn if session.urlCtx.Scheme == "https" { @@ -259,7 +258,7 @@ func (session *PullSession) connect(rawUrl string) (err error) { return err } - nazalog.Debugf("[%s] tcp connect succ. remote=%s", session.uniqueKey, conn.RemoteAddr().String()) + Log.Debugf("[%s] tcp connect succ. remote=%s", session.uniqueKey, conn.RemoteAddr().String()) session.conn = connection.New(conn, func(option *connection.Option) { option.ReadBufSize = readBufSize @@ -271,7 +270,7 @@ func (session *PullSession) connect(rawUrl string) (err error) { func (session *PullSession) writeHttpRequest() error { // # 发送 http GET 请求 - nazalog.Debugf("[%s] > W http request. GET %s", session.uniqueKey, session.urlCtx.PathWithRawQuery) + Log.Debugf("[%s] > W http request. GET %s", session.uniqueKey, session.urlCtx.PathWithRawQuery) req := fmt.Sprintf("GET %s HTTP/1.0\r\nUser-Agent: %s\r\nAccept: */*\r\nRange: byte=0-\r\nConnection: close\r\nHost: %s\r\nIcy-MetaData: 1\r\n\r\n", session.urlCtx.PathWithRawQuery, base.LalHttpflvPullSessionUa, session.urlCtx.StdHost) _, err := session.conn.Write([]byte(req)) @@ -288,7 +287,7 @@ func (session *PullSession) readHttpRespHeader() (statusCode string, headers htt return } - nazalog.Debugf("[%s] < R http response header. statusLine=%s", session.uniqueKey, statusLine) + Log.Debugf("[%s] < R http response header. statusLine=%s", session.uniqueKey, statusLine) return } @@ -298,7 +297,7 @@ func (session *PullSession) readFlvHeader() ([]byte, error) { if err != nil { return flvHeader, err } - nazalog.Debugf("[%s] < R http flv header.", session.uniqueKey) + Log.Debugf("[%s] < R http flv header.", session.uniqueKey) // TODO chef: check flv header's value return flvHeader, nil @@ -331,7 +330,7 @@ func (session *PullSession) runReadLoop(onReadFlvTag OnReadFlvTag) { func (session *PullSession) dispose(err error) error { var retErr error session.disposeOnce.Do(func() { - nazalog.Infof("[%s] lifecycle dispose httpflv PullSession. err=%+v", session.uniqueKey, err) + Log.Infof("[%s] lifecycle dispose httpflv PullSession. err=%+v", session.uniqueKey, err) if session.conn == nil { retErr = base.ErrSessionNotStarted return diff --git a/pkg/httpflv/flv_file_pump.go b/pkg/httpflv/flv_file_pump.go index 5eb71b1..35b2aea 100644 --- a/pkg/httpflv/flv_file_pump.go +++ b/pkg/httpflv/flv_file_pump.go @@ -12,8 +12,6 @@ import ( "time" "github.com/q191201771/naza/pkg/mock" - - "github.com/q191201771/naza/pkg/nazalog" ) var Clock = mock.NewStdClock() @@ -61,7 +59,7 @@ func (f *FlvFilePump) Pump(filename string, onFlvTag OnPumpFlvTag) error { return f.PumpWithTags(tags, onFlvTag) } -// @return error 暂时只做预留,目前只会返回nil +// PumpWithTags @return error 暂时只做预留,目前只会返回nil // func (f *FlvFilePump) PumpWithTags(tags []Tag, onFlvTag OnPumpFlvTag) error { var totalBaseTs uint32 // 整体的基础时间戳。每轮最后更新 @@ -79,7 +77,7 @@ func (f *FlvFilePump) PumpWithTags(tags []Tag, onFlvTag OnPumpFlvTag) error { // 循环一次,代表遍历文件一次 for roundIndex := 0; ; roundIndex++ { - nazalog.Debugf("new round. index=%d", roundIndex) + Log.Debugf("new round. index=%d", roundIndex) hasReadThisBaseTs = false diff --git a/pkg/httpflv/httpflv_test.go b/pkg/httpflv/httpflv_test.go index 4fd0f53..adc497e 100644 --- a/pkg/httpflv/httpflv_test.go +++ b/pkg/httpflv/httpflv_test.go @@ -13,8 +13,6 @@ import ( "os" "testing" - "github.com/q191201771/naza/pkg/nazalog" - "github.com/q191201771/lal/pkg/httpflv" "github.com/q191201771/naza/pkg/assert" "github.com/q191201771/naza/pkg/mock" @@ -30,7 +28,7 @@ func TestHttpflv(t *testing.T) { func TestFlvFilePump(t *testing.T) { const flvFile = "../../testdata/test.flv" if _, err := os.Lstat(flvFile); err != nil { - nazalog.Warnf("lstat %s error. err=%+v", flvFile, err) + httpflv.Log.Warnf("lstat %s error. err=%+v", flvFile, err) return } diff --git a/pkg/httpflv/server_sub_session.go b/pkg/httpflv/server_sub_session.go index 682b963..33c8661 100644 --- a/pkg/httpflv/server_sub_session.go +++ b/pkg/httpflv/server_sub_session.go @@ -14,8 +14,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/naza/pkg/connection" - - "github.com/q191201771/naza/pkg/nazalog" ) var flvHttpResponseHeader []byte @@ -44,7 +42,7 @@ func NewSubSession(conn net.Conn, urlCtx base.UrlContext, isWebSocket bool, webs IsFresh: true, ShouldWaitVideoKeyFrame: true, } - nazalog.Infof("[%s] lifecycle new httpflv SubSession. session=%p, remote addr=%s", uk, s, conn.RemoteAddr().String()) + Log.Infof("[%s] lifecycle new httpflv SubSession. session=%p, remote addr=%s", uk, s, conn.RemoteAddr().String()) return s } @@ -57,19 +55,19 @@ func (session *SubSession) RunLoop() error { } func (session *SubSession) Dispose() error { - nazalog.Infof("[%s] lifecycle dispose httpflv SubSession.", session.core.UniqueKey()) + Log.Infof("[%s] lifecycle dispose httpflv SubSession.", session.core.UniqueKey()) return session.core.Dispose() } // --------------------------------------------------------------------------------------------------------------------- func (session *SubSession) WriteHttpResponseHeader() { - nazalog.Debugf("[%s] > W http response header.", session.core.UniqueKey()) + Log.Debugf("[%s] > W http response header.", session.core.UniqueKey()) session.core.WriteHttpResponseHeader(flvHttpResponseHeader) } func (session *SubSession) WriteFlvHeader() { - nazalog.Debugf("[%s] > W http flv header.", session.core.UniqueKey()) + Log.Debugf("[%s] > W http flv header.", session.core.UniqueKey()) session.core.Write(FlvHeader) } diff --git a/pkg/httpflv/tag.go b/pkg/httpflv/tag.go index b7c79e5..799c7cd 100644 --- a/pkg/httpflv/tag.go +++ b/pkg/httpflv/tag.go @@ -26,7 +26,7 @@ type Tag struct { Raw []byte // 结构为 (11字节的 tag header) + (body) + (4字节的 prev tag size) } -// 只包含数据部分,去除了前面11字节的tag header和后面4字节的prev tag size +// Payload 只包含数据部分,去除了前面11字节的tag header和后面4字节的prev tag size // func (tag *Tag) Payload() []byte { return tag.Raw[TagHeaderSize : len(tag.Raw)-PrevTagSizeFieldSize] @@ -52,7 +52,7 @@ func (tag *Tag) IsHevcKeySeqHeader() bool { return tag.Header.Type == TagTypeVideo && tag.Raw[TagHeaderSize] == HevcKeyFrame && tag.Raw[TagHeaderSize+1] == HevcPacketTypeSeqHeader } -// AVC或HEVC的seq header +// IsVideoKeySeqHeader AVC或HEVC的seq header func (tag *Tag) IsVideoKeySeqHeader() bool { return tag.IsAvcKeySeqHeader() || tag.IsHevcKeySeqHeader() } @@ -65,7 +65,7 @@ func (tag *Tag) IsHevcKeyNalu() bool { return tag.Header.Type == TagTypeVideo && tag.Raw[TagHeaderSize] == HevcKeyFrame && tag.Raw[TagHeaderSize+1] == HevcPacketTypeNalu } -// AVC或HEVC的关键帧 +// IsVideoKeyNalu AVC或HEVC的关键帧 func (tag *Tag) IsVideoKeyNalu() bool { return tag.IsAvcKeyNalu() || tag.IsHevcKeyNalu() } @@ -87,7 +87,7 @@ func (tag *Tag) ModTagTimestamp(timestamp uint32) { tag.Raw[7] = byte(timestamp >> 24) } -// 打包一个序列化后的 tag 二进制buffer,包含 tag header,body,prev tag size +// PackHttpflvTag 打包一个序列化后的 tag 二进制buffer,包含 tag header,body,prev tag size func PackHttpflvTag(t uint8, timestamp uint32, in []byte) []byte { out := make([]byte, TagHeaderSize+len(in)+PrevTagSizeFieldSize) out[0] = t diff --git a/pkg/httpflv/var.go b/pkg/httpflv/var.go index f6fa6ec..89f62f5 100644 --- a/pkg/httpflv/var.go +++ b/pkg/httpflv/var.go @@ -8,10 +8,14 @@ package httpflv +import "github.com/q191201771/naza/pkg/nazalog" + var ( SubSessionWriteChanSize = 1024 // SubSession发送数据时channel的大小 SubSessionWriteTimeoutMs = 10000 FlvHeader = []byte{0x46, 0x4c, 0x56, 0x01, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00} + + Log = nazalog.GetGlobalLogger() ) var readBufSize = 256 //16384 // ClientPullSession读取数据时 diff --git a/pkg/httpts/httpts_test.go b/pkg/httpts/httpts_test.go new file mode 100644 index 0000000..53ed4fd --- /dev/null +++ b/pkg/httpts/httpts_test.go @@ -0,0 +1,19 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package httpts_test + +import ( + "testing" + + "github.com/q191201771/lal/pkg/innertest" +) + +func TestHttpts(t *testing.T) { + innertest.Entry(t) +} diff --git a/pkg/httpts/server_sub_session.go b/pkg/httpts/server_sub_session.go index 129e981..891a1b1 100644 --- a/pkg/httpts/server_sub_session.go +++ b/pkg/httpts/server_sub_session.go @@ -13,7 +13,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/naza/pkg/connection" - "github.com/q191201771/naza/pkg/nazalog" ) var tsHttpResponseHeader []byte @@ -40,7 +39,7 @@ func NewSubSession(conn net.Conn, urlCtx base.UrlContext, isWebSocket bool, webs }), true, } - nazalog.Infof("[%s] lifecycle new httpts SubSession. session=%p, remote addr=%s", uk, s, conn.RemoteAddr().String()) + Log.Infof("[%s] lifecycle new httpts SubSession. session=%p, remote addr=%s", uk, s, conn.RemoteAddr().String()) return s } @@ -53,14 +52,14 @@ func (session *SubSession) RunLoop() error { } func (session *SubSession) Dispose() error { - nazalog.Infof("[%s] lifecycle dispose httpts SubSession.", session.core.UniqueKey()) + Log.Infof("[%s] lifecycle dispose httpts SubSession.", session.core.UniqueKey()) return session.core.Dispose() } // --------------------------------------------------------------------------------------------------------------------- func (session *SubSession) WriteHttpResponseHeader() { - nazalog.Debugf("[%s] > W http response header.", session.core.UniqueKey()) + Log.Debugf("[%s] > W http response header.", session.core.UniqueKey()) session.core.WriteHttpResponseHeader(tsHttpResponseHeader) } diff --git a/pkg/httpts/var.go b/pkg/httpts/var.go index ef88446..350b78d 100644 --- a/pkg/httpts/var.go +++ b/pkg/httpts/var.go @@ -8,7 +8,11 @@ package httpts +import "github.com/q191201771/naza/pkg/nazalog" + var ( SubSessionWriteChanSize = 1024 SubSessionWriteTimeoutMs = 10000 + + Log = nazalog.GetGlobalLogger() ) diff --git a/pkg/innertest/innertest.go b/pkg/innertest/innertest.go index 86b8312..a626dc9 100644 --- a/pkg/innertest/innertest.go +++ b/pkg/innertest/innertest.go @@ -17,6 +17,9 @@ import ( "testing" "time" + "github.com/q191201771/lal/pkg/httpts" + "github.com/q191201771/naza/pkg/filebatch" + "github.com/q191201771/lal/pkg/hls" "github.com/q191201771/naza/pkg/mock" @@ -30,7 +33,6 @@ import ( "github.com/q191201771/lal/pkg/base" - "github.com/q191201771/naza/pkg/filebatch" "github.com/q191201771/naza/pkg/nazamd5" "github.com/q191201771/lal/pkg/httpflv" @@ -38,7 +40,6 @@ import ( "github.com/q191201771/lal/pkg/rtmp" "github.com/q191201771/naza/pkg/assert" "github.com/q191201771/naza/pkg/nazaatomic" - "github.com/q191201771/naza/pkg/nazalog" ) // 开启了一个lalserver @@ -54,17 +55,27 @@ import ( var ( tt *testing.T - confFile = "../../testdata/lalserver.conf.json" - rFlvFileName = "../../testdata/test.flv" - wFlvPullFileName = "../../testdata/flvpull.flv" - wRtmpPullFileName = "../../testdata/rtmppull.flv" - wRtspPullFileName = "../../testdata/rtsppull.flv" + confFile = "../../testdata/lalserver.conf.json" + rFlvFileName = "../../testdata/test.flv" + wRtmpPullFileName = "../../testdata/rtmppull.flv" + wFlvPullFileName = "../../testdata/flvpull.flv" + wPlaylistM3u8FileName string + wRecordM3u8FileName string + wHlsTsFilePath string + //wRtspPullFileName = "../../testdata/rtsppull.flv" pushUrl string httpflvPullUrl string + httptsPullUrl string rtmpPullUrl string rtspPullUrl string + fileTagCount int + httpflvPullTagCount nazaatomic.Uint32 + rtmpPullTagCount nazaatomic.Uint32 + rtspSdpCtx sdp.LogicContext + rtspPullAvPacketCount nazaatomic.Uint32 + httpFlvWriter httpflv.FlvFileWriter rtmpWriter httpflv.FlvFileWriter @@ -72,12 +83,6 @@ var ( httpflvPullSession *httpflv.PullSession rtmpPullSession *rtmp.PullSession rtspPullSession *rtsp.PullSession - - fileTagCount int - httpflvPullTagCount nazaatomic.Uint32 - rtmpPullTagCount nazaatomic.Uint32 - rtspSdpCtx sdp.LogicContext - rtspPullAvPacketCount nazaatomic.Uint32 ) type RtspPullObserver struct { @@ -96,16 +101,17 @@ func (r RtspPullObserver) OnAvPacket(pkt base.AvPacket) { func Entry(t *testing.T) { if _, err := os.Lstat(confFile); err != nil { - nazalog.Warnf("lstat %s error. err=%+v", confFile, err) + Log.Warnf("lstat %s error. err=%+v", confFile, err) return } if _, err := os.Lstat(rFlvFileName); err != nil { - nazalog.Warnf("lstat %s error. err=%+v", rFlvFileName, err) + Log.Warnf("lstat %s error. err=%+v", rFlvFileName, err) return } hls.Clock = mock.NewFakeClock() hls.Clock.Set(time.Date(2022, 1, 16, 23, 24, 25, 0, time.Local)) + httpts.SubSessionWriteChanSize = 0 tt = t @@ -123,8 +129,12 @@ func Entry(t *testing.T) { pushUrl = fmt.Sprintf("rtmp://127.0.0.1%s/live/innertest", config.RtmpConfig.Addr) httpflvPullUrl = fmt.Sprintf("http://127.0.0.1%s/live/innertest.flv", config.HttpflvConfig.HttpListenAddr) + httptsPullUrl = fmt.Sprintf("http://127.0.0.1%s/live/innertest.ts", config.HttpflvConfig.HttpListenAddr) rtmpPullUrl = fmt.Sprintf("rtmp://127.0.0.1%s/live/innertest", config.RtmpConfig.Addr) rtspPullUrl = fmt.Sprintf("rtsp://127.0.0.1%s/live/innertest", config.RtspConfig.Addr) + wPlaylistM3u8FileName = fmt.Sprintf("%sinnertest/playlist.m3u8", config.HlsConfig.OutPath) + wRecordM3u8FileName = fmt.Sprintf("%sinnertest/record.m3u8", config.HlsConfig.OutPath) + wHlsTsFilePath = fmt.Sprintf("%sinnertest/", config.HlsConfig.OutPath) tags, err := httpflv.ReadAllTagsFromFlvFile(rFlvFileName) assert.Equal(t, nil, err) @@ -153,9 +163,9 @@ func Entry(t *testing.T) { assert.Equal(tt, nil, err) rtmpPullTagCount.Increment() }) - nazalog.Assert(nil, err) + Log.Assert(nil, err) err = <-rtmpPullSession.WaitChan() - nazalog.Debug(err) + Log.Debug(err) }() go func() { @@ -167,9 +177,17 @@ func Entry(t *testing.T) { assert.Equal(t, nil, err) httpflvPullTagCount.Increment() }) - nazalog.Assert(nil, err) + Log.Assert(nil, err) err = <-httpflvPullSession.WaitChan() - nazalog.Debug(err) + Log.Debug(err) + }() + + go func() { + //nazalog.Info("CHEFGREPME >") + b, err := httpGet(httptsPullUrl) + assert.Equal(t, 2216332, len(b)) + assert.Equal(t, "03f8eac7d2c3d5d85056c410f5fcc756", nazamd5.Md5(b)) + Log.Infof("CHEFGREPME %+v", err) }() time.Sleep(200 * time.Millisecond) @@ -184,7 +202,7 @@ func Entry(t *testing.T) { option.PullTimeoutMs = 500 }) err := rtspPullSession.Pull(rtspPullUrl) - nazalog.Debug(err) + Log.Debug(err) if rtspSdpCtx.RawSdp != nil { break } @@ -202,7 +220,7 @@ func Entry(t *testing.T) { for _, tag := range tags { assert.Equal(t, nil, err) chunks := remux.FlvTag2RtmpChunks(tag) - //nazalog.Debugf("rtmp push: %d", fileTagCount.Load()) + //Log.Debugf("rtmp push: %d", fileTagCount.Load()) err = pushSession.Write(chunks) assert.Equal(t, nil, err) } @@ -220,7 +238,7 @@ func Entry(t *testing.T) { time.Sleep(10 * time.Millisecond) } - nazalog.Debug("[innertest] start dispose.") + Log.Debug("[innertest] start dispose.") pushSession.Dispose() httpflvPullSession.Dispose() @@ -234,58 +252,60 @@ func Entry(t *testing.T) { //_ = syscall.Kill(syscall.Getpid(), syscall.SIGUSR1) sm.Dispose() - nazalog.Debugf("tag count. in=%d, out httpflv=%d, out rtmp=%d, out rtsp=%d", + Log.Debugf("tag count. in=%d, out httpflv=%d, out rtmp=%d, out rtsp=%d", fileTagCount, httpflvPullTagCount.Load(), rtmpPullTagCount.Load(), rtspPullAvPacketCount.Load()) compareFile() - - // 检查hls的m3u8文件 - playListM3u8, err := ioutil.ReadFile(fmt.Sprintf("%sinnertest/playlist.m3u8", config.HlsConfig.OutPath)) - assert.Equal(t, nil, err) - assert.Equal(t, goldenPlaylistM3u8, string(playListM3u8)) - recordM3u8, err := ioutil.ReadFile(fmt.Sprintf("%sinnertest/record.m3u8", config.HlsConfig.OutPath)) - assert.Equal(t, nil, err) - assert.Equal(t, []byte(goldenRecordM3u8), recordM3u8) - - // 检查hls的ts文件 - var allContent []byte - var fileNum int - err = filebatch.Walk( - fmt.Sprintf("%sinnertest", config.HlsConfig.OutPath), - false, - ".ts", - func(path string, info os.FileInfo, content []byte, err error) []byte { - allContent = append(allContent, content...) - fileNum++ - return nil - }) - assert.Equal(t, nil, err) - allContentMd5 := nazamd5.Md5(allContent) - assert.Equal(t, 8, fileNum) - assert.Equal(t, 2219152, len(allContent)) - assert.Equal(t, "48db6251d40c271fd11b05650f074e0f", allContentMd5) } func compareFile() { r, err := ioutil.ReadFile(rFlvFileName) assert.Equal(tt, nil, err) - nazalog.Debugf("%s filesize:%d", rFlvFileName, len(r)) + Log.Debugf("%s filesize:%d", rFlvFileName, len(r)) + // 检查httpflv w, err := ioutil.ReadFile(wFlvPullFileName) assert.Equal(tt, nil, err) - nazalog.Debugf("%s filesize:%d", wFlvPullFileName, len(w)) + Log.Debugf("%s filesize:%d", wFlvPullFileName, len(w)) res := bytes.Compare(r, w) assert.Equal(tt, 0, res) //err = os.Remove(wFlvPullFileName) assert.Equal(tt, nil, err) + // 检查rtmp w2, err := ioutil.ReadFile(wRtmpPullFileName) assert.Equal(tt, nil, err) - nazalog.Debugf("%s filesize:%d", wRtmpPullFileName, len(w2)) + Log.Debugf("%s filesize:%d", wRtmpPullFileName, len(w2)) res = bytes.Compare(r, w2) assert.Equal(tt, 0, res) //err = os.Remove(wRtmpPullFileName) assert.Equal(tt, nil, err) + + // 检查hls的m3u8文件 + playListM3u8, err := ioutil.ReadFile(wPlaylistM3u8FileName) + assert.Equal(tt, nil, err) + assert.Equal(tt, goldenPlaylistM3u8, string(playListM3u8)) + recordM3u8, err := ioutil.ReadFile(wRecordM3u8FileName) + assert.Equal(tt, nil, err) + assert.Equal(tt, []byte(goldenRecordM3u8), recordM3u8) + + // 检查hls的ts文件 + var allContent []byte + var fileNum int + err = filebatch.Walk( + wHlsTsFilePath, + false, + ".ts", + func(path string, info os.FileInfo, content []byte, err error) []byte { + allContent = append(allContent, content...) + fileNum++ + return nil + }) + assert.Equal(tt, nil, err) + allContentMd5 := nazamd5.Md5(allContent) + assert.Equal(tt, 8, fileNum) + assert.Equal(tt, 2219152, len(allContent)) + assert.Equal(tt, "48db6251d40c271fd11b05650f074e0f", allContentMd5) } func getAllHttpApi(addr string) { @@ -293,32 +313,34 @@ func getAllHttpApi(addr string) { var err error b, err = httpGet(fmt.Sprintf("http://%s/api/list", addr)) - nazalog.Assert(nil, err) - nazalog.Debugf("%s", string(b)) + Log.Assert(nil, err) + Log.Debugf("%s", string(b)) b, err = httpGet(fmt.Sprintf("http://%s/api/stat/lal_info", addr)) - nazalog.Assert(nil, err) - nazalog.Debugf("%s", string(b)) + Log.Assert(nil, err) + Log.Debugf("%s", string(b)) b, err = httpGet(fmt.Sprintf("http://%s/api/stat/group?stream_name=innertest", addr)) - nazalog.Assert(nil, err) - nazalog.Debugf("%s", string(b)) + Log.Assert(nil, err) + Log.Debugf("%s", string(b)) b, err = httpGet(fmt.Sprintf("http://%s/api/stat/all_group", addr)) - nazalog.Assert(nil, err) - nazalog.Debugf("%s", string(b)) + Log.Assert(nil, err) + Log.Debugf("%s", string(b)) var acspr base.ApiCtrlStartPullReq b, err = httpPost(fmt.Sprintf("http://%s/api/ctrl/start_pull", addr), &acspr) - nazalog.Assert(nil, err) - nazalog.Debugf("%s", string(b)) + Log.Assert(nil, err) + Log.Debugf("%s", string(b)) var ackos base.ApiCtrlKickOutSession b, err = httpPost(fmt.Sprintf("http://%s/api/ctrl/kick_out_session", addr), &ackos) - nazalog.Assert(nil, err) - nazalog.Debugf("%s", string(b)) + Log.Assert(nil, err) + Log.Debugf("%s", string(b)) } +// --------------------------------------------------------------------------------------------------------------------- + // TODO(chef): refactor 移入naza中 func httpGet(url string) ([]byte, error) { @@ -339,6 +361,8 @@ func httpPost(url string, info interface{}) ([]byte, error) { return ioutil.ReadAll(resp.Body) } +// --------------------------------------------------------------------------------------------------------------------- + var goldenPlaylistM3u8 = `#EXTM3U #EXT-X-VERSION:3 #EXT-X-ALLOW-CACHE:NO diff --git a/pkg/innertest/var.go b/pkg/innertest/var.go new file mode 100644 index 0000000..0caf35d --- /dev/null +++ b/pkg/innertest/var.go @@ -0,0 +1,13 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package innertest + +import "github.com/q191201771/naza/pkg/nazalog" + +var Log = nazalog.GetGlobalLogger() diff --git a/pkg/logic/config.go b/pkg/logic/config.go index 7fd5cd0..5335a1c 100644 --- a/pkg/logic/config.go +++ b/pkg/logic/config.go @@ -221,16 +221,16 @@ func LoadConfAndInitLog(confFile string) *Config { cacheLog = append(cacheLog, fmt.Sprintf("log.assert_behavior=%s", config.LogConfig.AssertBehavior.ReadableString())) } - if err := nazalog.Init(func(option *nazalog.Option) { + if err := Log.Init(func(option *nazalog.Option) { *option = config.LogConfig }); err != nil { _, _ = fmt.Fprintf(os.Stderr, "initial log failed. err=%+v\n", err) base.OsExitAndWaitPressIfWindows(1) } - nazalog.Info("initial log succ.") + Log.Info("initial log succ.") // 打印Logo - nazalog.Info(` + Log.Info(` __ ___ __ / / / | / / / / / /| | / / @@ -240,7 +240,7 @@ func LoadConfAndInitLog(confFile string) *Config { // 检查配置版本号是否匹配 if config.ConfVersion != ConfVersion { - nazalog.Warnf("config version invalid. conf version of lalserver=%s, conf version of config file=%s", + Log.Warnf("config version invalid. conf version of lalserver=%s, conf version of config file=%s", ConfVersion, config.ConfVersion) } @@ -253,15 +253,15 @@ func LoadConfAndInitLog(confFile string) *Config { "httpts.http_listen_addr", "httpts.https_listen_addr", "httpts.https_cert_file", "httpts.https_key_file", ) if err != nil { - nazalog.Warnf("config nazajson collect not exist fields failed. err=%+v", err) + Log.Warnf("config nazajson collect not exist fields failed. err=%+v", err) } if len(notExistFields) != 0 { - nazalog.Warnf("config some fields do not exist which have been set to the zero value. fields=%+v", notExistFields) + Log.Warnf("config some fields do not exist which have been set to the zero value. fields=%+v", notExistFields) } // 日志字段检查,缺失的字段,打印前面设置的默认值 if len(cacheLog) > 0 { - nazalog.Warnf("config some log fields do not exist which have been set to default value. %s", strings.Join(cacheLog, ", ")) + Log.Warnf("config some log fields do not exist which have been set to default value. %s", strings.Join(cacheLog, ", ")) } // 如果具体的HTTP应用没有设置HTTP监听相关的配置,则尝试使用全局配置 @@ -271,39 +271,39 @@ func LoadConfAndInitLog(confFile string) *Config { // 为缺失的字段中的一些特定字段,设置特定默认值 if config.HlsConfig.Enable && !j.Exist("hls.cleanup_mode") { - nazalog.Warnf("config hls.cleanup_mode not exist. set to default which is %d", defaultHlsCleanupMode) + Log.Warnf("config hls.cleanup_mode not exist. set to default which is %d", defaultHlsCleanupMode) config.HlsConfig.CleanupMode = defaultHlsCleanupMode } if config.HlsConfig.Enable && !j.Exist("hls.delete_threshold") { - nazalog.Warnf("config hls.delete_threshold not exist. set to default same as hls.fragment_num which is %d", + Log.Warnf("config hls.delete_threshold not exist. set to default same as hls.fragment_num which is %d", config.HlsConfig.FragmentNum) config.HlsConfig.DeleteThreshold = config.HlsConfig.FragmentNum } if (config.HttpflvConfig.Enable || config.HttpflvConfig.EnableHttps) && !j.Exist("httpflv.url_pattern") { - nazalog.Warnf("config httpflv.url_pattern not exist. set to default wchich is %s", defaultHttpflvUrlPattern) + Log.Warnf("config httpflv.url_pattern not exist. set to default wchich is %s", defaultHttpflvUrlPattern) config.HttpflvConfig.UrlPattern = defaultHttpflvUrlPattern } if (config.HttptsConfig.Enable || config.HttptsConfig.EnableHttps) && !j.Exist("httpts.url_pattern") { - nazalog.Warnf("config httpts.url_pattern not exist. set to default wchich is %s", defaultHttptsUrlPattern) + Log.Warnf("config httpts.url_pattern not exist. set to default wchich is %s", defaultHttptsUrlPattern) config.HttptsConfig.UrlPattern = defaultHttptsUrlPattern } if (config.HlsConfig.Enable || config.HlsConfig.EnableHttps) && !j.Exist("hls.url_pattern") { - nazalog.Warnf("config hls.url_pattern not exist. set to default wchich is %s", defaultHlsUrlPattern) + Log.Warnf("config hls.url_pattern not exist. set to default wchich is %s", defaultHlsUrlPattern) config.HttpflvConfig.UrlPattern = defaultHlsUrlPattern } // 对一些常见的格式错误做修复 // 确保url pattern以`/`开始,并以`/`结束 if urlPattern, changed := ensureStartAndEndWithSlash(config.HttpflvConfig.UrlPattern); changed { - nazalog.Warnf("fix config. httpflv.url_pattern %s -> %s", config.HttpflvConfig.UrlPattern, urlPattern) + Log.Warnf("fix config. httpflv.url_pattern %s -> %s", config.HttpflvConfig.UrlPattern, urlPattern) config.HttpflvConfig.UrlPattern = urlPattern } if urlPattern, changed := ensureStartAndEndWithSlash(config.HttptsConfig.UrlPattern); changed { - nazalog.Warnf("fix config. httpts.url_pattern %s -> %s", config.HttptsConfig.UrlPattern, urlPattern) + Log.Warnf("fix config. httpts.url_pattern %s -> %s", config.HttptsConfig.UrlPattern, urlPattern) config.HttpflvConfig.UrlPattern = urlPattern } if urlPattern, changed := ensureStartAndEndWithSlash(config.HlsConfig.UrlPattern); changed { - nazalog.Warnf("fix config. hls.url_pattern %s -> %s", config.HlsConfig.UrlPattern, urlPattern) + Log.Warnf("fix config. hls.url_pattern %s -> %s", config.HlsConfig.UrlPattern, urlPattern) config.HttpflvConfig.UrlPattern = urlPattern } @@ -318,7 +318,7 @@ func LoadConfAndInitLog(confFile string) *Config { tlines = append(tlines, strings.TrimSpace(l)) } compactRawContent := strings.Join(tlines, " ") - nazalog.Infof("load conf file succ. filename=%s, raw content=%s parsed=%+v", confFile, compactRawContent, config) + Log.Infof("load conf file succ. filename=%s, raw content=%s parsed=%+v", confFile, compactRawContent, config) return config } diff --git a/pkg/logic/group.go b/pkg/logic/group.go index 1fbfb00..5721b96 100644 --- a/pkg/logic/group.go +++ b/pkg/logic/group.go @@ -38,7 +38,6 @@ import ( "github.com/q191201771/lal/pkg/httpflv" "github.com/q191201771/lal/pkg/rtmp" - "github.com/q191201771/naza/pkg/nazalog" ) type GroupObserver interface { @@ -149,7 +148,7 @@ func NewGroup(appName string, streamName string, config *Config, observer GroupO if config.RtmpConfig.MergeWriteSize > 0 { g.rtmpMergeWriter = base.NewMergeWriter(g.writev2RtmpSubSessions, config.RtmpConfig.MergeWriteSize) } - nazalog.Infof("[%s] lifecycle new group. group=%p, appName=%s, streamName=%s", uk, g, appName, streamName) + Log.Infof("[%s] lifecycle new group. group=%p, appName=%s, streamName=%s", uk, g, appName, streamName) return g } @@ -158,7 +157,7 @@ func (group *Group) RunLoop() { <-group.exitChan } -// TODO chef: 传入时间 +// Tick TODO chef: 传入时间 // 目前每秒触发一次 func (group *Group) Tick() { group.mutex.Lock() @@ -176,14 +175,14 @@ func (group *Group) Tick() { if group.tickCount%checkSessionAliveIntervalSec == 0 { if group.rtmpPubSession != nil { if readAlive, _ := group.rtmpPubSession.IsAlive(); !readAlive { - nazalog.Warnf("[%s] session timeout. session=%s", group.UniqueKey, group.rtmpPubSession.UniqueKey()) + Log.Warnf("[%s] session timeout. session=%s", group.UniqueKey, group.rtmpPubSession.UniqueKey()) group.rtmpPubSession.Dispose() group.rtmp2RtspRemuxer = nil } } if group.rtspPubSession != nil { if readAlive, _ := group.rtspPubSession.IsAlive(); !readAlive { - nazalog.Warnf("[%s] session timeout. session=%s", group.UniqueKey, group.rtspPubSession.UniqueKey()) + Log.Warnf("[%s] session timeout. session=%s", group.UniqueKey, group.rtspPubSession.UniqueKey()) group.rtspPubSession.Dispose() group.rtspPubSession = nil group.rtsp2RtmpRemuxer = nil @@ -191,35 +190,35 @@ func (group *Group) Tick() { } if group.pullProxy.pullSession != nil { if readAlive, _ := group.pullProxy.pullSession.IsAlive(); !readAlive { - nazalog.Warnf("[%s] session timeout. session=%s", group.UniqueKey, group.pullProxy.pullSession.UniqueKey()) + Log.Warnf("[%s] session timeout. session=%s", group.UniqueKey, group.pullProxy.pullSession.UniqueKey()) group.pullProxy.pullSession.Dispose() group.delRtmpPullSession(group.pullProxy.pullSession) } } for session := range group.rtmpSubSessionSet { if _, writeAlive := session.IsAlive(); !writeAlive { - nazalog.Warnf("[%s] session timeout. session=%s", group.UniqueKey, session.UniqueKey()) + Log.Warnf("[%s] session timeout. session=%s", group.UniqueKey, session.UniqueKey()) session.Dispose() group.delRtmpSubSession(session) } } for session := range group.httpflvSubSessionSet { if _, writeAlive := session.IsAlive(); !writeAlive { - nazalog.Warnf("[%s] session timeout. session=%s", group.UniqueKey, session.UniqueKey()) + Log.Warnf("[%s] session timeout. session=%s", group.UniqueKey, session.UniqueKey()) session.Dispose() group.delHttpflvSubSession(session) } } for session := range group.httptsSubSessionSet { if _, writeAlive := session.IsAlive(); !writeAlive { - nazalog.Warnf("[%s] session timeout. session=%s", group.UniqueKey, session.UniqueKey()) + Log.Warnf("[%s] session timeout. session=%s", group.UniqueKey, session.UniqueKey()) session.Dispose() group.delHttptsSubSession(session) } } for session := range group.rtspSubSessionSet { if _, writeAlive := session.IsAlive(); !writeAlive { - nazalog.Warnf("[%s] session timeout. session=%s", group.UniqueKey, session.UniqueKey()) + Log.Warnf("[%s] session timeout. session=%s", group.UniqueKey, session.UniqueKey()) session.Dispose() group.delRtspSubSession(session) } @@ -254,12 +253,12 @@ func (group *Group) Tick() { group.tickCount++ } -// 主动释放所有资源。保证所有资源的生命周期逻辑上都在我们的控制中。降低出bug的几率,降低心智负担。 +// Dispose 主动释放所有资源。保证所有资源的生命周期逻辑上都在我们的控制中。降低出bug的几率,降低心智负担。 // 注意,Dispose后,不应再使用这个对象。 // 值得一提,如果是从其他协程回调回来的消息,在使用Group中的资源前,要判断资源是否存在以及可用。 // func (group *Group) Dispose() { - nazalog.Infof("[%s] lifecycle dispose group.", group.UniqueKey) + Log.Infof("[%s] lifecycle dispose group.", group.UniqueKey) group.exitChan <- struct{}{} group.mutex.Lock() @@ -306,14 +305,14 @@ func (group *Group) Dispose() { // --------------------------------------------------------------------------------------------------------------------- func (group *Group) AddRtmpPubSession(session *rtmp.ServerSession) error { - nazalog.Debugf("[%s] [%s] add PubSession into group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] add PubSession into group.", group.UniqueKey, session.UniqueKey()) group.mutex.Lock() defer group.mutex.Unlock() if group.hasInSession() { // TODO(chef): [refactor] 打印in session - nazalog.Errorf("[%s] in stream already exist at group. add=%s", group.UniqueKey, session.UniqueKey()) + Log.Errorf("[%s] in stream already exist at group. add=%s", group.UniqueKey, session.UniqueKey()) return base.ErrDupInStream } @@ -341,15 +340,15 @@ func (group *Group) AddRtmpPubSession(session *rtmp.ServerSession) error { return nil } -// TODO chef: rtsp package中,增加回调返回值判断,如果是false,将连接关掉 +// AddRtspPubSession TODO chef: rtsp package中,增加回调返回值判断,如果是false,将连接关掉 func (group *Group) AddRtspPubSession(session *rtsp.PubSession) error { - nazalog.Debugf("[%s] [%s] add RTSP PubSession into group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] add RTSP PubSession into group.", group.UniqueKey, session.UniqueKey()) group.mutex.Lock() defer group.mutex.Unlock() if group.hasInSession() { - nazalog.Errorf("[%s] in stream already exist at group. wanna add=%s", group.UniqueKey, session.UniqueKey()) + Log.Errorf("[%s] in stream already exist at group. wanna add=%s", group.UniqueKey, session.UniqueKey()) return base.ErrDupInStream } @@ -365,13 +364,13 @@ func (group *Group) AddRtspPubSession(session *rtsp.PubSession) error { } func (group *Group) AddRtmpPullSession(session *rtmp.PullSession) bool { - nazalog.Debugf("[%s] [%s] add PullSession into group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] add PullSession into group.", group.UniqueKey, session.UniqueKey()) group.mutex.Lock() defer group.mutex.Unlock() if group.hasInSession() { - nazalog.Errorf("[%s] in stream already exist. wanna add=%s", group.UniqueKey, session.UniqueKey()) + Log.Errorf("[%s] in stream already exist. wanna add=%s", group.UniqueKey, session.UniqueKey()) return false } @@ -404,7 +403,7 @@ func (group *Group) DelRtmpPullSession(session *rtmp.PullSession) { // --------------------------------------------------------------------------------------------------------------------- func (group *Group) AddRtmpSubSession(session *rtmp.ServerSession) { - nazalog.Debugf("[%s] [%s] add SubSession into group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] add SubSession into group.", group.UniqueKey, session.UniqueKey()) group.mutex.Lock() defer group.mutex.Unlock() group.rtmpSubSessionSet[session] = struct{}{} @@ -421,7 +420,7 @@ func (group *Group) AddRtmpSubSession(session *rtmp.ServerSession) { } func (group *Group) AddHttpflvSubSession(session *httpflv.SubSession) { - nazalog.Debugf("[%s] [%s] add httpflv SubSession into group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] add httpflv SubSession into group.", group.UniqueKey, session.UniqueKey()) session.WriteHttpResponseHeader() session.WriteFlvHeader() @@ -436,11 +435,11 @@ func (group *Group) AddHttpflvSubSession(session *httpflv.SubSession) { group.pullIfNeeded() } -// TODO chef: +// AddHttptsSubSession TODO chef: // 这里应该也要考虑触发hls muxer开启 // 也即HTTPTS sub需要使用hls muxer,hls muxer开启和关闭都要考虑HTTPTS sub func (group *Group) AddHttptsSubSession(session *httpts.SubSession) { - nazalog.Debugf("[%s] [%s] add httpts SubSession into group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] add httpts SubSession into group.", group.UniqueKey, session.UniqueKey()) session.WriteHttpResponseHeader() group.mutex.Lock() @@ -455,7 +454,7 @@ func (group *Group) HandleNewRtspSubSessionDescribe(session *rtsp.SubSession) (o defer group.mutex.Unlock() // TODO(chef): 应该有等待机制,而不是直接关闭 if group.sdpCtx == nil { - nazalog.Warnf("[%s] close rtsp subSession while describe but sdp not exist. [%s]", + Log.Warnf("[%s] close rtsp subSession while describe but sdp not exist. [%s]", group.UniqueKey, session.UniqueKey()) return false, nil } @@ -464,7 +463,7 @@ func (group *Group) HandleNewRtspSubSessionDescribe(session *rtsp.SubSession) (o } func (group *Group) HandleNewRtspSubSessionPlay(session *rtsp.SubSession) { - nazalog.Debugf("[%s] [%s] add rtsp SubSession into group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] add rtsp SubSession into group.", group.UniqueKey, session.UniqueKey()) group.mutex.Lock() defer group.mutex.Unlock() @@ -477,7 +476,7 @@ func (group *Group) HandleNewRtspSubSessionPlay(session *rtsp.SubSession) { } func (group *Group) AddRtmpPushSession(url string, session *rtmp.PushSession) { - nazalog.Debugf("[%s] [%s] add rtmp PushSession into group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] add rtmp PushSession into group.", group.UniqueKey, session.UniqueKey()) group.mutex.Lock() defer group.mutex.Unlock() if group.url2PushProxy != nil { @@ -504,14 +503,14 @@ func (group *Group) DelHttptsSubSession(session *httpts.SubSession) { } func (group *Group) DelRtspSubSession(session *rtsp.SubSession) { - nazalog.Debugf("[%s] [%s] del rtsp SubSession from group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] del rtsp SubSession from group.", group.UniqueKey, session.UniqueKey()) group.mutex.Lock() defer group.mutex.Unlock() delete(group.rtspSubSessionSet, session) } func (group *Group) DelRtmpPushSession(url string, session *rtmp.PushSession) { - nazalog.Debugf("[%s] [%s] del rtmp PushSession into group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] del rtmp PushSession into group.", group.UniqueKey, session.UniqueKey()) group.mutex.Lock() defer group.mutex.Unlock() if group.url2PushProxy != nil { @@ -607,7 +606,7 @@ func (group *Group) KickOutSession(sessionId string) bool { group.mutex.Lock() defer group.mutex.Unlock() - nazalog.Infof("[%s] kick out session. session id=%s", group.UniqueKey, sessionId) + Log.Infof("[%s] kick out session. session id=%s", group.UniqueKey, sessionId) if strings.HasPrefix(sessionId, base.UkPreRtmpServerSession) { if group.rtmpPubSession != nil { @@ -639,13 +638,13 @@ func (group *Group) KickOutSession(sessionId string) bool { } else if strings.HasPrefix(sessionId, base.UkPreRtspSubSession) { // TODO chef: impl me } else { - nazalog.Errorf("[%s] kick out session while session id format invalid. %s", group.UniqueKey, sessionId) + Log.Errorf("[%s] kick out session while session id format invalid. %s", group.UniqueKey, sessionId) } return false } -// 外部命令主动触发pull拉流 +// StartPull 外部命令主动触发pull拉流 // // 当前调用时机: // 1. 比如http api @@ -661,10 +660,10 @@ func (group *Group) StartPull(url string) { // --------------------------------------------------------------------------------------------------------------------- func (group *Group) delRtmpPubSession(session *rtmp.ServerSession) { - nazalog.Debugf("[%s] [%s] del rtmp PubSession from group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] del rtmp PubSession from group.", group.UniqueKey, session.UniqueKey()) if session != group.rtmpPubSession { - nazalog.Warnf("[%s] del rtmp pub session but not match. del session=%s, group session=%p", group.UniqueKey, session.UniqueKey(), group.rtmpPubSession) + Log.Warnf("[%s] del rtmp pub session but not match. del session=%s, group session=%p", group.UniqueKey, session.UniqueKey(), group.rtmpPubSession) return } @@ -675,10 +674,10 @@ func (group *Group) delRtmpPubSession(session *rtmp.ServerSession) { } func (group *Group) delRtspPubSession(session *rtsp.PubSession) { - nazalog.Debugf("[%s] [%s] del rtsp PubSession from group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] del rtsp PubSession from group.", group.UniqueKey, session.UniqueKey()) if session != group.rtspPubSession { - nazalog.Warnf("[%s] del rtmp pub session but not match. del session=%s, group session=%p", group.UniqueKey, session.UniqueKey(), group.rtmpPubSession) + Log.Warnf("[%s] del rtmp pub session but not match. del session=%s, group session=%p", group.UniqueKey, session.UniqueKey(), group.rtmpPubSession) return } @@ -689,7 +688,7 @@ func (group *Group) delRtspPubSession(session *rtsp.PubSession) { } func (group *Group) delRtmpPullSession(session *rtmp.PullSession) { - nazalog.Debugf("[%s] [%s] del rtmp PullSession from group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] del rtmp PullSession from group.", group.UniqueKey, session.UniqueKey()) group.pullProxy.pullSession = nil group.setPullingFlag(false) @@ -697,22 +696,22 @@ func (group *Group) delRtmpPullSession(session *rtmp.PullSession) { } func (group *Group) delRtmpSubSession(session *rtmp.ServerSession) { - nazalog.Debugf("[%s] [%s] del rtmp SubSession from group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] del rtmp SubSession from group.", group.UniqueKey, session.UniqueKey()) delete(group.rtmpSubSessionSet, session) } func (group *Group) delHttpflvSubSession(session *httpflv.SubSession) { - nazalog.Debugf("[%s] [%s] del httpflv SubSession from group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] del httpflv SubSession from group.", group.UniqueKey, session.UniqueKey()) delete(group.httpflvSubSessionSet, session) } func (group *Group) delHttptsSubSession(session *httpts.SubSession) { - nazalog.Debugf("[%s] [%s] del httpts SubSession from group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] del httpts SubSession from group.", group.UniqueKey, session.UniqueKey()) delete(group.httptsSubSessionSet, session) } func (group *Group) delRtspSubSession(session *rtsp.SubSession) { - nazalog.Debugf("[%s] [%s] del rtsp SubSession from group.", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] del rtsp SubSession from group.", group.UniqueKey, session.UniqueKey()) delete(group.rtspSubSessionSet, session) } @@ -744,7 +743,7 @@ func (group *Group) pushIfNeeded() { if urlParam != "" { urlWithParam += "?" + urlParam } - nazalog.Infof("[%s] start relay push. url=%s", group.UniqueKey, urlWithParam) + Log.Infof("[%s] start relay push. url=%s", group.UniqueKey, urlWithParam) go func(u, u2 string) { pushSession := rtmp.NewPushSession(func(option *rtmp.PushSessionOption) { @@ -753,13 +752,13 @@ func (group *Group) pushIfNeeded() { }) err := pushSession.Push(u2) if err != nil { - nazalog.Errorf("[%s] relay push done. err=%v", pushSession.UniqueKey(), err) + Log.Errorf("[%s] relay push done. err=%v", pushSession.UniqueKey(), err) group.DelRtmpPushSession(u, pushSession) return } group.AddRtmpPushSession(u, pushSession) err = <-pushSession.WaitChan() - nazalog.Infof("[%s] relay push done. err=%v", pushSession.UniqueKey(), err) + Log.Infof("[%s] relay push done. err=%v", pushSession.UniqueKey(), err) group.DelRtmpPushSession(u, pushSession) }(url, urlWithParam) } @@ -805,7 +804,7 @@ func (group *Group) addIn() { // 是否启动hls if group.config.HlsConfig.Enable { if group.hlsMuxer != nil { - nazalog.Errorf("[%s] hls muxer exist while addIn. muxer=%+v", group.UniqueKey, group.hlsMuxer) + Log.Errorf("[%s] hls muxer exist while addIn. muxer=%+v", group.UniqueKey, group.hlsMuxer) } enable := group.config.HlsConfig.Enable || group.config.HlsConfig.EnableHttps group.hlsMuxer = hls.NewMuxer(group.streamName, enable, &group.config.HlsConfig.MuxerConfig, group) @@ -824,20 +823,20 @@ func (group *Group) addIn() { filename := fmt.Sprintf("%s-%d.flv", group.streamName, now) filenameWithPath := filepath.Join(group.config.RecordConfig.FlvOutPath, filename) if group.recordFlv != nil { - nazalog.Errorf("[%s] record flv but already exist. new filename=%s, old filename=%s", + Log.Errorf("[%s] record flv but already exist. new filename=%s, old filename=%s", group.UniqueKey, filenameWithPath, group.recordFlv.Name()) if err := group.recordFlv.Dispose(); err != nil { - nazalog.Errorf("[%s] record flv dispose error. err=%+v", group.UniqueKey, err) + Log.Errorf("[%s] record flv dispose error. err=%+v", group.UniqueKey, err) } } group.recordFlv = &httpflv.FlvFileWriter{} if err := group.recordFlv.Open(filenameWithPath); err != nil { - nazalog.Errorf("[%s] record flv open file failed. filename=%s, err=%+v", + Log.Errorf("[%s] record flv open file failed. filename=%s, err=%+v", group.UniqueKey, filenameWithPath, err) group.recordFlv = nil } if err := group.recordFlv.WriteFlvHeader(); err != nil { - nazalog.Errorf("[%s] record flv write flv header failed. filename=%s, err=%+v", + Log.Errorf("[%s] record flv write flv header failed. filename=%s, err=%+v", group.UniqueKey, filenameWithPath, err) group.recordFlv = nil } @@ -848,15 +847,15 @@ func (group *Group) addIn() { filename := fmt.Sprintf("%s-%d.ts", group.streamName, now) filenameWithPath := filepath.Join(group.config.RecordConfig.MpegtsOutPath, filename) if group.recordMpegts != nil { - nazalog.Errorf("[%s] record mpegts but already exist. new filename=%s, old filename=%s", + Log.Errorf("[%s] record mpegts but already exist. new filename=%s, old filename=%s", group.UniqueKey, filenameWithPath, group.recordMpegts.Name()) if err := group.recordMpegts.Dispose(); err != nil { - nazalog.Errorf("[%s] record mpegts dispose error. err=%+v", group.UniqueKey, err) + Log.Errorf("[%s] record mpegts dispose error. err=%+v", group.UniqueKey, err) } } group.recordMpegts = &mpegts.FileWriter{} if err := group.recordMpegts.Create(filenameWithPath); err != nil { - nazalog.Errorf("[%s] record mpegts open file failed. filename=%s, err=%+v", + Log.Errorf("[%s] record mpegts open file failed. filename=%s, err=%+v", group.UniqueKey, filenameWithPath, err) group.recordFlv = nil } @@ -885,7 +884,7 @@ func (group *Group) delIn() { if group.config.RecordConfig.EnableFlv { if group.recordFlv != nil { if err := group.recordFlv.Dispose(); err != nil { - nazalog.Errorf("[%s] record flv dispose error. err=%+v", group.UniqueKey, err) + Log.Errorf("[%s] record flv dispose error. err=%+v", group.UniqueKey, err) } group.recordFlv = nil } @@ -895,7 +894,7 @@ func (group *Group) delIn() { if group.config.RecordConfig.EnableMpegts { if group.recordMpegts != nil { if err := group.recordMpegts.Dispose(); err != nil { - nazalog.Errorf("[%s] record mpegts dispose error. err=%+v", group.UniqueKey, err) + Log.Errorf("[%s] record mpegts dispose error. err=%+v", group.UniqueKey, err) } group.recordMpegts = nil } @@ -923,14 +922,14 @@ func (group *Group) disposeHlsMuxer() { // 音视频数据转发、转封装的逻辑 // --------------------------------------------------------------------------------------------------------------------- -// rtmp.PubSession or rtmp.PullSession +// OnReadRtmpAvMsg rtmp.PubSession or rtmp.PullSession func (group *Group) OnReadRtmpAvMsg(msg base.RtmpMsg) { group.mutex.Lock() defer group.mutex.Unlock() group.broadcastByRtmpMsg(msg) } -// rtsp.PubSession +// OnRtpPacket rtsp.PubSession func (group *Group) OnRtpPacket(pkt rtprtcp.RtpPacket) { group.mutex.Lock() defer group.mutex.Unlock() @@ -938,7 +937,7 @@ func (group *Group) OnRtpPacket(pkt rtprtcp.RtpPacket) { group.onRtpPacket(pkt) } -// rtsp.PubSession +// OnSdp rtsp.PubSession func (group *Group) OnSdp(sdpCtx sdp.LogicContext) { group.mutex.Lock() defer group.mutex.Unlock() @@ -947,27 +946,29 @@ func (group *Group) OnSdp(sdpCtx sdp.LogicContext) { group.rtsp2RtmpRemuxer.OnSdp(sdpCtx) } -// rtsp.PubSession +// OnAvPacket rtsp.PubSession func (group *Group) OnAvPacket(pkt base.AvPacket) { group.mutex.Lock() defer group.mutex.Unlock() - //nazalog.Debugf("[%s] > Group::OnAvPacket. type=%s, ts=%d, len=%d", group.UniqueKey, pkt.PayloadType.ReadableString(), pkt.Timestamp, len(pkt.Payload)) + //Log.Debugf("[%s] > Group::OnAvPacket. type=%s, ts=%d, len=%d", group.UniqueKey, pkt.PayloadType.ReadableString(), pkt.Timestamp, len(pkt.Payload)) group.rtsp2RtmpRemuxer.OnAvPacket(pkt) } -// hls.Muxer +// ----- implement hls.MuxerObserver of hls.Muxer ---------------------------------------------------------------------- + +// OnPatPmt hls.Muxer func (group *Group) OnPatPmt(b []byte) { group.patpmt = b if group.recordMpegts != nil { if err := group.recordMpegts.Write(b); err != nil { - nazalog.Errorf("[%s] record mpegts write fragment header error. err=%+v", group.UniqueKey, err) + Log.Errorf("[%s] record mpegts write fragment header error. err=%+v", group.UniqueKey, err) } } } -// hls.Muxer +// OnTsPackets hls.Muxer func (group *Group) OnTsPackets(rawFrame []byte, boundary bool) { // 因为最前面Feed时已经加锁了,所以这里回调上来就不用加锁了 @@ -985,11 +986,13 @@ func (group *Group) OnTsPackets(rawFrame []byte, boundary bool) { if group.recordMpegts != nil { if err := group.recordMpegts.Write(rawFrame); err != nil { - nazalog.Errorf("[%s] record mpegts write error. err=%+v", group.UniqueKey, err) + Log.Errorf("[%s] record mpegts write error. err=%+v", group.UniqueKey, err) } } } +// --------------------------------------------------------------------------------------------------------------------- + // TODO chef: 目前相当于其他类型往rtmp.AVMsg转了,考虑统一往一个通用类型转 // // rtmp.PubSession, rtmp.PullSession, rtsp2rtmpRemuxer @@ -1003,7 +1006,7 @@ func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) { ) if len(msg.Payload) == 0 { - nazalog.Warnf("[%s] msg payload length is 0. %+v", group.UniqueKey, msg.Header) + Log.Warnf("[%s] msg payload length is 0. %+v", group.UniqueKey, msg.Header) return } @@ -1020,7 +1023,7 @@ func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) { // # 设置好用于发送的 rtmp 头部信息 currHeader := remux.MakeDefaultRtmpHeader(msg.Header) if currHeader.MsgLen != uint32(len(msg.Payload)) { - nazalog.Errorf("[%s] diff. msgLen=%d, payload len=%d, %+v", group.UniqueKey, currHeader.MsgLen, len(msg.Payload), msg.Header) + Log.Errorf("[%s] diff. msgLen=%d, payload len=%d, %+v", group.UniqueKey, currHeader.MsgLen, len(msg.Payload), msg.Header) } // # 懒初始化rtmp chunk切片,以及httpflv转换 @@ -1033,15 +1036,15 @@ func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) { if session.IsFresh { // TODO chef: 头信息和full gop也可以在SubSession刚加入时发送 if group.rtmpGopCache.Metadata != nil { - nazalog.Debugf("[%s] [%s] write metadata", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] write metadata", group.UniqueKey, session.UniqueKey()) _ = session.Write(group.rtmpGopCache.Metadata) } if group.rtmpGopCache.VideoSeqHeader != nil { - nazalog.Debugf("[%s] [%s] write vsh", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] write vsh", group.UniqueKey, session.UniqueKey()) _ = session.Write(group.rtmpGopCache.VideoSeqHeader) } if group.rtmpGopCache.AacSeqHeader != nil { - nazalog.Debugf("[%s] [%s] write ash", group.UniqueKey, session.UniqueKey()) + Log.Debugf("[%s] [%s] write ash", group.UniqueKey, session.UniqueKey()) _ = session.Write(group.rtmpGopCache.AacSeqHeader) } gopCount := group.rtmpGopCache.GetGopCount() @@ -1049,7 +1052,7 @@ func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) { // GOP缓存中肯定包含了关键帧 session.ShouldWaitVideoKeyFrame = false - nazalog.Debugf("[%s] [%s] write gop cache. gop num=%d", group.UniqueKey, session.UniqueKey(), gopCount) + Log.Debugf("[%s] [%s] write gop cache. gop num=%d", group.UniqueKey, session.UniqueKey(), gopCount) } for i := 0; i < gopCount; i++ { for _, item := range group.rtmpGopCache.GetGopDataAt(i) { @@ -1157,7 +1160,7 @@ func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) { // # 录制flv文件 if group.recordFlv != nil { if err := group.recordFlv.WriteRaw(lrm2ft.Get()); err != nil { - nazalog.Errorf("[%s] record flv write error. err=%+v", group.UniqueKey, err) + Log.Errorf("[%s] record flv write error. err=%+v", group.UniqueKey, err) } } @@ -1317,7 +1320,7 @@ func (group *Group) pullIfNeeded() { } group.setPullingFlag(true) - nazalog.Infof("[%s] start relay pull. url=%s", group.UniqueKey, group.getPullUrl()) + Log.Infof("[%s] start relay pull. url=%s", group.UniqueKey, group.getPullUrl()) go func() { pullSession := rtmp.NewPullSession(func(option *rtmp.PullSessionOption) { @@ -1327,14 +1330,14 @@ func (group *Group) pullIfNeeded() { // TODO(chef): 处理数据回调,是否应该等待Add成功之后。避免竞态条件中途加入了其他in session err := pullSession.Pull(group.getPullUrl(), group.OnReadRtmpAvMsg) if err != nil { - nazalog.Errorf("[%s] relay pull fail. err=%v", pullSession.UniqueKey(), err) + Log.Errorf("[%s] relay pull fail. err=%v", pullSession.UniqueKey(), err) group.DelRtmpPullSession(pullSession) return } res := group.AddRtmpPullSession(pullSession) if res { err = <-pullSession.WaitChan() - nazalog.Infof("[%s] relay pull done. err=%v", pullSession.UniqueKey(), err) + Log.Infof("[%s] relay pull done. err=%v", pullSession.UniqueKey(), err) group.DelRtmpPullSession(pullSession) } else { pullSession.Dispose() @@ -1350,7 +1353,7 @@ func (group *Group) pullIfNeeded() { func (group *Group) stopPullIfNeeded() { // 没有输出型的流了 if group.pullProxy.pullSession != nil && !group.hasOutSession() { - nazalog.Infof("[%s] stop pull since no sub session.", group.UniqueKey) + Log.Infof("[%s] stop pull since no sub session.", group.UniqueKey) group.pullProxy.pullSession.Dispose() } } diff --git a/pkg/logic/http_api.go b/pkg/logic/http_api.go index a4d0905..3d398ef 100644 --- a/pkg/logic/http_api.go +++ b/pkg/logic/http_api.go @@ -16,7 +16,6 @@ import ( "github.com/q191201771/naza/pkg/nazahttp" "github.com/q191201771/lal/pkg/base" - "github.com/q191201771/naza/pkg/nazalog" ) type HttpApiServer struct { @@ -37,7 +36,7 @@ func (h *HttpApiServer) Listen() (err error) { if h.ln, err = net.Listen("tcp", h.addr); err != nil { return } - nazalog.Infof("start httpapi server listen. addr=%s", h.addr) + Log.Infof("start httpapi server listen. addr=%s", h.addr) return } @@ -106,13 +105,13 @@ func (h *HttpApiServer) ctrlStartPullHandler(w http.ResponseWriter, req *http.Re err := nazahttp.UnmarshalRequestJsonBody(req, &info, "protocol", "addr", "app_name", "stream_name") if err != nil { - nazalog.Warnf("http api start pull error. err=%+v", err) + Log.Warnf("http api start pull error. err=%+v", err) v.ErrorCode = base.ErrorCodeParamMissing v.Desp = base.DespParamMissing feedback(v, w) return } - nazalog.Infof("http api start pull. req info=%+v", info) + Log.Infof("http api start pull. req info=%+v", info) h.sm.CtrlStartPull(info) v.ErrorCode = base.ErrorCodeSucc @@ -127,13 +126,13 @@ func (h *HttpApiServer) ctrlKickOutSessionHandler(w http.ResponseWriter, req *ht err := nazahttp.UnmarshalRequestJsonBody(req, &info, "stream_name", "session_id") if err != nil { - nazalog.Warnf("http api kick out session error. err=%+v", err) + Log.Warnf("http api kick out session error. err=%+v", err) v.ErrorCode = base.ErrorCodeParamMissing v.Desp = base.DespParamMissing feedback(v, w) return } - nazalog.Infof("http api kick out session. req info=%+v", info) + Log.Infof("http api kick out session. req info=%+v", info) resp := h.sm.CtrlKickOutSession(info) feedback(resp, w) diff --git a/pkg/logic/http_api_test.go b/pkg/logic/http_api_test.go index c4159e8..a1e723a 100644 --- a/pkg/logic/http_api_test.go +++ b/pkg/logic/http_api_test.go @@ -15,9 +15,9 @@ import ( func TestHttpApiServer(t *testing.T) { //s := logic.NewHttpApiServer(":8083") //if err := s.Listen(); err != nil { - // nazalog.Error(err) + // Log.Error(err) // return //} //err := s.RunLoop() - //nazalog.Error(err) + //Log.Error(err) } diff --git a/pkg/logic/http_notify.go b/pkg/logic/http_notify.go index be27da7..e023ad7 100644 --- a/pkg/logic/http_notify.go +++ b/pkg/logic/http_notify.go @@ -14,7 +14,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/naza/pkg/nazahttp" - "github.com/q191201771/naza/pkg/nazalog" ) // TODO(chef): refactor 配置参数供外部传入 @@ -132,12 +131,12 @@ func (h *HttpNotify) asyncPost(url string, info interface{}) { case h.taskQueue <- PostTask{url: url, info: info}: // noop default: - nazalog.Error("http notify queue full.") + Log.Error("http notify queue full.") } } func (h *HttpNotify) post(url string, info interface{}) { if _, err := nazahttp.PostJson(url, info, h.client); err != nil { - nazalog.Errorf("http notify post error. err=%+v", err) + Log.Errorf("http notify post error. err=%+v", err) } } diff --git a/pkg/logic/http_server_handler.go b/pkg/logic/http_server_handler.go index 4c5992b..f1a49ba 100644 --- a/pkg/logic/http_server_handler.go +++ b/pkg/logic/http_server_handler.go @@ -15,7 +15,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/httpflv" "github.com/q191201771/lal/pkg/httpts" - "github.com/q191201771/naza/pkg/nazalog" ) type HttpServerHandlerObserver interface { @@ -45,17 +44,17 @@ func NewHttpServerHandler(observer HttpServerHandlerObserver) *HttpServerHandler func (h *HttpServerHandler) ServeSubSession(writer http.ResponseWriter, req *http.Request) { urlCtx, err := base.ParseUrl(base.ParseHttpRequest(req), 80) if err != nil { - nazalog.Errorf("parse url. err=%+v", err) + Log.Errorf("parse url. err=%+v", err) return } conn, bio, err := writer.(http.Hijacker).Hijack() if err != nil { - nazalog.Errorf("hijack failed. err=%+v", err) + Log.Errorf("hijack failed. err=%+v", err) return } if bio.Reader.Buffered() != 0 || bio.Writer.Buffered() != 0 { - nazalog.Errorf("hijack but buffer not empty. rb=%d, wb=%d", bio.Reader.Buffered(), bio.Writer.Buffered()) + Log.Errorf("hijack but buffer not empty. rb=%d, wb=%d", bio.Reader.Buffered(), bio.Writer.Buffered()) } var ( @@ -69,28 +68,28 @@ func (h *HttpServerHandler) ServeSubSession(writer http.ResponseWriter, req *htt if strings.HasSuffix(urlCtx.LastItemOfPath, ".flv") { session := httpflv.NewSubSession(conn, urlCtx, isWebSocket, webSocketKey) - nazalog.Debugf("[%s] < read http request. url=%s", session.UniqueKey(), session.Url()) + Log.Debugf("[%s] < read http request. url=%s", session.UniqueKey(), session.Url()) if err = h.observer.OnNewHttpflvSubSession(session); err != nil { - nazalog.Infof("[%s] dispose by observer. err=%+v", session.UniqueKey(), err) + Log.Infof("[%s] dispose by observer. err=%+v", session.UniqueKey(), err) _ = session.Dispose() return } err = session.RunLoop() - nazalog.Debugf("[%s] httpflv sub session loop done. err=%v", session.UniqueKey(), err) + Log.Debugf("[%s] httpflv sub session loop done. err=%v", session.UniqueKey(), err) h.observer.OnDelHttpflvSubSession(session) return } if strings.HasSuffix(urlCtx.LastItemOfPath, ".ts") { session := httpts.NewSubSession(conn, urlCtx, isWebSocket, webSocketKey) - nazalog.Debugf("[%s] < read http request. url=%s", session.UniqueKey(), session.Url()) + Log.Debugf("[%s] < read http request. url=%s", session.UniqueKey(), session.Url()) if err = h.observer.OnNewHttptsSubSession(session); err != nil { - nazalog.Infof("[%s] dispose by observer. err=%+v", session.UniqueKey(), err) + Log.Infof("[%s] dispose by observer. err=%+v", session.UniqueKey(), err) _ = session.Dispose() return } err = session.RunLoop() - nazalog.Debugf("[%s] httpts sub session loop done. err=%v", session.UniqueKey(), err) + Log.Debugf("[%s] httpts sub session loop done. err=%v", session.UniqueKey(), err) h.observer.OnDelHttptsSubSession(session) return } diff --git a/pkg/logic/logic.go b/pkg/logic/logic.go index ebda95c..3804908 100644 --- a/pkg/logic/logic.go +++ b/pkg/logic/logic.go @@ -66,23 +66,3 @@ var defaultOption = Option{ } type ModOption func(option *Option) - -// --------------------------------------------------------------------------------------------------------------------- - -// 一些没有放入配置文件中,包级别的配置,暂时没有对外暴露 -// -var ( - relayPushTimeoutMs = 5000 - relayPushWriteAvTimeoutMs = 5000 - relayPullTimeoutMs = 5000 - relayPullReadAvTimeoutMs = 5000 - calcSessionStatIntervalSec uint32 = 5 - - // checkSessionAliveIntervalSec - // - // - 对于输入型session,检查一定时间内,是否没有收到数据 - // - 对于输出型session,检查一定时间内,是否没有发送数据 - // 注意,这里既检查socket发送阻塞,又检查上层没有给session喂数据 - // - checkSessionAliveIntervalSec uint32 = 10 -) diff --git a/pkg/logic/server_manager.go b/pkg/logic/server_manager.go index a509162..f45a3e3 100644 --- a/pkg/logic/server_manager.go +++ b/pkg/logic/server_manager.go @@ -31,7 +31,6 @@ import ( "github.com/q191201771/lal/pkg/httpflv" "github.com/q191201771/lal/pkg/rtmp" - "github.com/q191201771/naza/pkg/nazalog" //"github.com/felixge/fgprof" ) @@ -57,7 +56,7 @@ type ServerManager struct { func NewServerManager(confFile string, modOption ...ModOption) *ServerManager { sm := &ServerManager{ - serverStartTime: time.Now().Format("2006-01-02 15:04:05.999"), + serverStartTime: base.ReadableNowTime(), exitChan: make(chan struct{}, 1), } sm.groupManager = NewSimpleGroupManager(sm) @@ -66,16 +65,16 @@ func NewServerManager(confFile string, modOption ...ModOption) *ServerManager { base.LogoutStartInfo() if sm.config.HlsConfig.Enable && sm.config.HlsConfig.UseMemoryAsDiskFlag { - nazalog.Infof("hls use memory as disk.") + Log.Infof("hls use memory as disk.") hls.SetUseMemoryAsDiskFlag(true) } if sm.config.RecordConfig.EnableFlv { if err := os.MkdirAll(sm.config.RecordConfig.FlvOutPath, 0777); err != nil { - nazalog.Errorf("record flv mkdir error. path=%s, err=%+v", sm.config.RecordConfig.FlvOutPath, err) + Log.Errorf("record flv mkdir error. path=%s, err=%+v", sm.config.RecordConfig.FlvOutPath, err) } if err := os.MkdirAll(sm.config.RecordConfig.MpegtsOutPath, 0777); err != nil { - nazalog.Errorf("record mpegts mkdir error. path=%s, err=%+v", sm.config.RecordConfig.MpegtsOutPath, err) + Log.Errorf("record mpegts mkdir error. path=%s, err=%+v", sm.config.RecordConfig.MpegtsOutPath, err) } } @@ -132,10 +131,10 @@ func (sm *ServerManager) RunLoop() error { handler, ) if err != nil { - nazalog.Errorf("add http listen for %s failed. addr=%s, pattern=%s, err=%+v", name, config.HttpListenAddr, config.UrlPattern, err) + Log.Errorf("add http listen for %s failed. addr=%s, pattern=%s, err=%+v", name, config.HttpListenAddr, config.UrlPattern, err) return err } - nazalog.Infof("add http listen for %s. addr=%s, pattern=%s", name, config.HttpListenAddr, config.UrlPattern) + Log.Infof("add http listen for %s. addr=%s, pattern=%s", name, config.HttpListenAddr, config.UrlPattern) } if config.EnableHttps { err := sm.httpServerManager.AddListen( @@ -144,9 +143,9 @@ func (sm *ServerManager) RunLoop() error { handler, ) if err != nil { - nazalog.Errorf("add https listen for %s failed. addr=%s, pattern=%s, err=%+v", name, config.HttpsListenAddr, config.UrlPattern, err) + Log.Errorf("add https listen for %s failed. addr=%s, pattern=%s, err=%+v", name, config.HttpsListenAddr, config.UrlPattern, err) } else { - nazalog.Infof("add https listen for %s. addr=%s, pattern=%s", name, config.HttpsListenAddr, config.UrlPattern) + Log.Infof("add https listen for %s. addr=%s, pattern=%s", name, config.HttpsListenAddr, config.UrlPattern) } } return nil @@ -165,7 +164,7 @@ func (sm *ServerManager) RunLoop() error { if sm.httpServerManager != nil { go func() { if err := sm.httpServerManager.RunLoop(); err != nil { - nazalog.Error(err) + Log.Error(err) } }() } @@ -176,7 +175,7 @@ func (sm *ServerManager) RunLoop() error { } go func() { if err := sm.rtmpServer.RunLoop(); err != nil { - nazalog.Error(err) + Log.Error(err) } }() } @@ -187,7 +186,7 @@ func (sm *ServerManager) RunLoop() error { } go func() { if err := sm.rtspServer.RunLoop(); err != nil { - nazalog.Error(err) + Log.Error(err) } }() } @@ -198,7 +197,7 @@ func (sm *ServerManager) RunLoop() error { } go func() { if err := sm.httpApiServer.RunLoop(); err != nil { - nazalog.Error(err) + Log.Error(err) } }() } @@ -224,7 +223,7 @@ func (sm *ServerManager) RunLoop() error { // 关闭空闲的group sm.groupManager.Iterate(func(group *Group) bool { if group.IsTotalEmpty() { - nazalog.Infof("erase empty group. [%s]", group.UniqueKey) + Log.Infof("erase empty group. [%s]", group.UniqueKey) group.Dispose() return false } @@ -237,13 +236,13 @@ func (sm *ServerManager) RunLoop() error { if sm.config.DebugConfig.LogGroupIntervalSec > 0 && count%uint32(sm.config.DebugConfig.LogGroupIntervalSec) == 0 { groupNum := sm.groupManager.Len() - nazalog.Debugf("DEBUG_GROUP_LOG: group size=%d", groupNum) + Log.Debugf("DEBUG_GROUP_LOG: group size=%d", groupNum) if sm.config.DebugConfig.LogGroupMaxGroupNum > 0 { var loggedGroupCount int sm.groupManager.Iterate(func(group *Group) bool { loggedGroupCount++ if loggedGroupCount <= sm.config.DebugConfig.LogGroupMaxGroupNum { - nazalog.Debugf("DEBUG_GROUP_LOG: %d %s", loggedGroupCount, group.StringifyDebugStats(sm.config.DebugConfig.LogGroupMaxSubNumPerGroup)) + Log.Debugf("DEBUG_GROUP_LOG: %d %s", loggedGroupCount, group.StringifyDebugStats(sm.config.DebugConfig.LogGroupMaxSubNumPerGroup)) } return true }) @@ -265,7 +264,7 @@ func (sm *ServerManager) RunLoop() error { } func (sm *ServerManager) Dispose() { - nazalog.Debug("dispose server manager.") + Log.Debug("dispose server manager.") // TODO(chef) add httpServer @@ -324,7 +323,7 @@ func (sm *ServerManager) CtrlStartPull(info base.ApiCtrlStartPullReq) { defer sm.mutex.Unlock() g := sm.getGroup(info.AppName, info.StreamName) if g == nil { - nazalog.Warnf("group not exist, ignore start pull. streamName=%s", info.StreamName) + Log.Warnf("group not exist, ignore start pull. streamName=%s", info.StreamName) return } var url string @@ -738,14 +737,14 @@ func (sm *ServerManager) CleanupHlsIfNeeded(appName string, streamName string, p if g := sm.GetGroup(appName, streamName); g != nil { if g.IsHlsMuxerAlive() { - nazalog.Warnf("cancel cleanup hls file path since hls muxer still alive. streamName=%s", streamName) + Log.Warnf("cancel cleanup hls file path since hls muxer still alive. streamName=%s", streamName) return } } - nazalog.Infof("cleanup hls file path. streamName=%s, path=%s", streamName, outPath) + Log.Infof("cleanup hls file path. streamName=%s, path=%s", streamName, outPath) if err := hls.RemoveAll(outPath); err != nil { - nazalog.Warnf("cleanup hls file path error. path=%s, err=%+v", outPath, err) + Log.Warnf("cleanup hls file path error. path=%s, err=%+v", outPath, err) } }, appName, @@ -785,12 +784,12 @@ func (sm *ServerManager) getGroup(appName string, streamName string) *Group { func (sm *ServerManager) serveHls(writer http.ResponseWriter, req *http.Request) { urlCtx, err := base.ParseUrl(base.ParseHttpRequest(req), 80) if err != nil { - nazalog.Errorf("parse url. err=%+v", err) + Log.Errorf("parse url. err=%+v", err) return } if urlCtx.GetFileType() == "m3u8" { if err = sm.simpleAuthCtx.OnHls(urlCtx.GetFilenameWithoutType(), urlCtx.RawQuery); err != nil { - nazalog.Errorf("simple auth failed. err=%+v", err) + Log.Errorf("simple auth failed. err=%+v", err) return } } @@ -799,13 +798,13 @@ func (sm *ServerManager) serveHls(writer http.ResponseWriter, req *http.Request) } func runWebPprof(addr string) { - nazalog.Infof("start web pprof listen. addr=%s", addr) + Log.Infof("start web pprof listen. addr=%s", addr) - //nazalog.Warn("start fgprof.") + //Log.Warn("start fgprof.") //http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler()) if err := http.ListenAndServe(addr, nil); err != nil { - nazalog.Error(err) + Log.Error(err) return } } diff --git a/pkg/logic/var.go b/pkg/logic/var.go new file mode 100644 index 0000000..811dfae --- /dev/null +++ b/pkg/logic/var.go @@ -0,0 +1,29 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package logic + +import "github.com/q191201771/naza/pkg/nazalog" + +var Log = nazalog.GetGlobalLogger() + +var ( + relayPushTimeoutMs = 5000 + relayPushWriteAvTimeoutMs = 5000 + relayPullTimeoutMs = 5000 + relayPullReadAvTimeoutMs = 5000 + calcSessionStatIntervalSec uint32 = 5 + + // checkSessionAliveIntervalSec + // + // - 对于输入型session,检查一定时间内,是否没有收到数据 + // - 对于输出型session,检查一定时间内,是否没有发送数据 + // 注意,这里既检查socket发送阻塞,又检查上层没有给session喂数据 + // + checkSessionAliveIntervalSec uint32 = 10 +) diff --git a/pkg/mpegts/mpegts.go b/pkg/mpegts/mpegts.go index 13bfad8..9115fdf 100644 --- a/pkg/mpegts/mpegts.go +++ b/pkg/mpegts/mpegts.go @@ -10,7 +10,7 @@ package mpegts // MPEG: Moving Picture Experts Group -// 每个TS文件都以固定的PAT,PMT开始 +// FixedFragmentHeader 每个TS文件都以固定的PAT,PMT开始 var FixedFragmentHeader = []byte{ /* TS */ 0x47, 0x40, 0x00, 0x10, 0x00, @@ -70,7 +70,7 @@ var FixedFragmentHeader = []byte{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, } -// 每个TS文件都以固定的PAT,PMT开始 +// FixedFragmentHeaderHevc 每个TS文件都以固定的PAT,PMT开始 var FixedFragmentHeaderHevc = []byte{ /* TS */ 0x47, 0x40, 0x00, 0x10, 0x00, @@ -140,7 +140,7 @@ const ( PidVideo uint16 = 0x100 PidAudio uint16 = 0x101 - // ------------------------------------------ + // AdaptationFieldControlReserved ------------------------------------------ // // ------------------------------------------ AdaptationFieldControlReserved uint8 = 0 // Reserved for future use by ISO/IEC @@ -164,13 +164,13 @@ const ( // PES const ( - // ----------------------------------------------------------------- + // StreamIdAudio ----------------------------------------------------------------- //
// ----------------------------------------------------------------- StreamIdAudio uint8 = 192 // 110x xxxx 0xC0 StreamIdVideo uint8 = 224 // 1110 xxxx - // ------------------------------ + // PtsDtsFlags0 ------------------------------ // // ------------------------------ PtsDtsFlags0 uint8 = 0 // no PTS no DTS diff --git a/pkg/mpegts/mpegts_test.go b/pkg/mpegts/mpegts_test.go index 34a036b..cc0d178 100644 --- a/pkg/mpegts/mpegts_test.go +++ b/pkg/mpegts/mpegts_test.go @@ -14,7 +14,6 @@ import ( "github.com/q191201771/lal/pkg/innertest" "github.com/q191201771/lal/pkg/mpegts" - "github.com/q191201771/naza/pkg/nazalog" ) func TestMpegts(t *testing.T) { @@ -23,12 +22,12 @@ func TestMpegts(t *testing.T) { func TestParseFixedTsPacket(t *testing.T) { h := mpegts.ParseTsPacketHeader(mpegts.FixedFragmentHeader) - nazalog.Debugf("%+v", h) + mpegts.Log.Debugf("%+v", h) pat := mpegts.ParsePat(mpegts.FixedFragmentHeader[5:]) - nazalog.Debugf("%+v", pat) + mpegts.Log.Debugf("%+v", pat) h = mpegts.ParseTsPacketHeader(mpegts.FixedFragmentHeaderHevc[188:]) - nazalog.Debugf("%+v", h) + mpegts.Log.Debugf("%+v", h) pmt := mpegts.ParsePmt(mpegts.FixedFragmentHeader[188+5:]) - nazalog.Debugf("%+v", pmt) + mpegts.Log.Debugf("%+v", pmt) } diff --git a/pkg/mpegts/pack.go b/pkg/mpegts/pack.go index fe89f7d..fe8de3c 100644 --- a/pkg/mpegts/pack.go +++ b/pkg/mpegts/pack.go @@ -8,6 +8,8 @@ package mpegts +// Frame 帧数据 +// type Frame struct { Pts uint64 // =(毫秒 * 90) Dts uint64 @@ -32,11 +34,11 @@ type Frame struct { Raw []byte } -// @param packet: 188字节大小的TS包,注意,一次Pack对应的多个TSPacket,复用的是一块内存 +// OnTsPacket @param packet: 188字节大小的TS包,注意,一次Pack对应的多个TSPacket,复用的是一块内存 // type OnTsPacket func(packet []byte) -// Annexb格式的流转换为mpegts packet +// PackTsPacket Annexb格式的流转换为mpegts packet // // @param frame: 各字段含义见mpegts.Frame结构体定义 // frame.CC 注意,内部会修改frame.CC的值,外部在调用结束后,可保存CC的值,供下次调用时使用 @@ -49,6 +51,8 @@ func PackTsPacket(frame *Frame, onTsPacket OnTsPacket) { lpos := 0 // 当前帧的处理位置 rpos := len(frame.Raw) // 当前帧大小 first := true // 是否为帧的首个packet的标准 + + // TODO(chef): [perf] 由于上层并不需要区分单个packet,所以可以考虑预分配内存,存储整个packet流 packet := make([]byte, 188) for lpos != rpos { diff --git a/pkg/mpegts/pat.go b/pkg/mpegts/pat.go index d136910..466501a 100644 --- a/pkg/mpegts/pat.go +++ b/pkg/mpegts/pat.go @@ -12,7 +12,7 @@ import ( "github.com/q191201771/naza/pkg/nazabits" ) -// --------------------------------------------------------------------------------------------------- +// Pat --------------------------------------------------------------------------------------------------- // Program association section // <2.4.4.3> // table_id [8b] * diff --git a/pkg/mpegts/pes.go b/pkg/mpegts/pes.go index 75c9cfb..6bf6570 100644 --- a/pkg/mpegts/pes.go +++ b/pkg/mpegts/pes.go @@ -12,7 +12,7 @@ import ( "github.com/q191201771/naza/pkg/nazabits" ) -// ----------------------------------------------------------- +// Pes ----------------------------------------------------------- // // <2.4.3.6 PES packet> //
diff --git a/pkg/mpegts/pmt.go b/pkg/mpegts/pmt.go index f52fab6..004618d 100644 --- a/pkg/mpegts/pmt.go +++ b/pkg/mpegts/pmt.go @@ -10,10 +10,9 @@ package mpegts import ( "github.com/q191201771/naza/pkg/nazabits" - "github.com/q191201771/naza/pkg/nazalog" ) -// ---------------------------------------- +// Pmt ---------------------------------------- // Program Map Table // <2.4.4.8> // table_id [8b] * @@ -79,7 +78,7 @@ func ParsePmt(b []byte) (pmt Pmt) { _, _ = br.ReadBits8(4) pmt.pil, _ = br.ReadBits16(12) if pmt.pil != 0 { - nazalog.Warn(pmt.pil) + Log.Warn(pmt.pil) _, _ = br.ReadBytes(uint(pmt.pil)) } @@ -91,7 +90,7 @@ func ParsePmt(b []byte) (pmt Pmt) { _, _ = br.ReadBits8(4) ppe.Length, _ = br.ReadBits16(12) if ppe.Length != 0 { - nazalog.Warn(ppe.Length) + Log.Warn(ppe.Length) _, _ = br.ReadBits32(uint(ppe.Length)) } pmt.ProgramElements = append(pmt.ProgramElements, ppe) diff --git a/pkg/mpegts/ts_packet_header.go b/pkg/mpegts/ts_packet_header.go index 9e1162c..fc788f6 100644 --- a/pkg/mpegts/ts_packet_header.go +++ b/pkg/mpegts/ts_packet_header.go @@ -12,7 +12,7 @@ import ( "github.com/q191201771/naza/pkg/nazabits" ) -// ------------------------------------------------ +// TsPacketHeader ------------------------------------------------ // <2.4.3.2> // sync_byte [8b] * always 0x47 // transport_error_indicator [1b] @@ -34,7 +34,7 @@ type TsPacketHeader struct { Cc uint8 } -// ---------------------------------------------------------- +// TsPacketAdaptation ---------------------------------------------------------- //
// adaptation_field_length [8b] * 不包括自己这1字节 // discontinuity_indicator [1b] @@ -54,7 +54,7 @@ type TsPacketAdaptation struct { Length uint8 } -// 解析4字节TS Packet header +// ParseTsPacketHeader 解析4字节TS Packet header func ParseTsPacketHeader(b []byte) (h TsPacketHeader) { // TODO chef: 检查长度 br := nazabits.NewBitReader(b) @@ -69,7 +69,7 @@ func ParseTsPacketHeader(b []byte) (h TsPacketHeader) { return } -// TODO chef +// ParseTsPacketAdaptation TODO chef func ParseTsPacketAdaptation(b []byte) (f TsPacketAdaptation) { br := nazabits.NewBitReader(b) f.Length, _ = br.ReadBits8(8) diff --git a/pkg/mpegts/var.go b/pkg/mpegts/var.go new file mode 100644 index 0000000..e284efa --- /dev/null +++ b/pkg/mpegts/var.go @@ -0,0 +1,13 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package mpegts + +import "github.com/q191201771/naza/pkg/nazalog" + +var Log = nazalog.GetGlobalLogger() diff --git a/pkg/remux/avpacket2rtmp.go b/pkg/remux/avpacket2rtmp.go index 6c7e48c..93603e2 100644 --- a/pkg/remux/avpacket2rtmp.go +++ b/pkg/remux/avpacket2rtmp.go @@ -17,10 +17,9 @@ import ( "github.com/q191201771/lal/pkg/rtprtcp" "github.com/q191201771/lal/pkg/sdp" "github.com/q191201771/naza/pkg/bele" - "github.com/q191201771/naza/pkg/nazalog" ) -// AvPacket转换为RTMP +// AvPacket2RtmpRemuxer AvPacket转换为RTMP // 目前AvPacket来自RTSP的sdp以及rtp的合帧包。理论上也支持webrtc,后续接入webrtc时再验证 // type AvPacket2RtmpRemuxer struct { @@ -43,7 +42,7 @@ func NewAvPacket2RtmpRemuxer(onRtmpAvMsg rtmp.OnReadRtmpAvMsg) *AvPacket2RtmpRem } } -// 实现RTSP回调数据的三个接口,使得接入时方便些 +// OnRtpPacket 实现RTSP回调数据的三个接口,使得接入时方便些 func (r *AvPacket2RtmpRemuxer) OnRtpPacket(pkt rtprtcp.RtpPacket) { // noop } @@ -54,7 +53,7 @@ func (r *AvPacket2RtmpRemuxer) OnAvPacket(pkt base.AvPacket) { r.FeedAvPacket(pkt) } -// rtsp场景下,有时sps、pps等信息只包含在sdp中,有时包含在rtp包中, +// InitWithAvConfig rtsp场景下,有时sps、pps等信息只包含在sdp中,有时包含在rtp包中, // 这里提供输入sdp的sps、pps等信息的机会,如果没有,可以不调用 // // 内部不持有输入参数的内存块 @@ -76,14 +75,14 @@ func (r *AvPacket2RtmpRemuxer) InitWithAvConfig(asc, vps, sps, pps []byte) { } if r.audioType == base.AvPacketPtUnknown && r.videoType == base.AvPacketPtUnknown { - nazalog.Warn("has no audio or video") + Log.Warn("has no audio or video") return } if r.audioType != base.AvPacketPtUnknown { bAsh, err = aac.MakeAudioDataSeqHeaderWithAsc(asc) if err != nil { - nazalog.Errorf("build aac seq header failed. err=%+v", err) + Log.Errorf("build aac seq header failed. err=%+v", err) return } } @@ -92,13 +91,13 @@ func (r *AvPacket2RtmpRemuxer) InitWithAvConfig(asc, vps, sps, pps []byte) { if r.videoType == base.AvPacketPtHevc { bVsh, err = hevc.BuildSeqHeaderFromVpsSpsPps(vps, sps, pps) if err != nil { - nazalog.Errorf("build hevc seq header failed. err=%+v", err) + Log.Errorf("build hevc seq header failed. err=%+v", err) return } } else { bVsh, err = avc.BuildSeqHeaderFromSpsPps(sps, pps) if err != nil { - nazalog.Errorf("build avc seq header failed. err=%+v", err) + Log.Errorf("build avc seq header failed. err=%+v", err) return } } @@ -113,7 +112,7 @@ func (r *AvPacket2RtmpRemuxer) InitWithAvConfig(asc, vps, sps, pps []byte) { } } -// @param pkt: 内部不持有该内存块 +// FeedAvPacket @param pkt: 内部不持有该内存块 // func (r *AvPacket2RtmpRemuxer) FeedAvPacket(pkt base.AvPacket) { switch pkt.PayloadType { @@ -122,7 +121,7 @@ func (r *AvPacket2RtmpRemuxer) FeedAvPacket(pkt base.AvPacket) { case base.AvPacketPtHevc: nals, err := avc.SplitNaluAvcc(pkt.Payload) if err != nil { - nazalog.Errorf("iterate nalu failed. err=%+v", err) + Log.Errorf("iterate nalu failed. err=%+v", err) return } @@ -149,7 +148,7 @@ func (r *AvPacket2RtmpRemuxer) FeedAvPacket(pkt base.AvPacket) { bVsh, err := avc.BuildSeqHeaderFromSpsPps(r.sps, r.pps) if err != nil { - nazalog.Errorf("build avc seq header failed. err=%+v", err) + Log.Errorf("build avc seq header failed. err=%+v", err) continue } r.emitRtmpAvMsg(false, bVsh, pkt.Timestamp) @@ -182,7 +181,7 @@ func (r *AvPacket2RtmpRemuxer) FeedAvPacket(pkt base.AvPacket) { if len(r.vps) > 0 && len(r.sps) > 0 && len(r.pps) > 0 { bVsh, err := hevc.BuildSeqHeaderFromVpsSpsPps(r.vps, r.sps, r.pps) if err != nil { - nazalog.Errorf("build hevc seq header failed. err=%+v", err) + Log.Errorf("build hevc seq header failed. err=%+v", err) continue } r.emitRtmpAvMsg(false, bVsh, pkt.Timestamp) @@ -217,7 +216,7 @@ func (r *AvPacket2RtmpRemuxer) FeedAvPacket(pkt base.AvPacket) { copy(payload[2:], pkt.Payload) r.emitRtmpAvMsg(true, payload, pkt.Timestamp) default: - nazalog.Warnf("unsupported packet. type=%d", pkt.PayloadType) + Log.Warnf("unsupported packet. type=%d", pkt.PayloadType) } } @@ -237,7 +236,7 @@ func (r *AvPacket2RtmpRemuxer) emitRtmpAvMsg(isAudio bool, payload []byte, times } bMetadata, err := rtmp.BuildMetadata(-1, -1, audiocodecid, videocodecid) if err != nil { - nazalog.Errorf("build metadata failed. err=%+v", err) + Log.Errorf("build metadata failed. err=%+v", err) return } r.onRtmpAvMsg(base.RtmpMsg{ diff --git a/pkg/remux/avpacket2rtmp_test.go b/pkg/remux/avpacket2rtmp_test.go index ba134a0..cfd7bc6 100644 --- a/pkg/remux/avpacket2rtmp_test.go +++ b/pkg/remux/avpacket2rtmp_test.go @@ -14,7 +14,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/remux" - "github.com/q191201771/naza/pkg/nazalog" ) // #85 @@ -39,7 +38,7 @@ func TestCase1(t *testing.T) { } remuxer := remux.NewAvPacket2RtmpRemuxer(func(msg base.RtmpMsg) { - nazalog.Debugf("%+v", msg) + remux.Log.Debugf("%+v", msg) }) for _, p := range golden { remuxer.FeedAvPacket(p) @@ -78,7 +77,7 @@ func TestCase2(t *testing.T) { } remuxer := remux.NewAvPacket2RtmpRemuxer(func(msg base.RtmpMsg) { - nazalog.Debugf("%+v", msg) + remux.Log.Debugf("%+v", msg) }) for _, p := range golden { remuxer.FeedAvPacket(p) diff --git a/pkg/remux/dummy_audio_filter.go b/pkg/remux/dummy_audio_filter.go index 36cdcf2..60f8c21 100644 --- a/pkg/remux/dummy_audio_filter.go +++ b/pkg/remux/dummy_audio_filter.go @@ -13,7 +13,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/rtmp" - "github.com/q191201771/naza/pkg/nazalog" ) const ( @@ -103,7 +102,7 @@ func (filter *DummyAudioFilter) handleAnalysisStage(msg base.RtmpMsg) { } // 达到阈值 - nazalog.Debugf("[%s] start make dummy audio.", filter.uk) + Log.Debugf("[%s] start make dummy audio.", filter.uk) filter.stage = dummyAudioFilterStageDummy for i := range filter.earlyStageQueue { filter.handleDummyStage(filter.earlyStageQueue[i]) @@ -122,7 +121,7 @@ func (filter *DummyAudioFilter) handleNormalStage(msg base.RtmpMsg) { func (filter *DummyAudioFilter) handleDummyStage(msg base.RtmpMsg) { if msg.Header.MsgTypeId == base.RtmpTypeIdAudio { // 由于我们已经开始制造静音包了,静音包的编码参数可能会和实际音频参数不一致,所以我们只能过滤掉原始的音频数据了 - nazalog.Warnf("[%s] recv audio but we are making dummy audio.", filter.uk) + Log.Warnf("[%s] recv audio but we are making dummy audio.", filter.uk) return } diff --git a/pkg/remux/dummy_audio_filter_test.go b/pkg/remux/dummy_audio_filter_test.go index cf944a4..9c61ea5 100644 --- a/pkg/remux/dummy_audio_filter_test.go +++ b/pkg/remux/dummy_audio_filter_test.go @@ -17,7 +17,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/remux" "github.com/q191201771/naza/pkg/assert" - "github.com/q191201771/naza/pkg/nazalog" ) func TestDummyAudioFilter(t *testing.T) { @@ -116,7 +115,7 @@ func helperUnpackRtmpMsg(logstr string) base.RtmpMsg { } var fetchIntItemFn = func(str string, prefix string, suffix string) int { ret, err := strconv.Atoi(fetchItemFn(str, prefix, suffix)) - nazalog.Assert(nil, err) + remux.Log.Assert(nil, err) return ret } @@ -129,7 +128,7 @@ func helperUnpackRtmpMsg(logstr string) base.RtmpMsg { hexStr := fetchItemFn(logstr, "payload=", "") payload, err := hex.DecodeString(hexStr) - nazalog.Assert(nil, err) + remux.Log.Assert(nil, err) return base.RtmpMsg{ Header: header, diff --git a/pkg/remux/flv2rtmp.go b/pkg/remux/flv2rtmp.go index 730c388..8407511 100644 --- a/pkg/remux/flv2rtmp.go +++ b/pkg/remux/flv2rtmp.go @@ -30,7 +30,7 @@ func FlvTagHeader2RtmpHeader(in httpflv.TagHeader) (out base.RtmpHeader) { return } -// @return msg: 返回的内存块引用参数`tag`的内存块 +// FlvTag2RtmpMsg @return msg: 返回的内存块引用参数`tag`的内存块 // func FlvTag2RtmpMsg(tag httpflv.Tag) (msg base.RtmpMsg) { msg.Header = FlvTagHeader2RtmpHeader(tag.Header) @@ -38,7 +38,7 @@ func FlvTag2RtmpMsg(tag httpflv.Tag) (msg base.RtmpMsg) { return } -// @return 返回的内存块为内部新申请 +// FlvTag2RtmpChunks @return 返回的内存块为内部新申请 // func FlvTag2RtmpChunks(tag httpflv.Tag) []byte { rtmpHeader := FlvTagHeader2RtmpHeader(tag.Header) diff --git a/pkg/remux/gop_cache.go b/pkg/remux/gop_cache.go index 4a93dbd..2c8842b 100644 --- a/pkg/remux/gop_cache.go +++ b/pkg/remux/gop_cache.go @@ -10,7 +10,6 @@ package remux import ( "github.com/q191201771/lal/pkg/base" - "github.com/q191201771/naza/pkg/nazalog" ) // GopCache @@ -66,7 +65,7 @@ type GopCache struct { gopSize int } -// @param gopNum: gop缓存大小 +// NewGopCache @param gopNum: gop缓存大小 // 如果为0,则不缓存音频数据,也即GOP缓存功能不生效 // 如果>0,则缓存个完整GOP,另外还可能有半个最近不完整的GOP // @@ -87,18 +86,18 @@ func (gc *GopCache) Feed(msg base.RtmpMsg, lg LazyGet) { switch msg.Header.MsgTypeId { case base.RtmpTypeIdMetadata: gc.Metadata = lg() - nazalog.Debugf("[%s] cache %s metadata. size:%d", gc.uniqueKey, gc.t, len(gc.Metadata)) + Log.Debugf("[%s] cache %s metadata. size:%d", gc.uniqueKey, gc.t, len(gc.Metadata)) return case base.RtmpTypeIdAudio: if msg.IsAacSeqHeader() { gc.AacSeqHeader = lg() - nazalog.Debugf("[%s] cache %s aac seq header. size:%d", gc.uniqueKey, gc.t, len(gc.AacSeqHeader)) + Log.Debugf("[%s] cache %s aac seq header. size:%d", gc.uniqueKey, gc.t, len(gc.AacSeqHeader)) return } case base.RtmpTypeIdVideo: if msg.IsVideoKeySeqHeader() { gc.VideoSeqHeader = lg() - nazalog.Debugf("[%s] cache %s video seq header. size:%d", gc.uniqueKey, gc.t, len(gc.VideoSeqHeader)) + Log.Debugf("[%s] cache %s video seq header. size:%d", gc.uniqueKey, gc.t, len(gc.VideoSeqHeader)) return } } @@ -112,7 +111,7 @@ func (gc *GopCache) Feed(msg base.RtmpMsg, lg LazyGet) { } } -// 获取GOP数量,注意,最后一个可能是不完整的 +// GetGopCount 获取GOP数量,注意,最后一个可能是不完整的 func (gc *GopCache) GetGopCount() int { return (gc.gopRingLast + gc.gopSize - gc.gopRingFirst) % gc.gopSize } @@ -132,6 +131,8 @@ func (gc *GopCache) Clear() { gc.gopRingFirst = 0 } +// --------------------------------------------------------------------------------------------------------------------- + // 往最后一个GOP元素追加一个msg // 注意,如果GopCache为空,则不缓存msg func (gc *GopCache) feedLastGop(msg base.RtmpMsg, b []byte) { @@ -158,6 +159,8 @@ func (gc *GopCache) isGopRingEmpty() bool { return gc.gopRingFirst == gc.gopRingLast } +// --------------------------------------------------------------------------------------------------------------------- + type Gop struct { data [][]byte } diff --git a/pkg/remux/rtmp2flv.go b/pkg/remux/rtmp2flv.go index ac25d02..0aeab89 100644 --- a/pkg/remux/rtmp2flv.go +++ b/pkg/remux/rtmp2flv.go @@ -13,7 +13,7 @@ import ( "github.com/q191201771/lal/pkg/httpflv" ) -// @return 返回的内存块为新申请的独立内存块 +// RtmpMsg2FlvTag @return 返回的内存块为新申请的独立内存块 func RtmpMsg2FlvTag(msg base.RtmpMsg) *httpflv.Tag { var tag httpflv.Tag tag.Header.Type = msg.Header.MsgTypeId diff --git a/pkg/remux/rtmp2rtsp.go b/pkg/remux/rtmp2rtsp.go index 81a73b4..77ab9e7 100644 --- a/pkg/remux/rtmp2rtsp.go +++ b/pkg/remux/rtmp2rtsp.go @@ -19,7 +19,6 @@ import ( "github.com/q191201771/lal/pkg/hevc" "github.com/q191201771/lal/pkg/rtprtcp" "github.com/q191201771/lal/pkg/sdp" - "github.com/q191201771/naza/pkg/nazalog" ) // TODO(chef): refactor 将analyze部分独立出来作为一个filter @@ -30,7 +29,7 @@ var ( maxAnalyzeAvMsgSize = 16 ) -// 提供rtmp数据向sdp+rtp数据的转换 +// Rtmp2RtspRemuxer 提供rtmp数据向sdp+rtp数据的转换 type Rtmp2RtspRemuxer struct { onSdp OnSdp onRtpPacket OnRtpPacket @@ -50,7 +49,7 @@ type Rtmp2RtspRemuxer struct { type OnSdp func(sdpCtx sdp.LogicContext) type OnRtpPacket func(pkt rtprtcp.RtpPacket) -// @param onSdp: 每次回调为独立的内存块,回调结束后,内部不再使用该内存块 +// NewRtmp2RtspRemuxer @param onSdp: 每次回调为独立的内存块,回调结束后,内部不再使用该内存块 // @param onRtpPacket: 每次回调为独立的内存块,回调结束后,内部不再使用该内存块 // func NewRtmp2RtspRemuxer(onSdp OnSdp, onRtpPacket OnRtpPacket) *Rtmp2RtspRemuxer { @@ -62,7 +61,7 @@ func NewRtmp2RtspRemuxer(onSdp OnSdp, onRtpPacket OnRtpPacket) *Rtmp2RtspRemuxer } } -// @param msg: 函数调用结束后,内部不持有`msg`内存块 +// FeedRtmpMsg @param msg: 函数调用结束后,内部不持有`msg`内存块 // func (r *Rtmp2RtspRemuxer) FeedRtmpMsg(msg base.RtmpMsg) { var err error @@ -80,10 +79,10 @@ func (r *Rtmp2RtspRemuxer) FeedRtmpMsg(msg base.RtmpMsg) { if msg.IsAvcKeySeqHeader() || msg.IsHevcKeySeqHeader() { if msg.IsAvcKeySeqHeader() { r.sps, r.pps, err = avc.ParseSpsPpsFromSeqHeader(msg.Payload) - nazalog.Assert(nil, err) + Log.Assert(nil, err) } else if msg.IsHevcKeySeqHeader() { r.vps, r.sps, r.pps, err = hevc.ParseVpsSpsPpsFromSeqHeader(msg.Payload) - nazalog.Assert(nil, err) + Log.Assert(nil, err) } r.doAnalyze() return @@ -91,7 +90,7 @@ func (r *Rtmp2RtspRemuxer) FeedRtmpMsg(msg base.RtmpMsg) { if msg.IsAacSeqHeader() { if len(msg.Payload) < 3 { - nazalog.Warnf("aac seq header payload too short. len=%d, payload=%s", len(msg.Payload), hex.Dump(msg.Payload)) + Log.Warnf("aac seq header payload too short. len=%d, payload=%s", len(msg.Payload), hex.Dump(msg.Payload)) return } r.asc = msg.Clone().Payload[2:] @@ -115,7 +114,7 @@ func (r *Rtmp2RtspRemuxer) FeedRtmpMsg(msg base.RtmpMsg) { } func (r *Rtmp2RtspRemuxer) doAnalyze() { - nazalog.Assert(false, r.analyzeDone) + Log.Assert(false, r.analyzeDone) if r.isAnalyzeEnough() { if r.sps != nil && r.pps != nil { @@ -131,7 +130,7 @@ func (r *Rtmp2RtspRemuxer) doAnalyze() { // 回调sdp ctx, err := sdp.Pack(r.vps, r.sps, r.pps, r.asc) - nazalog.Assert(nil, err) + Log.Assert(nil, err) r.onSdp(ctx) // 分析阶段缓存的数据 @@ -189,11 +188,11 @@ func (r *Rtmp2RtspRemuxer) getAudioPacker() *rtprtcp.RtpPacker { // TODO(chef): 如果rtmp不是以音视频头开始,也可能收到了帧数据,但是头不存在,目前该remux没有做过多容错判断,后续要加上,或者在输入层保证 ascCtx, err := aac.NewAscContext(r.asc) if err != nil { - nazalog.Errorf("parse asc failed. err=%+v", err) + Log.Errorf("parse asc failed. err=%+v", err) } clockRate, err := ascCtx.GetSamplingFrequency() if err != nil { - nazalog.Errorf("get sampling frequency failed. err=%+v", err) + Log.Errorf("get sampling frequency failed. err=%+v", err) } pp := rtprtcp.NewRtpPackerPayloadAac() diff --git a/pkg/remux/var.go b/pkg/remux/var.go new file mode 100644 index 0000000..bbbd490 --- /dev/null +++ b/pkg/remux/var.go @@ -0,0 +1,13 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package remux + +import "github.com/q191201771/naza/pkg/nazalog" + +var Log = nazalog.GetGlobalLogger() diff --git a/pkg/rtmp/amf0.go b/pkg/rtmp/amf0.go index 9d206b9..072834b 100644 --- a/pkg/rtmp/amf0.go +++ b/pkg/rtmp/amf0.go @@ -20,7 +20,6 @@ import ( "github.com/q191201771/naza/pkg/nazaerrors" "github.com/q191201771/naza/pkg/bele" - "github.com/q191201771/naza/pkg/nazalog" ) const ( @@ -160,7 +159,7 @@ func (amf0) WriteObject(writer io.Writer, opa ObjectPairArray) error { return err } default: - nazalog.Panicf("unknown value type. i=%d, v=%+v", i, opa[i].Value) + Log.Panicf("unknown value type. i=%d, v=%+v", i, opa[i].Value) } } _, err := writer.Write(Amf0TypeMarkerObjectEndBytes) @@ -307,7 +306,7 @@ func (amf0) ReadObject(b []byte) (ObjectPairArray, int, error) { } index += l default: - nazalog.Panicf("unknown type. vt=%d", vt) + Log.Panicf("unknown type. vt=%d", vt) } } } @@ -366,7 +365,7 @@ func (amf0) ReadArray(b []byte) (ObjectPairArray, int, error) { } index += l default: - nazalog.Panicf("unknown type. vt=%d", vt) + Log.Panicf("unknown type. vt=%d", vt) } } @@ -374,7 +373,7 @@ func (amf0) ReadArray(b []byte) (ObjectPairArray, int, error) { index += 3 } else { // 测试时发现Array最后也是以00 00 09结束,不确定是否是标准规定的,加个日志在这 - nazalog.Warn("amf ReadArray without suffix Amf0TypeMarkerObjectEndBytes.") + Log.Warn("amf ReadArray without suffix Amf0TypeMarkerObjectEndBytes.") } return ops, index, nil } diff --git a/pkg/rtmp/amf0_test.go b/pkg/rtmp/amf0_test.go index 1bb6bcc..a5aa87d 100644 --- a/pkg/rtmp/amf0_test.go +++ b/pkg/rtmp/amf0_test.go @@ -17,8 +17,6 @@ import ( "github.com/q191201771/lal/pkg/base" - "github.com/q191201771/naza/pkg/nazalog" - . "github.com/q191201771/lal/pkg/rtmp" "github.com/q191201771/naza/pkg/assert" "github.com/q191201771/naza/pkg/fake" @@ -118,7 +116,7 @@ func TestAmf0_ReadArray(t *testing.T) { assert.Equal(t, 16, len(ops)) assert.Equal(t, 359, len(gold)) assert.Equal(t, 359, l) - nazalog.Debug(ops) + Log.Debug(ops) } func TestAmf0_ReadCase1(t *testing.T) { diff --git a/pkg/rtmp/chunk_composer.go b/pkg/rtmp/chunk_composer.go index ae17623..44954e5 100644 --- a/pkg/rtmp/chunk_composer.go +++ b/pkg/rtmp/chunk_composer.go @@ -126,8 +126,8 @@ func (c *ChunkComposer) RunLoop(reader io.Reader, cb OnCompleteMessage) error { case 3: // noop } - if nazalog.GetOption().Level == nazalog.LevelTrace { - nazalog.Tracef("[%p] RTMP_READ chunk.fmt=%d, csid=%d, header=%+v, timestamp=%d", + if Log.GetOption().Level == nazalog.LevelTrace { + Log.Tracef("[%p] RTMP_READ chunk.fmt=%d, csid=%d, header=%+v, timestamp=%d", c, fmt, csid, stream.header, stream.timestamp) } @@ -143,8 +143,8 @@ func (c *ChunkComposer) RunLoop(reader io.Reader, cb OnCompleteMessage) error { return err } newTs := bele.BeUint32(bootstrap) - if nazalog.GetOption().Level == nazalog.LevelTrace { - nazalog.Tracef("[%p] RTMP_READ ext. ts=(%d,%d,%d)", + if Log.GetOption().Level == nazalog.LevelTrace { + Log.Tracef("[%p] RTMP_READ ext. ts=(%d,%d,%d)", c, stream.timestamp, newTs, stream.header.TimestampAbs) } stream.timestamp = newTs @@ -188,8 +188,8 @@ func (c *ChunkComposer) RunLoop(reader io.Reader, cb OnCompleteMessage) error { stream.header.TimestampAbs += stream.timestamp } absTsFlag = false - if nazalog.GetOption().Level == nazalog.LevelTrace { - nazalog.Tracef("[%p] RTMP_READ cb. fmt=%d, csid=%d, header=%+v, timestamp=%d, hex=%s", + if Log.GetOption().Level == nazalog.LevelTrace { + Log.Tracef("[%p] RTMP_READ cb. fmt=%d, csid=%d, header=%+v, timestamp=%d, hex=%s", c, fmt, csid, stream.header, stream.timestamp, hex.Dump(nazabytes.Prefix(stream.msg.buff.Bytes(), 32))) } diff --git a/pkg/rtmp/chunk_divider.go b/pkg/rtmp/chunk_divider.go index 352b5eb..84e1ad1 100644 --- a/pkg/rtmp/chunk_divider.go +++ b/pkg/rtmp/chunk_divider.go @@ -23,12 +23,12 @@ var defaultChunkDivider = ChunkDivider{ localChunkSize: LocalChunkSize, } -// @return 返回的内存块由内部申请,不依赖参数内存块 +// Message2Chunks @return 返回的内存块由内部申请,不依赖参数内存块 func Message2Chunks(message []byte, header *base.RtmpHeader) []byte { return defaultChunkDivider.Message2Chunks(message, header) } -// TODO chef: 新的 message 的第一个 chunk 始终使用 fmt0 格式,没有参考前一个 message +// Message2Chunks TODO chef: 新的 message 的第一个 chunk 始终使用 fmt0 格式,没有参考前一个 message func (d *ChunkDivider) Message2Chunks(message []byte, header *base.RtmpHeader) []byte { return message2Chunks(message, header, nil, d.localChunkSize) } diff --git a/pkg/rtmp/client_pull_session.go b/pkg/rtmp/client_pull_session.go index d52698c..61ab1e7 100644 --- a/pkg/rtmp/client_pull_session.go +++ b/pkg/rtmp/client_pull_session.go @@ -53,7 +53,7 @@ func NewPullSession(modOptions ...ModPullSessionOption) *PullSession { } } -// 阻塞直到和对端完成拉流前的所有准备工作(也即收到RTMP Play response),或者发生错误 +// Pull 阻塞直到和对端完成拉流前的所有准备工作(也即收到RTMP Play response),或者发生错误 // // @param onReadRtmpAvMsg: msg: 注意,回调结束后,`msg`的内存块会被`PullSession`重复使用 // 也即多次回调的`msg`是复用的同一块内存块 @@ -83,42 +83,42 @@ func (s *PullSession) WaitChan() <-chan error { // --------------------------------------------------------------------------------------------------------------------- -// 文档请参考: interface ISessionUrlContext +// Url 文档请参考: interface ISessionUrlContext func (s *PullSession) Url() string { return s.core.Url() } -// 文档请参考: interface ISessionUrlContext +// AppName 文档请参考: interface ISessionUrlContext func (s *PullSession) AppName() string { return s.core.AppName() } -// 文档请参考: interface ISessionUrlContext +// StreamName 文档请参考: interface ISessionUrlContext func (s *PullSession) StreamName() string { return s.core.StreamName() } -// 文档请参考: interface ISessionUrlContext +// RawQuery 文档请参考: interface ISessionUrlContext func (s *PullSession) RawQuery() string { return s.core.RawQuery() } -// 文档请参考: interface IObject +// UniqueKey 文档请参考: interface IObject func (s *PullSession) UniqueKey() string { return s.core.uniqueKey } -// 文档请参考: interface ISessionStat +// GetStat 文档请参考: interface ISessionStat func (s *PullSession) GetStat() base.StatSession { return s.core.GetStat() } -// 文档请参考: interface ISessionStat +// UpdateStat 文档请参考: interface ISessionStat func (s *PullSession) UpdateStat(intervalSec uint32) { s.core.UpdateStat(intervalSec) } -// 文档请参考: interface ISessionStat +// IsAlive 文档请参考: interface ISessionStat func (s *PullSession) IsAlive() (readAlive, writeAlive bool) { return s.core.IsAlive() } diff --git a/pkg/rtmp/client_push_session.go b/pkg/rtmp/client_push_session.go index c360a5d..ffa35ce 100644 --- a/pkg/rtmp/client_push_session.go +++ b/pkg/rtmp/client_push_session.go @@ -54,7 +54,7 @@ func NewPushSession(modOptions ...ModPushSessionOption) *PushSession { } } -// 阻塞直到和对端完成推流前,握手部分的工作(也即收到RTMP Publish response),或者发生错误 +// Push 阻塞直到和对端完成推流前,握手部分的工作(也即收到RTMP Publish response),或者发生错误 func (s *PushSession) Push(rawUrl string) error { return s.core.Do(rawUrl) } @@ -65,7 +65,7 @@ func (s *PushSession) Write(msg []byte) error { return s.core.Write(msg) } -// 将缓存的数据立即刷新发送 +// Flush 将缓存的数据立即刷新发送 // 是否有缓存策略,请参见配置及内部实现 func (s *PushSession) Flush() error { return s.core.Flush() @@ -89,42 +89,42 @@ func (s *PushSession) WaitChan() <-chan error { // --------------------------------------------------------------------------------------------------------------------- -// 文档请参考: interface ISessionUrlContext +// Url 文档请参考: interface ISessionUrlContext func (s *PushSession) Url() string { return s.core.Url() } -// 文档请参考: interface ISessionUrlContext +// AppName 文档请参考: interface ISessionUrlContext func (s *PushSession) AppName() string { return s.core.AppName() } -// 文档请参考: interface ISessionUrlContext +// StreamName 文档请参考: interface ISessionUrlContext func (s *PushSession) StreamName() string { return s.core.StreamName() } -// 文档请参考: interface ISessionUrlContext +// RawQuery 文档请参考: interface ISessionUrlContext func (s *PushSession) RawQuery() string { return s.core.RawQuery() } -// 文档请参考: interface IObject +// UniqueKey 文档请参考: interface IObject func (s *PushSession) UniqueKey() string { return s.core.uniqueKey } -// 文档请参考: interface ISessionStat +// GetStat 文档请参考: interface ISessionStat func (s *PushSession) GetStat() base.StatSession { return s.core.GetStat() } -// 文档请参考: interface ISessionStat +// UpdateStat 文档请参考: interface ISessionStat func (s *PushSession) UpdateStat(intervalSec uint32) { s.core.UpdateStat(intervalSec) } -// 文档请参考: interface ISessionStat +// IsAlive 文档请参考: interface ISessionStat func (s *PushSession) IsAlive() (readAlive, writeAlive bool) { return s.core.IsAlive() } diff --git a/pkg/rtmp/client_session.go b/pkg/rtmp/client_session.go index bc9f50c..3c709bb 100644 --- a/pkg/rtmp/client_session.go +++ b/pkg/rtmp/client_session.go @@ -20,10 +20,9 @@ import ( "github.com/q191201771/naza/pkg/bele" "github.com/q191201771/naza/pkg/connection" - "github.com/q191201771/naza/pkg/nazalog" ) -// rtmp 客户端类型连接的底层实现 +// ClientSession rtmp 客户端类型连接的底层实现 // package rtmp 的使用者应该优先使用基于 ClientSession 实现的 PushSession 和 PullSession type ClientSession struct { uniqueKey string @@ -85,7 +84,7 @@ var defaultClientSessOption = ClientSessionOption{ type ModClientSessionOption func(option *ClientSessionOption) -// @param t: session的类型,只能是推或者拉 +// NewClientSession @param t: session的类型,只能是推或者拉 func NewClientSession(t ClientSessionType, modOptions ...ModClientSessionOption) *ClientSession { var uk string switch t { @@ -117,18 +116,18 @@ func NewClientSession(t ClientSessionType, modOptions ...ModClientSessionOption) stat: base.StatSession{ Protocol: base.ProtocolRtmp, SessionId: uk, - StartTime: time.Now().Format("2006-01-02 15:04:05.999"), + StartTime: base.ReadableNowTime(), }, debugLogReadUserCtrlMsgMax: 5, hc: hc, } - nazalog.Infof("[%s] lifecycle new rtmp ClientSession. session=%p", uk, s) + Log.Infof("[%s] lifecycle new rtmp ClientSession. session=%p", uk, s) return s } -// 阻塞直到收到服务端返回的 publish / play 对应结果的信令或者发生错误 +// Do 阻塞直到收到服务端返回的 publish / play 对应结果的信令或者发生错误 func (s *ClientSession) Do(rawUrl string) error { - nazalog.Debugf("[%s] Do. url=%s", s.uniqueKey, rawUrl) + Log.Debugf("[%s] Do. url=%s", s.uniqueKey, rawUrl) var ( ctx context.Context @@ -250,13 +249,13 @@ func (s *ClientSession) doContext(ctx context.Context, rawUrl string) error { return } - nazalog.Infof("[%s] > W SetChunkSize %d.", s.uniqueKey, LocalChunkSize) + Log.Infof("[%s] > W SetChunkSize %d.", s.uniqueKey, LocalChunkSize) if err := s.packer.writeChunkSize(s.conn, LocalChunkSize); err != nil { errChan <- err return } - nazalog.Infof("[%s] > W connect('%s'). tcUrl=%s", s.uniqueKey, s.appName(), s.tcUrl()) + Log.Infof("[%s] > W connect('%s'). tcUrl=%s", s.uniqueKey, s.appName(), s.tcUrl()) if err := s.packer.writeConnect(s.conn, s.appName(), s.tcUrl(), s.t == CstPushSession); err != nil { errChan <- err return @@ -301,7 +300,7 @@ func (s *ClientSession) streamNameWithRawQuery() string { } func (s *ClientSession) tcpConnect() error { - nazalog.Infof("[%s] > tcp connect.", s.uniqueKey) + Log.Infof("[%s] > tcp connect.", s.uniqueKey) var err error s.stat.RemoteAddr = s.urlCtx.HostWithPort @@ -319,7 +318,7 @@ func (s *ClientSession) tcpConnect() error { } func (s *ClientSession) handshake() error { - nazalog.Infof("[%s] > W Handshake C0+C1.", s.uniqueKey) + Log.Infof("[%s] > W Handshake C0+C1.", s.uniqueKey) if err := s.hc.WriteC0C1(s.conn); err != nil { return err } @@ -327,9 +326,9 @@ func (s *ClientSession) handshake() error { if err := s.hc.ReadS0S1(s.conn); err != nil { return err } - nazalog.Infof("[%s] < R Handshake S0+S1.", s.uniqueKey) + Log.Infof("[%s] < R Handshake S0+S1.", s.uniqueKey) - nazalog.Infof("[%s] > W Handshake C2.", s.uniqueKey) + Log.Infof("[%s] > W Handshake C2.", s.uniqueKey) if err := s.hc.WriteC2(s.conn); err != nil { return err } @@ -337,7 +336,7 @@ func (s *ClientSession) handshake() error { if err := s.hc.ReadS2(s.conn); err != nil { return err } - nazalog.Infof("[%s] < R Handshake S2.", s.uniqueKey) + Log.Infof("[%s] < R Handshake S2.", s.uniqueKey) return nil } @@ -368,7 +367,7 @@ func (s *ClientSession) doMsg(stream *Stream) error { case base.RtmpTypeIdVideo: s.onReadRtmpAvMsg(stream.toAvMsg()) default: - nazalog.Errorf("[%s] read unknown message. typeid=%d, %s", s.uniqueKey, stream.header.MsgTypeId, stream.toDebugString()) + Log.Errorf("[%s] read unknown message. typeid=%d, %s", s.uniqueKey, stream.header.MsgTypeId, stream.toDebugString()) panic(0) } return nil @@ -376,7 +375,7 @@ func (s *ClientSession) doMsg(stream *Stream) error { func (s *ClientSession) doAck(stream *Stream) error { seqNum := bele.BeUint32(stream.msg.buff.Bytes()) - nazalog.Infof("[%s] < R Acknowledgement. ignore. sequence number=%d.", s.uniqueKey, seqNum) + Log.Infof("[%s] < R Acknowledgement. ignore. sequence number=%d.", s.uniqueKey, seqNum) return nil } func (s *ClientSession) doUserControl(stream *Stream) error { @@ -389,7 +388,7 @@ func (s *ClientSession) doUserControl(stream *Stream) error { s.debugLogReadUserCtrlMsgCount++ if s.debugLogReadUserCtrlMsgCount <= s.debugLogReadUserCtrlMsgMax { - nazalog.Warnf("[%s] read user control message, ignore. buf=%s", + Log.Warnf("[%s] read user control message, ignore. buf=%s", s.uniqueKey, hex.Dump(stream.msg.buff.Peek(32))) } return nil @@ -403,7 +402,7 @@ func (s *ClientSession) doDataMessageAmf0(stream *Stream) error { switch val { case "|RtmpSampleAccess": - nazalog.Debugf("[%s] < R |RtmpSampleAccess, ignore.", s.uniqueKey) + Log.Debugf("[%s] < R |RtmpSampleAccess, ignore.", s.uniqueKey) return nil default: } @@ -424,13 +423,13 @@ func (s *ClientSession) doCommandMessage(stream *Stream) error { switch cmd { case "onBWDone": - nazalog.Warnf("[%s] < R onBWDone. ignore.", s.uniqueKey) + Log.Warnf("[%s] < R onBWDone. ignore.", s.uniqueKey) case "_result": return s.doResultMessage(stream, tid) case "onStatus": return s.doOnStatusMessage(stream, tid) default: - nazalog.Errorf("[%s] read unknown command message. cmd=%s, %s", s.uniqueKey, cmd, stream.toDebugString()) + Log.Errorf("[%s] read unknown command message. cmd=%s, %s", s.uniqueKey, cmd, stream.toDebugString()) } return nil @@ -452,18 +451,18 @@ func (s *ClientSession) doOnStatusMessage(stream *Stream, tid int) error { case CstPushSession: switch code { case "NetStream.Publish.Start": - nazalog.Infof("[%s] < R onStatus('NetStream.Publish.Start').", s.uniqueKey) + Log.Infof("[%s] < R onStatus('NetStream.Publish.Start').", s.uniqueKey) s.notifyDoResultSucc() default: - nazalog.Warnf("[%s] read on status message but code field unknown. code=%s", s.uniqueKey, code) + Log.Warnf("[%s] read on status message but code field unknown. code=%s", s.uniqueKey, code) } case CstPullSession: switch code { case "NetStream.Play.Start": - nazalog.Infof("[%s] < R onStatus('NetStream.Play.Start').", s.uniqueKey) + Log.Infof("[%s] < R onStatus('NetStream.Play.Start').", s.uniqueKey) s.notifyDoResultSucc() default: - nazalog.Warnf("[%s] read on status message but code field unknown. code=%s", s.uniqueKey, code) + Log.Warnf("[%s] read on status message but code field unknown. code=%s", s.uniqueKey, code) } } @@ -487,13 +486,13 @@ func (s *ClientSession) doResultMessage(stream *Stream, tid int) error { } switch code { case "NetConnection.Connect.Success": - nazalog.Infof("[%s] < R _result(\"NetConnection.Connect.Success\").", s.uniqueKey) - nazalog.Infof("[%s] > W createStream().", s.uniqueKey) + Log.Infof("[%s] < R _result(\"NetConnection.Connect.Success\").", s.uniqueKey) + Log.Infof("[%s] > W createStream().", s.uniqueKey) if err := s.packer.writeCreateStream(s.conn); err != nil { return err } default: - nazalog.Errorf("[%s] unknown code. code=%v", s.uniqueKey, code) + Log.Errorf("[%s] unknown code. code=%v", s.uniqueKey, code) } case tidClientCreateStream: err := stream.msg.readNull() @@ -504,21 +503,21 @@ func (s *ClientSession) doResultMessage(stream *Stream, tid int) error { if err != nil { return err } - nazalog.Infof("[%s] < R _result().", s.uniqueKey) + Log.Infof("[%s] < R _result().", s.uniqueKey) switch s.t { case CstPullSession: - nazalog.Infof("[%s] > W play('%s').", s.uniqueKey, s.streamNameWithRawQuery()) + Log.Infof("[%s] > W play('%s').", s.uniqueKey, s.streamNameWithRawQuery()) if err := s.packer.writePlay(s.conn, s.streamNameWithRawQuery(), sid); err != nil { return err } case CstPushSession: - nazalog.Infof("[%s] > W publish('%s').", s.uniqueKey, s.streamNameWithRawQuery()) + Log.Infof("[%s] > W publish('%s').", s.uniqueKey, s.streamNameWithRawQuery()) if err := s.packer.writePublish(s.conn, s.appName(), s.streamNameWithRawQuery(), sid); err != nil { return err } } default: - nazalog.Errorf("[%s] unknown tid. tid=%d", s.uniqueKey, tid) + Log.Errorf("[%s] unknown tid. tid=%d", s.uniqueKey, tid) } return nil } @@ -531,15 +530,15 @@ func (s *ClientSession) doProtocolControlMessage(stream *Stream) error { switch stream.header.MsgTypeId { case base.RtmpTypeIdWinAckSize: s.peerWinAckSize = val - nazalog.Infof("[%s] < R Window Acknowledgement Size: %d", s.uniqueKey, s.peerWinAckSize) + Log.Infof("[%s] < R Window Acknowledgement Size: %d", s.uniqueKey, s.peerWinAckSize) case base.RtmpTypeIdBandwidth: // TODO chef: 是否需要关注这个信令 - nazalog.Warnf("[%s] < R Set Peer Bandwidth. ignore.", s.uniqueKey) + Log.Warnf("[%s] < R Set Peer Bandwidth. ignore.", s.uniqueKey) case base.RtmpTypeIdSetChunkSize: // composer内部会自动更新peer chunk size. - nazalog.Infof("[%s] < R Set Chunk Size %d.", s.uniqueKey, val) + Log.Infof("[%s] < R Set Chunk Size %d.", s.uniqueKey, val) default: - nazalog.Errorf("[%s] read unknown protocol control message. typeid=%d, %s", s.uniqueKey, stream.header.MsgTypeId, stream.toDebugString()) + Log.Errorf("[%s] read unknown protocol control message. typeid=%d, %s", s.uniqueKey, stream.header.MsgTypeId, stream.toDebugString()) } return nil } @@ -547,7 +546,7 @@ func (s *ClientSession) doProtocolControlMessage(stream *Stream) error { func (s *ClientSession) notifyDoResultSucc() { // 碰上过对端服务器实现有问题,对于play信令回复了两次相同的结果,我们在这里忽略掉非第一次的回复 if s.hasNotifyDoResultSucc { - nazalog.Warnf("[%s] has notified do result succ already, ignore it", s.uniqueKey) + Log.Warnf("[%s] has notified do result succ already, ignore it", s.uniqueKey) return } s.hasNotifyDoResultSucc = true @@ -563,7 +562,7 @@ func (s *ClientSession) notifyDoResultSucc() { func (s *ClientSession) dispose(err error) error { var retErr error s.disposeOnce.Do(func() { - nazalog.Infof("[%s] lifecycle dispose rtmp ClientSession. err=%+v", s.uniqueKey, err) + Log.Infof("[%s] lifecycle dispose rtmp ClientSession. err=%+v", s.uniqueKey, err) if s.conn == nil { retErr = base.ErrSessionNotStarted return diff --git a/pkg/rtmp/handshake.go b/pkg/rtmp/handshake.go index 806875e..ad4dac3 100644 --- a/pkg/rtmp/handshake.go +++ b/pkg/rtmp/handshake.go @@ -19,7 +19,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/naza/pkg/bele" - "github.com/q191201771/naza/pkg/nazalog" ) // https://pengrl.com/p/20027 @@ -234,7 +233,7 @@ func parseChallenge(b []byte, peerKey []byte, key []byte) []byte { //} ver := bele.BeUint32(b[5:]) if ver == 0 { - nazalog.Debug("handshake simple mode.") + Log.Debug("handshake simple mode.") return nil } @@ -243,10 +242,10 @@ func parseChallenge(b []byte, peerKey []byte, key []byte) []byte { offs = findDigest(b[1:], 8, peerKey) } if offs == -1 { - nazalog.Warn("get digest offs failed. roll back to try simple handshake.") + Log.Warn("get digest offs failed. roll back to try simple handshake.") return nil } - nazalog.Debug("handshake complex mode.") + Log.Debug("handshake complex mode.") // use c0c1 digest to make a new digest digest := makeDigest(b[1+offs:1+offs+keyLen], key) diff --git a/pkg/rtmp/message_packer.go b/pkg/rtmp/message_packer.go index 848bce1..b1c5b5d 100644 --- a/pkg/rtmp/message_packer.go +++ b/pkg/rtmp/message_packer.go @@ -12,8 +12,6 @@ import ( "fmt" "io" - "github.com/q191201771/naza/pkg/nazalog" - "github.com/q191201771/lal/pkg/base" "github.com/q191201771/naza/pkg/bele" @@ -25,7 +23,7 @@ const ( peerBandwidthLimitTypeDynamic = uint8(2) ) -// 打包并发送 rtmp 信令 +// MessagePacker 打包并发送 rtmp 信令 // type MessagePacker struct { b *Buffer @@ -323,7 +321,7 @@ func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) { if nBytes := b.Len(); nBytes > 0 { m, e := w.Write(b.Bytes()) if m > nBytes { - nazalog.Panicf("Buffer.WriteTo: invalid Write count. expected=%d, actual=%d", nBytes, m) + Log.Panicf("Buffer.WriteTo: invalid Write count. expected=%d, actual=%d", nBytes, m) } b.readPos += m n = int64(m) @@ -356,7 +354,7 @@ func (b *Buffer) grow(n int) { newLen = cap(b.core) * 2 } buf := make([]byte, newLen) - nazalog.Debugf("Buffer::grow. need=%d, old len=%d, cap=%d, new len=%d", n, b.Len(), cap(b.core), newLen) + Log.Debugf("Buffer::grow. need=%d, old len=%d, cap=%d, new len=%d", n, b.Len(), cap(b.core), newLen) copy(buf, b.core[b.readPos:b.writePos]) b.core = buf b.readPos = 0 diff --git a/pkg/rtmp/metadata.go b/pkg/rtmp/metadata.go index d5a8fb5..a721536 100644 --- a/pkg/rtmp/metadata.go +++ b/pkg/rtmp/metadata.go @@ -32,7 +32,7 @@ func ParseMetadata(b []byte) (ObjectPairArray, error) { return opa, err } -// spec-video_file_format_spec_v10.pdf +// BuildMetadata spec-video_file_format_spec_v10.pdf // onMetaData // - duration DOUBLE, seconds // - width DOUBLE diff --git a/pkg/rtmp/metadata_test.go b/pkg/rtmp/metadata_test.go index 42cf04f..c77102f 100644 --- a/pkg/rtmp/metadata_test.go +++ b/pkg/rtmp/metadata_test.go @@ -15,7 +15,6 @@ import ( "github.com/q191201771/lal/pkg/rtmp" "github.com/q191201771/naza/pkg/assert" - "github.com/q191201771/naza/pkg/nazalog" ) func TestMetadata(t *testing.T) { @@ -24,7 +23,7 @@ func TestMetadata(t *testing.T) { opa, err := rtmp.ParseMetadata(b) assert.Equal(t, nil, err) - nazalog.Debugf("%+v", opa) + rtmp.Log.Debugf("%+v", opa) assert.Equal(t, 5, len(opa)) v := opa.Find("width") diff --git a/pkg/rtmp/rtmp.go b/pkg/rtmp/rtmp.go index 67398f7..6b7baaa 100644 --- a/pkg/rtmp/rtmp.go +++ b/pkg/rtmp/rtmp.go @@ -38,6 +38,7 @@ const defaultChunkSize = 128 // 未收到对端设置chunk size时的默认值 const ( //MSID0 = 0 // 所有除 publish、play、onStatus 之外的信令 + Msid1 = 1 // publish、play、onStatus 以及 音视频数据 ) diff --git a/pkg/rtmp/server.go b/pkg/rtmp/server.go index a5e6b48..3d2c366 100644 --- a/pkg/rtmp/server.go +++ b/pkg/rtmp/server.go @@ -10,8 +10,6 @@ package rtmp import ( "net" - - log "github.com/q191201771/naza/pkg/nazalog" ) type ServerObserver interface { @@ -52,7 +50,7 @@ func (server *Server) Listen() (err error) { if server.ln, err = net.Listen("tcp", server.addr); err != nil { return } - log.Infof("start rtmp server listen. addr=%s", server.addr) + Log.Infof("start rtmp server listen. addr=%s", server.addr) return } @@ -71,12 +69,12 @@ func (server *Server) Dispose() { return } if err := server.ln.Close(); err != nil { - log.Error(err) + Log.Error(err) } } func (server *Server) handleTcpConnect(conn net.Conn) { - log.Infof("accept a rtmp connection. remoteAddr=%s", conn.RemoteAddr().String()) + Log.Infof("accept a rtmp connection. remoteAddr=%s", conn.RemoteAddr().String()) session := NewServerSession(server, conn) _ = session.RunLoop() diff --git a/pkg/rtmp/server_session.go b/pkg/rtmp/server_session.go index 7dbb9f1..0e5618c 100644 --- a/pkg/rtmp/server_session.go +++ b/pkg/rtmp/server_session.go @@ -13,7 +13,6 @@ import ( "net" "strings" "sync" - "time" "github.com/q191201771/naza/pkg/nazaerrors" @@ -21,7 +20,6 @@ import ( "github.com/q191201771/naza/pkg/bele" "github.com/q191201771/naza/pkg/connection" - "github.com/q191201771/naza/pkg/nazalog" ) // TODO chef: 没有进化成Pub Sub时的超时释放 @@ -41,7 +39,7 @@ type ServerSessionObserver interface { } type PubSessionObserver interface { - // 注意,回调结束后,内部会复用Payload内存块 + // OnReadRtmpAvMsg 注意,回调结束后,内部会复用Payload内存块 OnReadRtmpAvMsg(msg base.RtmpMsg) } @@ -98,7 +96,7 @@ func NewServerSession(observer ServerSessionObserver, conn net.Conn) *ServerSess stat: base.StatSession{ Protocol: base.ProtocolRtmp, SessionId: uk, - StartTime: time.Now().Format("2006-01-02 15:04:05.999"), + StartTime: base.ReadableNowTime(), RemoteAddr: conn.RemoteAddr().String(), }, uniqueKey: uk, @@ -109,7 +107,7 @@ func NewServerSession(observer ServerSessionObserver, conn net.Conn) *ServerSess IsFresh: true, ShouldWaitVideoKeyFrame: true, } - nazalog.Infof("[%s] lifecycle new rtmp ServerSession. session=%p, remote addr=%s", uk, s, conn.RemoteAddr().String()) + Log.Infof("[%s] lifecycle new rtmp ServerSession. session=%p, remote addr=%s", uk, s, conn.RemoteAddr().String()) return s } @@ -207,9 +205,9 @@ func (s *ServerSession) handshake() error { if err := s.hs.ReadC0C1(s.conn); err != nil { return err } - nazalog.Infof("[%s] < R Handshake C0+C1.", s.uniqueKey) + Log.Infof("[%s] < R Handshake C0+C1.", s.uniqueKey) - nazalog.Infof("[%s] > W Handshake S0+S1+S2.", s.uniqueKey) + Log.Infof("[%s] > W Handshake S0+S1+S2.", s.uniqueKey) if err := s.hs.WriteS0S1S2(s.conn); err != nil { return err } @@ -217,7 +215,7 @@ func (s *ServerSession) handshake() error { if err := s.hs.ReadC2(s.conn); err != nil { return err } - nazalog.Infof("[%s] < R Handshake C2.", s.uniqueKey) + Log.Infof("[%s] < R Handshake C2.", s.uniqueKey) return nil } @@ -245,7 +243,7 @@ func (s *ServerSession) doMsg(stream *Stream) error { } s.avObserver.OnReadRtmpAvMsg(stream.toAvMsg()) default: - nazalog.Warnf("[%s] read unknown message. typeid=%d, %s", s.uniqueKey, stream.header.MsgTypeId, stream.toDebugString()) + Log.Warnf("[%s] read unknown message. typeid=%d, %s", s.uniqueKey, stream.header.MsgTypeId, stream.toDebugString()) } return nil @@ -253,7 +251,7 @@ func (s *ServerSession) doMsg(stream *Stream) error { func (s *ServerSession) doAck(stream *Stream) error { seqNum := bele.BeUint32(stream.msg.buff.Bytes()) - nazalog.Infof("[%s] < R Acknowledgement. ignore. sequence number=%d.", s.uniqueKey, seqNum) + Log.Infof("[%s] < R Acknowledgement. ignore. sequence number=%d.", s.uniqueKey, seqNum) return nil } func (s *ServerSession) doUserControl(stream *Stream) error { @@ -277,7 +275,7 @@ func (s *ServerSession) doDataMessageAmf0(stream *Stream) error { switch val { case "|RtmpSampleAccess": - nazalog.Debugf("[%s] < R |RtmpSampleAccess, ignore.", s.uniqueKey) + Log.Debugf("[%s] < R |RtmpSampleAccess, ignore.", s.uniqueKey) return nil default: } @@ -292,7 +290,7 @@ func (s *ServerSession) doDataMessageAmf0(stream *Stream) error { // //switch val { //case "|RtmpSampleAccess": - // nazalog.Warnf("[%s] read data message, ignore it. val=%s", s.uniqueKey, val) + // Log.Warnf("[%s] read data message, ignore it. val=%s", s.uniqueKey, val) // return nil //case "@setDataFrame": // // macos obs and ffmpeg @@ -304,13 +302,13 @@ func (s *ServerSession) doDataMessageAmf0(stream *Stream) error { // return err // } // if val != "onMetaData" { - // nazalog.Errorf("[%s] read unknown data message. val=%s, %s", s.uniqueKey, val, stream.toDebugString()) + // Log.Errorf("[%s] read unknown data message. val=%s, %s", s.uniqueKey, val, stream.toDebugString()) // return ErrRtmp // } //case "onMetaData": // // noop //default: - // nazalog.Errorf("[%s] read unknown data message. val=%s, %s", s.uniqueKey, val, stream.toDebugString()) + // Log.Errorf("[%s] read unknown data message. val=%s, %s", s.uniqueKey, val, stream.toDebugString()) // return nil //} // @@ -346,9 +344,9 @@ func (s *ServerSession) doCommandMessage(stream *Stream) error { case "getStreamLength": fallthrough case "deleteStream": - nazalog.Debugf("[%s] read command message, ignore it. cmd=%s, %s", s.uniqueKey, cmd, stream.toDebugString()) + Log.Debugf("[%s] read command message, ignore it. cmd=%s, %s", s.uniqueKey, cmd, stream.toDebugString()) default: - nazalog.Errorf("[%s] read unknown command message. cmd=%s, %s", s.uniqueKey, cmd, stream.toDebugString()) + Log.Errorf("[%s] read unknown command message. cmd=%s, %s", s.uniqueKey, cmd, stream.toDebugString()) } return nil } @@ -370,28 +368,28 @@ func (s *ServerSession) doConnect(tid int, stream *Stream) error { } s.tcUrl, err = val.FindString("tcUrl") if err != nil { - nazalog.Warnf("[%s] tcUrl not exist.", s.uniqueKey) + Log.Warnf("[%s] tcUrl not exist.", s.uniqueKey) } - nazalog.Infof("[%s] < R connect('%s'). tcUrl=%s", s.uniqueKey, s.appName, s.tcUrl) + Log.Infof("[%s] < R connect('%s'). tcUrl=%s", s.uniqueKey, s.appName, s.tcUrl) s.observer.OnRtmpConnect(s, val) - nazalog.Infof("[%s] > W Window Acknowledgement Size %d.", s.uniqueKey, windowAcknowledgementSize) + Log.Infof("[%s] > W Window Acknowledgement Size %d.", s.uniqueKey, windowAcknowledgementSize) if err := s.packer.writeWinAckSize(s.conn, windowAcknowledgementSize); err != nil { return err } - nazalog.Infof("[%s] > W Set Peer Bandwidth.", s.uniqueKey) + Log.Infof("[%s] > W Set Peer Bandwidth.", s.uniqueKey) if err := s.packer.writePeerBandwidth(s.conn, peerBandwidth, peerBandwidthLimitTypeDynamic); err != nil { return err } - nazalog.Infof("[%s] > W SetChunkSize %d.", s.uniqueKey, LocalChunkSize) + Log.Infof("[%s] > W SetChunkSize %d.", s.uniqueKey, LocalChunkSize) if err := s.packer.writeChunkSize(s.conn, LocalChunkSize); err != nil { return err } - nazalog.Infof("[%s] > W _result('NetConnection.Connect.Success').", s.uniqueKey) + Log.Infof("[%s] > W _result('NetConnection.Connect.Success').", s.uniqueKey) oe, err := val.FindNumber("objectEncoding") if oe != 0 && oe != 3 { oe = 0 @@ -403,8 +401,8 @@ func (s *ServerSession) doConnect(tid int, stream *Stream) error { } func (s *ServerSession) doCreateStream(tid int, stream *Stream) error { - nazalog.Infof("[%s] < R createStream().", s.uniqueKey) - nazalog.Infof("[%s] > W _result().", s.uniqueKey) + Log.Infof("[%s] < R createStream().", s.uniqueKey) + Log.Infof("[%s] > W _result().", s.uniqueKey) if err := s.packer.writeCreateStreamResult(s.conn, tid); err != nil { return err } @@ -431,10 +429,10 @@ func (s *ServerSession) doPublish(tid int, stream *Stream) (err error) { if err != nil { return err } - nazalog.Debugf("[%s] pubType=%s", s.uniqueKey, pubType) - nazalog.Infof("[%s] < R publish('%s')", s.uniqueKey, s.streamNameWithRawQuery) + Log.Debugf("[%s] pubType=%s", s.uniqueKey, pubType) + Log.Infof("[%s] < R publish('%s')", s.uniqueKey, s.streamNameWithRawQuery) - nazalog.Infof("[%s] > W onStatus('NetStream.Publish.Start').", s.uniqueKey) + Log.Infof("[%s] > W onStatus('NetStream.Publish.Start').", s.uniqueKey) if err = s.packer.writeOnStatusPublish(s.conn, Msid1); err != nil { return err } @@ -466,7 +464,7 @@ func (s *ServerSession) doPlay(tid int, stream *Stream) (err error) { s.url = fmt.Sprintf("%s/%s", s.tcUrl, s.streamNameWithRawQuery) - nazalog.Infof("[%s] < R play('%s').", s.uniqueKey, s.streamNameWithRawQuery) + Log.Infof("[%s] < R play('%s').", s.uniqueKey, s.streamNameWithRawQuery) // TODO chef: start duration reset if err := s.packer.writeStreamIsRecorded(s.conn, Msid1); err != nil { @@ -476,7 +474,7 @@ func (s *ServerSession) doPlay(tid int, stream *Stream) (err error) { return err } - nazalog.Infof("[%s] > W onStatus('NetStream.Play.Start').", s.uniqueKey) + Log.Infof("[%s] > W onStatus('NetStream.Play.Start').", s.uniqueKey) if err := s.packer.writeOnStatusPlay(s.conn, Msid1); err != nil { return err } @@ -506,7 +504,7 @@ func (s *ServerSession) modConnProps() { func (s *ServerSession) dispose(err error) error { var retErr error s.disposeOnce.Do(func() { - nazalog.Infof("[%s] lifecycle dispose rtmp ServerSession. err=%+v", s.uniqueKey, err) + Log.Infof("[%s] lifecycle dispose rtmp ServerSession. err=%+v", s.uniqueKey, err) if s.conn == nil { retErr = base.ErrSessionNotStarted return diff --git a/pkg/rtmp/stream.go b/pkg/rtmp/stream.go index 621a384..6faea61 100644 --- a/pkg/rtmp/stream.go +++ b/pkg/rtmp/stream.go @@ -15,7 +15,6 @@ import ( "github.com/q191201771/naza/pkg/nazabytes" "github.com/q191201771/lal/pkg/base" - "github.com/q191201771/naza/pkg/nazalog" ) // ----- Stream -------------------------------------------------------------------------------------------------------- @@ -44,7 +43,7 @@ func (stream *Stream) toDebugString() string { func (stream *Stream) toAvMsg() base.RtmpMsg { // TODO chef: 考虑可能出现header中的len和buf的大小不一致的情况 if stream.header.MsgLen != uint32(stream.msg.buff.Len()) { - nazalog.Errorf("toAvMsg. headerMsgLen=%d, bufLen=%d", stream.header.MsgLen, stream.msg.buff.Len()) + Log.Errorf("toAvMsg. headerMsgLen=%d, bufLen=%d", stream.header.MsgLen, stream.msg.buff.Len()) } return base.RtmpMsg{ Header: stream.header, @@ -58,7 +57,7 @@ type StreamMsg struct { buff *nazabytes.Buffer } -// 确保可写空间,如果不够会扩容 +// Grow 确保可写空间,如果不够会扩容 func (msg *StreamMsg) Grow(n uint32) { msg.buff.Grow(int(n)) } diff --git a/pkg/rtmp/var.go b/pkg/rtmp/var.go index ee10db1..91f155a 100644 --- a/pkg/rtmp/var.go +++ b/pkg/rtmp/var.go @@ -8,8 +8,14 @@ package rtmp -// TODO chef -// 一些更专业的配置项,暂时只在该源码文件中配置,不提供外部配置接口 +import "github.com/q191201771/naza/pkg/nazalog" + +// TODO chef 一些更专业的配置项,暂时只在该源码文件中配置,不提供外部配置接口 + +var ( + Log = nazalog.GetGlobalLogger() +) + var ( readBufSize = 4096 // server session connection读缓冲的大小 wChanSize = 1024 // server session 发送数据时,channel 的大小 diff --git a/pkg/rtprtcp/ntp.go b/pkg/rtprtcp/ntp.go index a960c31..9226446 100644 --- a/pkg/rtprtcp/ntp.go +++ b/pkg/rtprtcp/ntp.go @@ -11,19 +11,19 @@ package rtprtcp // (70 * 365 + 17) * 24 * 60 * 60 const offset uint64 = 2208988800 -// 将ntp时间戳转换为Unix时间戳,Unix时间戳单位是纳秒 +// Ntp2UnixNano 将ntp时间戳转换为Unix时间戳,Unix时间戳单位是纳秒 func Ntp2UnixNano(v uint64) uint64 { msw := v >> 32 lsw := v & 0xFFFFFFFF return (msw-offset)*1e9 + (lsw*1e9)>>32 } -// 将ntp时间戳(高32位低32位分开的形式)转换为Unix时间戳 +// MswLsw2UnixNano 将ntp时间戳(高32位低32位分开的形式)转换为Unix时间戳 func MswLsw2UnixNano(msw, lsw uint64) uint64 { return Ntp2UnixNano(MswLsw2Ntp(msw, lsw)) } -// msw是ntp的高32位,lsw是ntp的低32位 +// MswLsw2Ntp msw是ntp的高32位,lsw是ntp的低32位 func MswLsw2Ntp(msw, lsw uint64) uint64 { return (msw << 32) | lsw } diff --git a/pkg/rtprtcp/ntp_test.go b/pkg/rtprtcp/ntp_test.go index ffb79fb..dac2574 100644 --- a/pkg/rtprtcp/ntp_test.go +++ b/pkg/rtprtcp/ntp_test.go @@ -13,12 +13,11 @@ import ( "time" "github.com/q191201771/lal/pkg/rtprtcp" - "github.com/q191201771/naza/pkg/nazalog" ) func TestMswLsw2UnixNano(t *testing.T) { u := rtprtcp.MswLsw2UnixNano(3805600902, 2181843386) - nazalog.Debug(u) + rtprtcp.Log.Debug(u) tt := time.Unix(int64(u/1e9), int64(u%1e9)) - nazalog.Debug(tt.String()) + rtprtcp.Log.Debug(tt.String()) } diff --git a/pkg/rtprtcp/rtcp.go b/pkg/rtprtcp/rtcp.go index ad84d46..204a023 100644 --- a/pkg/rtprtcp/rtcp.go +++ b/pkg/rtprtcp/rtcp.go @@ -119,7 +119,7 @@ func ParseRtcpHeader(b []byte) RtcpHeader { return h } -// rfc3550 6.4.1 +// ParseSr rfc3550 6.4.1 // // @param b rtcp包,包含包头 func ParseSr(b []byte) Sr { @@ -133,7 +133,7 @@ func ParseSr(b []byte) Sr { return s } -// @param out 传出参数,注意,调用方保证长度>=4 +// PackTo @param out 传出参数,注意,调用方保证长度>=4 func (r *RtcpHeader) PackTo(out []byte) { out[0] = r.Version<<6 | r.Padding<<5 | r.CountOrFormat out[1] = r.PacketType diff --git a/pkg/rtprtcp/rtcp_rr_producer.go b/pkg/rtprtcp/rtcp_rr_producer.go index 063a6b2..3764ef7 100644 --- a/pkg/rtprtcp/rtcp_rr_producer.go +++ b/pkg/rtprtcp/rtcp_rr_producer.go @@ -40,7 +40,7 @@ func NewRrProducer(clockRate int) *RrProducer { } } -// 每次收到rtp包,都将seq序号传入这个函数 +// FeedRtpPacket 每次收到rtp包,都将seq序号传入这个函数 func (r *RrProducer) FeedRtpPacket(seq uint16) { r.received++ @@ -62,7 +62,7 @@ func (r *RrProducer) FeedRtpPacket(seq uint16) { r.extendedSeq = (r.cycles << 16) | uint32(r.maxSeq) } -// 收到sr包时,产生rr包 +// Produce 收到sr包时,产生rr包 // // @param lsr: 从sr包中获取,见func SR.GetMiddleNtp // @return: rr包的二进制数据 diff --git a/pkg/rtprtcp/rtp.go b/pkg/rtprtcp/rtp.go index 82b0f2b..cfc5141 100644 --- a/pkg/rtprtcp/rtp.go +++ b/pkg/rtprtcp/rtp.go @@ -28,11 +28,11 @@ const ( NaluTypeAvcStapa = 24 // one packet, multiple nals NaluTypeAvcFua = 28 - // TODO(chef): hevc有stapa格式吗 + // NaluTypeHevcFua TODO(chef): hevc有stapa格式吗 NaluTypeHevcFua = 49 ) -// 比较序号的值,内部处理序号翻转问题,见单元测试中的例子 +// CompareSeq 比较序号的值,内部处理序号翻转问题,见单元测试中的例子 // @return 0 a和b相等 // 1 a大于b // -1 a小于b @@ -56,7 +56,7 @@ func CompareSeq(a, b uint16) int { return 1 } -// a减b的值,内部处理序号翻转问题,如果a小于b,则返回负值,见单元测试中的例子 +// SubSeq a减b的值,内部处理序号翻转问题,如果a小于b,则返回负值,见单元测试中的例子 func SubSeq(a, b uint16) int { if a == b { return 0 diff --git a/pkg/rtprtcp/rtp_packer.go b/pkg/rtprtcp/rtp_packer.go index dc5d60f..d857888 100644 --- a/pkg/rtprtcp/rtp_packer.go +++ b/pkg/rtprtcp/rtp_packer.go @@ -52,7 +52,7 @@ func NewRtpPacker(payloadPacker IRtpPackerPayload, clockRate int, ssrc uint32, m } } -// @param pkt: pkt.Timestamp 绝对时间戳,单位毫秒 +// Pack @param pkt: pkt.Timestamp 绝对时间戳,单位毫秒 // pkt.PayloadType rtp包头中的packet type // func (r *RtpPacker) Pack(pkt base.AvPacket) (out []RtpPacket) { diff --git a/pkg/rtprtcp/rtp_packer_payload.go b/pkg/rtprtcp/rtp_packer_payload.go index 0a52c4c..edab4a6 100644 --- a/pkg/rtprtcp/rtp_packer_payload.go +++ b/pkg/rtprtcp/rtp_packer_payload.go @@ -9,7 +9,7 @@ package rtprtcp type IRtpPackerPayload interface { - // @param maxSize: rtp payload包体部分(不含包头)的最大大小 + // Pack @param maxSize: rtp payload包体部分(不含包头)的最大大小 // Pack(in []byte, maxSize int) (out [][]byte) } diff --git a/pkg/rtprtcp/rtp_packer_payload_aac.go b/pkg/rtprtcp/rtp_packer_payload_aac.go index 3e920b3..0c087ce 100644 --- a/pkg/rtprtcp/rtp_packer_payload_aac.go +++ b/pkg/rtprtcp/rtp_packer_payload_aac.go @@ -8,8 +8,6 @@ package rtprtcp -import "github.com/q191201771/naza/pkg/nazalog" - type RtpPackerPayloadAac struct { } @@ -31,7 +29,7 @@ func (r *RtpPackerPayloadAac) Pack(in []byte, maxSize int) (out [][]byte) { // 第三部分是帧数据的数组 if len(in) > maxSize { - nazalog.Warnf("frame size bigger than rtp payload size while packing. len(in)=%d, maxSize=%d", len(in), maxSize) + Log.Warnf("frame size bigger than rtp payload size while packing. len(in)=%d, maxSize=%d", len(in), maxSize) } auHeadersLength := 2 // auHeaderSize * nbAuHeaders = 2 * 1 diff --git a/pkg/rtprtcp/rtp_packer_payload_avc_hevc.go b/pkg/rtprtcp/rtp_packer_payload_avc_hevc.go index 1625830..e9fa13a 100644 --- a/pkg/rtprtcp/rtp_packer_payload_avc_hevc.go +++ b/pkg/rtprtcp/rtp_packer_payload_avc_hevc.go @@ -56,7 +56,7 @@ func NewRtpPackerPayloadAvcHevc(payloadType base.AvPacketPt, modOptions ...ModRt } } -// @param in: AVCC格式 +// Pack @param in: AVCC格式 // // @return out: 内存块为独立新申请;函数返回后,内部不再持有该内存块 // diff --git a/pkg/rtprtcp/rtp_packet.go b/pkg/rtprtcp/rtp_packet.go index 8744b30..65770cd 100644 --- a/pkg/rtprtcp/rtp_packet.go +++ b/pkg/rtprtcp/rtp_packet.go @@ -13,7 +13,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/hevc" "github.com/q191201771/naza/pkg/bele" - "github.com/q191201771/naza/pkg/nazalog" ) // ----------------------------------- @@ -114,7 +113,7 @@ func ParseRtpHeader(b []byte) (h RtpHeader, err error) { return } -// 函数调用结束后,不持有参数的内存块 +// ParseRtpPacket 函数调用结束后,不持有参数的内存块 func ParseRtpPacket(b []byte) (pkt RtpPacket, err error) { pkt.Header, err = ParseRtpHeader(b) if err != nil { @@ -127,13 +126,13 @@ func ParseRtpPacket(b []byte) (pkt RtpPacket, err error) { func (p *RtpPacket) Body() []byte { if p.Header.payloadOffset == 0 { - nazalog.Warnf("CHEFNOTICEME. payloadOffset=%d", p.Header.payloadOffset) + Log.Warnf("CHEFNOTICEME. payloadOffset=%d", p.Header.payloadOffset) p.Header.payloadOffset = RtpFixedHeaderLength } return p.Raw[p.Header.payloadOffset:] } -// @param pt: 取值范围为AvPacketPtAvc或AvPacketPtHevc,否则直接返回false +// IsAvcHevcBoundary @param pt: 取值范围为AvPacketPtAvc或AvPacketPtHevc,否则直接返回false // func IsAvcHevcBoundary(pkt RtpPacket, pt base.AvPacketPt) bool { switch pt { diff --git a/pkg/rtprtcp/rtp_unpack_container.go b/pkg/rtprtcp/rtp_unpack_container.go index f38d25f..ca1609b 100644 --- a/pkg/rtprtcp/rtp_unpack_container.go +++ b/pkg/rtprtcp/rtp_unpack_container.go @@ -35,7 +35,7 @@ func NewRtpUnpackContainer(maxSize int, unpackerProtocol IRtpUnpackerProtocol) * } } -// 输入收到的rtp包 +// Feed 输入收到的rtp包 func (r *RtpUnpackContainer) Feed(pkt RtpPacket) { // 过期的包 if r.isStale(pkt.Header.Seq) { diff --git a/pkg/rtprtcp/rtp_unpacker.go b/pkg/rtprtcp/rtp_unpacker.go index ff7f5c7..3a1aca2 100644 --- a/pkg/rtprtcp/rtp_unpacker.go +++ b/pkg/rtprtcp/rtp_unpacker.go @@ -10,7 +10,6 @@ package rtprtcp import ( "github.com/q191201771/lal/pkg/base" - "github.com/q191201771/naza/pkg/nazalog" ) // 传入RTP包,合成帧数据,并回调返回 @@ -32,10 +31,10 @@ type IRtpUnpackContainer interface { } type IRtpUnpackerProtocol interface { - // 计算rtp包处于帧中的位置 + // CalcPositionIfNeeded 计算rtp包处于帧中的位置 CalcPositionIfNeeded(pkt *RtpPacket) - // 尝试合成一个完整帧 + // TryUnpackOne 尝试合成一个完整帧 // // 从当前队列的第一个包开始合成 // 如果一个rtp包对应一个完整帧,则合成一帧 @@ -47,7 +46,7 @@ type IRtpUnpackerProtocol interface { TryUnpackOne(list *RtpPacketList) (unpackedFlag bool, unpackedSeq uint16) } -// @param pkt: pkt.Timestamp RTP包头中的时间戳(pts)经过clockrate换算后的时间戳,单位毫秒 +// OnAvPacket @param pkt: pkt.Timestamp RTP包头中的时间戳(pts)经过clockrate换算后的时间戳,单位毫秒 // 注意,不支持带B帧的视频流,pts和dts永远相同 // pkt.PayloadType base.AvPacketPTXXX // pkt.Payload AAC: @@ -60,7 +59,7 @@ type IRtpUnpackerProtocol interface { // 假如sps和pps是一个stapA包,则合并结果为一个AvPacket type OnAvPacket func(pkt base.AvPacket) -// 目前支持AVC,HEVC和AAC MPEG4-GENERIC,业务方也可以自己实现IRtpUnpackerProtocol,甚至是IRtpUnpackContainer +// DefaultRtpUnpackerFactory 目前支持AVC,HEVC和AAC MPEG4-GENERIC,业务方也可以自己实现IRtpUnpackerProtocol,甚至是IRtpUnpackContainer func DefaultRtpUnpackerFactory(payloadType base.AvPacketPt, clockRate int, maxSize int, onAvPacket OnAvPacket) IRtpUnpacker { var protocol IRtpUnpackerProtocol switch payloadType { @@ -71,7 +70,7 @@ func DefaultRtpUnpackerFactory(payloadType base.AvPacketPt, clockRate int, maxSi case base.AvPacketPtHevc: protocol = NewRtpUnpackerAvcHevc(payloadType, clockRate, onAvPacket) default: - nazalog.Fatalf("payload type not support yet. payloadType=%d", payloadType) + Log.Fatalf("payload type not support yet. payloadType=%d", payloadType) } return NewRtpUnpackContainer(maxSize, protocol) } diff --git a/pkg/rtprtcp/rtp_unpacker_aac.go b/pkg/rtprtcp/rtp_unpacker_aac.go index 2cd14ed..c81a4c3 100644 --- a/pkg/rtprtcp/rtp_unpacker_aac.go +++ b/pkg/rtprtcp/rtp_unpacker_aac.go @@ -10,7 +10,6 @@ package rtprtcp import ( "github.com/q191201771/lal/pkg/base" - "github.com/q191201771/naza/pkg/nazalog" ) type RtpUnpackerAac struct { @@ -67,7 +66,7 @@ func (unpacker *RtpUnpackerAac) TryUnpackOne(list *RtpPacketList) (unpackedFlag return false, 0 } b := p.Packet.Raw[p.Packet.Header.payloadOffset:] - //nazalog.Debugf("%d, %d, %s", len(pkt.Raw), pkt.Header.timestamp, hex.Dump(b)) + //Log.Debugf("%d, %d, %s", len(pkt.Raw), pkt.Header.timestamp, hex.Dump(b)) aus := parseAu(b) @@ -107,7 +106,7 @@ func (unpacker *RtpUnpackerAac) TryUnpackOne(list *RtpPacketList) (unpackedFlag return false, 0 } if p.Packet.Header.Timestamp != timestamp { - nazalog.Errorf("fragments of the same access shall have the same timestamp. first=%d, curr=%d", + Log.Errorf("fragments of the same access shall have the same timestamp. first=%d, curr=%d", timestamp, p.Packet.Header.Timestamp) return false, 0 } @@ -115,11 +114,11 @@ func (unpacker *RtpUnpackerAac) TryUnpackOne(list *RtpPacketList) (unpackedFlag b = p.Packet.Raw[p.Packet.Header.payloadOffset:] aus := parseAu(b) if len(aus) != 1 { - nazalog.Errorf("shall be a single fragment. len(aus)=%d", len(aus)) + Log.Errorf("shall be a single fragment. len(aus)=%d", len(aus)) return false, 0 } if aus[0].size != totalSize { - nazalog.Errorf("fragments of the same access shall have the same size. first=%d, curr=%d", + Log.Errorf("fragments of the same access shall have the same size. first=%d, curr=%d", totalSize, aus[0].size) return false, 0 } @@ -142,7 +141,7 @@ func (unpacker *RtpUnpackerAac) TryUnpackOne(list *RtpPacketList) (unpackedFlag list.Size -= packetCount return true, p.Packet.Header.Seq } else { - nazalog.Errorf("cache size bigger then total size. cacheSize=%d, totalSize=%d", + Log.Errorf("cache size bigger then total size. cacheSize=%d, totalSize=%d", cacheSize, totalSize) return false, 0 } @@ -190,7 +189,7 @@ func parseAu(b []byte) (ret []au) { auSize /= 8 // 注意,fragment时,auIndex并不可靠。见TestAacCase1 //auIndex := b[pauh+1] & 0x7 - //nazalog.Debugf("~ %d %d", auSize, auIndex) + //Log.Debugf("~ %d %d", auSize, auIndex) ret = append(ret, au{ size: auSize, @@ -203,7 +202,7 @@ func parseAu(b []byte) (ret []au) { if (nbAuHeaders > 1 && pau != uint32(len(b))) || (nbAuHeaders == 1 && pau < uint32(len(b))) { - nazalog.Warnf("rtp packet size invalid. nbAuHeaders=%d, pau=%d, len(b)=%d, auHeadersLength=%d", nbAuHeaders, pau, len(b), auHeadersLength) + Log.Warnf("rtp packet size invalid. nbAuHeaders=%d, pau=%d, len(b)=%d, auHeadersLength=%d", nbAuHeaders, pau, len(b), auHeadersLength) } return diff --git a/pkg/rtprtcp/rtp_unpacker_avc_hevc.go b/pkg/rtprtcp/rtp_unpacker_avc_hevc.go index 8d013dc..060204a 100644 --- a/pkg/rtprtcp/rtp_unpacker_avc_hevc.go +++ b/pkg/rtprtcp/rtp_unpacker_avc_hevc.go @@ -13,7 +13,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/hevc" "github.com/q191201771/naza/pkg/bele" - "github.com/q191201771/naza/pkg/nazalog" ) type RtpUnpackerAvcHevc struct { @@ -72,7 +71,7 @@ func (unpacker *RtpUnpackerAvcHevc) TryUnpackOne(list *RtpPacketList) (unpackedF totalSize := 0 for i := 0; i != len(buf); { if len(buf)-i < 2 { - nazalog.Errorf("invalid STAP-A packet.") + Log.Errorf("invalid STAP-A packet.") return false, 0 } naluSize := int(bele.BeUint16(buf[i:])) @@ -179,7 +178,7 @@ func (unpacker *RtpUnpackerAvcHevc) TryUnpackOne(list *RtpPacketList) (unpackedF return true, p.Packet.Header.Seq } else { // 不应该出现其他类型 - nazalog.Errorf("invalid position type. position=%d, first=(h=%+v, pos=%d), prev=(h=%+v, pos=%d), p=(h=%+v, pos=%d)", + Log.Errorf("invalid position type. position=%d, first=(h=%+v, pos=%d), prev=(h=%+v, pos=%d), p=(h=%+v, pos=%d)", p.Packet.positionType, first.Packet.Header, first.Packet.positionType, prev.Packet.Header, prev.Packet.positionType, p.Packet.Header, p.Packet.positionType) return false, 0 } @@ -190,7 +189,7 @@ func (unpacker *RtpUnpackerAvcHevc) TryUnpackOne(list *RtpPacketList) (unpackedF case PositionTypeFuaEnd: // noop default: - nazalog.Errorf("invalid position. pos=%d", first.Packet.positionType) + Log.Errorf("invalid position. pos=%d", first.Packet.positionType) } return false, 0 @@ -262,7 +261,7 @@ func calcPositionIfNeededAvc(pkt *RtpPacket) { } else if outerNaluType == NaluTypeAvcStapa { pkt.positionType = PositionTypeStapa } else { - nazalog.Errorf("unknown nalu type. outerNaluType=%d", outerNaluType) + Log.Errorf("unknown nalu type. outerNaluType=%d", outerNaluType) } return @@ -342,7 +341,7 @@ func calcPositionIfNeededHevc(pkt *RtpPacket) { return default: // TODO chef: 没有实现 AP 48 - nazalog.Errorf("unknown nalu type. outerNaluType=%d(%d), header=%+v, len=%d", + Log.Errorf("unknown nalu type. outerNaluType=%d(%d), header=%+v, len=%d", b[0], outerNaluType, pkt.Header, len(pkt.Raw)) } diff --git a/pkg/rtprtcp/rtp_unpacker_test.go b/pkg/rtprtcp/rtp_unpacker_test.go index 9a1439f..6fee801 100644 --- a/pkg/rtprtcp/rtp_unpacker_test.go +++ b/pkg/rtprtcp/rtp_unpacker_test.go @@ -12,8 +12,6 @@ import ( "encoding/hex" "testing" - "github.com/q191201771/naza/pkg/nazalog" - "github.com/q191201771/naza/pkg/bele" "github.com/q191201771/lal/pkg/base" @@ -176,7 +174,7 @@ func testHelperAddPrefixLength(in []byte) (out []byte) { func testHelperUnpack(payloadType base.AvPacketPt, clockRate int, maxSize int, rtpPackets []RtpPacket) []base.AvPacket { var outPkts []base.AvPacket unpacker := DefaultRtpUnpackerFactory(payloadType, clockRate, maxSize, func(pkt base.AvPacket) { - nazalog.Debugf("%s", hex.EncodeToString(pkt.Payload)) + Log.Debugf("%s", hex.EncodeToString(pkt.Payload)) outPkts = append(outPkts, pkt) }) for _, pkt := range rtpPackets { diff --git a/pkg/rtprtcp/var.go b/pkg/rtprtcp/var.go new file mode 100644 index 0000000..7b09027 --- /dev/null +++ b/pkg/rtprtcp/var.go @@ -0,0 +1,13 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package rtprtcp + +import "github.com/q191201771/naza/pkg/nazalog" + +var Log = nazalog.GetGlobalLogger() diff --git a/pkg/rtsp/auth.go b/pkg/rtsp/auth.go index 68b414c..e53637a 100644 --- a/pkg/rtsp/auth.go +++ b/pkg/rtsp/auth.go @@ -12,7 +12,6 @@ import ( "fmt" "strings" - "github.com/q191201771/naza/pkg/nazalog" "github.com/q191201771/naza/pkg/nazamd5" ) @@ -51,7 +50,7 @@ func (a *Auth) FeedWwwAuthenticate(auths []string, username, password string) { return } if !strings.HasPrefix(s, AuthTypeDigest) { - nazalog.Warnf("FeedWwwAuthenticate type invalid. v=%s", s) + Log.Warnf("FeedWwwAuthenticate type invalid. v=%s", s) return } @@ -61,21 +60,21 @@ func (a *Auth) FeedWwwAuthenticate(auths []string, username, password string) { a.Algorithm = a.getV(s, `algorithm="`) if a.Realm == "" { - nazalog.Warnf("FeedWwwAuthenticate realm invalid. v=%s", s) + Log.Warnf("FeedWwwAuthenticate realm invalid. v=%s", s) } if a.Nonce == "" { - nazalog.Warnf("FeedWwwAuthenticate realm invalid. v=%s", s) + Log.Warnf("FeedWwwAuthenticate realm invalid. v=%s", s) } if a.Algorithm == "" { a.Algorithm = AuthAlgorithm - nazalog.Warnf("FeedWwwAuthenticate algorithm not found fallback to %s. v=%s", AuthAlgorithm, s) + Log.Warnf("FeedWwwAuthenticate algorithm not found fallback to %s. v=%s", AuthAlgorithm, s) } if a.Algorithm != AuthAlgorithm { - nazalog.Warnf("FeedWwwAuthenticate algorithm invalid, only support MD5. v=%s", s) + Log.Warnf("FeedWwwAuthenticate algorithm invalid, only support MD5. v=%s", s) } } -// 如果没有调用`FeedWwwAuthenticate`初始化过,则直接返回空字符串 +// MakeAuthorization 如果没有调用`FeedWwwAuthenticate`初始化过,则直接返回空字符串 func (a *Auth) MakeAuthorization(method, uri string) string { if a.Username == "" { return "" diff --git a/pkg/rtsp/avpacket_queue.go b/pkg/rtsp/avpacket_queue.go index 6b8547e..66771b5 100644 --- a/pkg/rtsp/avpacket_queue.go +++ b/pkg/rtsp/avpacket_queue.go @@ -11,7 +11,6 @@ package rtsp import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/naza/pkg/circularqueue" - "github.com/q191201771/naza/pkg/nazalog" ) // 处理音频和视频的时间戳: @@ -42,16 +41,16 @@ func NewAvPacketQueue(onAvPacket OnAvPacket) *AvPacketQueue { } } -// 注意,调用方保证,音频相较于音频,视频相较于视频,时间戳是线性递增的。 +// Feed 注意,调用方保证,音频相较于音频,视频相较于视频,时间戳是线性递增的。 func (a *AvPacketQueue) Feed(pkt base.AvPacket) { - //nazalog.Debugf("AVQ feed. t=%d, ts=%d", pkt.PayloadType, pkt.Timestamp) + //Log.Debugf("AVQ feed. t=%d, ts=%d", pkt.PayloadType, pkt.Timestamp) switch pkt.PayloadType { case base.AvPacketPtAvc: fallthrough case base.AvPacketPtHevc: // 时间戳回退了 if int64(pkt.Timestamp) < a.videoBaseTs { - nazalog.Warnf("video ts rotate. pktTS=%d, audioBaseTs=%d, videoBaseTs=%d, audioQueue=%d, videoQueue=%d", + Log.Warnf("video ts rotate. pktTS=%d, audioBaseTs=%d, videoBaseTs=%d, audioQueue=%d, videoQueue=%d", pkt.Timestamp, a.audioBaseTs, a.videoBaseTs, a.audioQueue.Size(), a.videoQueue.Size()) a.videoBaseTs = -1 a.audioBaseTs = -1 @@ -67,7 +66,7 @@ func (a *AvPacketQueue) Feed(pkt base.AvPacket) { _ = a.videoQueue.PushBack(pkt) case base.AvPacketPtAac: if int64(pkt.Timestamp) < a.audioBaseTs { - nazalog.Warnf("audio ts rotate. pktTS=%d, audioBaseTs=%d, videoBaseTs=%d, audioQueue=%d, videoQueue=%d", + Log.Warnf("audio ts rotate. pktTS=%d, audioBaseTs=%d, videoBaseTs=%d, audioQueue=%d, videoQueue=%d", pkt.Timestamp, a.audioBaseTs, a.videoBaseTs, a.audioQueue.Size(), a.videoQueue.Size()) a.videoBaseTs = -1 a.audioBaseTs = -1 @@ -97,14 +96,14 @@ func (a *AvPacketQueue) Feed(pkt base.AvPacket) { // 如果视频满了,则全部输出 if a.videoQueue.Full() { - nazalog.Assert(true, a.audioQueue.Empty()) + Log.Assert(true, a.audioQueue.Empty()) a.popAllVideo() return } // 如果音频满了,则全部输出 if a.audioQueue.Full() { - nazalog.Assert(true, a.videoQueue.Empty()) + Log.Assert(true, a.videoQueue.Empty()) a.popAllAudio() return } @@ -120,7 +119,7 @@ func (a *AvPacketQueue) PopAllByForce() { } // never reach here - nazalog.Assert(false, !a.audioQueue.Empty() && !a.videoQueue.Empty()) + Log.Assert(false, !a.audioQueue.Empty() && !a.videoQueue.Empty()) } func (a *AvPacketQueue) popAllAudio() { diff --git a/pkg/rtsp/avpacket_queue_test.go b/pkg/rtsp/avpacket_queue_test.go index 0fa8d1e..16b3c9b 100644 --- a/pkg/rtsp/avpacket_queue_test.go +++ b/pkg/rtsp/avpacket_queue_test.go @@ -15,7 +15,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/naza/pkg/assert" - "github.com/q191201771/naza/pkg/nazalog" ) var ( @@ -147,11 +146,11 @@ func TestAvPacketQueue(t *testing.T) { } for i := 0; i < len(in); i++ { out, q := oneCase(t, in[:i+1], expects[i]) - nazalog.Infof("-----%d", i) - nazalog.Infof("i:%s", packetsReadable(in[:i+1])) - nazalog.Infof("o:%s", packetsReadable(out)) - nazalog.Infof("e:%s", packetsReadable(expects[i])) - nazalog.Infof("q:%s", packetsReadable(peekQueuePackets(q))) + Log.Infof("-----%d", i) + Log.Infof("i:%s", packetsReadable(in[:i+1])) + Log.Infof("o:%s", packetsReadable(out)) + Log.Infof("e:%s", packetsReadable(expects[i])) + Log.Infof("q:%s", packetsReadable(peekQueuePackets(q))) } // case. 翻转2 diff --git a/pkg/rtsp/base_in_session.go b/pkg/rtsp/base_in_session.go index ccb655f..b61e441 100644 --- a/pkg/rtsp/base_in_session.go +++ b/pkg/rtsp/base_in_session.go @@ -12,7 +12,6 @@ import ( "encoding/hex" "net" "sync" - "time" "github.com/q191201771/naza/pkg/nazaatomic" @@ -23,7 +22,6 @@ import ( "github.com/q191201771/lal/pkg/rtprtcp" "github.com/q191201771/lal/pkg/sdp" "github.com/q191201771/naza/pkg/connection" - "github.com/q191201771/naza/pkg/nazalog" "github.com/q191201771/naza/pkg/nazanet" ) @@ -96,15 +94,15 @@ func NewBaseInSession(uniqueKey string, cmdSession IInterleavedPacketWriter) *Ba stat: base.StatSession{ Protocol: base.ProtocolRtsp, SessionId: uniqueKey, - StartTime: time.Now().Format("2006-01-02 15:04:05.999"), + StartTime: base.ReadableNowTime(), }, cmdSession: cmdSession, waitChan: make(chan error, 1), - dumpReadAudioRtp: base.NewLogDump(1), - dumpReadVideoRtp: base.NewLogDump(1), - dumpReadSr: base.NewLogDump(2), + dumpReadAudioRtp: base.NewLogDump(Log, 1), + dumpReadVideoRtp: base.NewLogDump(Log, 1), + dumpReadSr: base.NewLogDump(Log, 2), } - nazalog.Infof("[%s] lifecycle new rtsp BaseInSession. session=%p", uniqueKey, s) + Log.Infof("[%s] lifecycle new rtsp BaseInSession. session=%p", uniqueKey, s) return s } @@ -122,12 +120,12 @@ func (session *BaseInSession) InitWithSdp(sdpCtx sdp.LogicContext) { if session.sdpCtx.IsAudioUnpackable() { session.audioUnpacker = rtprtcp.DefaultRtpUnpackerFactory(session.sdpCtx.GetAudioPayloadTypeBase(), session.sdpCtx.AudioClockRate, unpackerItemMaxSize, session.onAvPacketUnpacked) } else { - nazalog.Warnf("[%s] audio unpacker not support for this type yet. logicCtx=%+v", session.uniqueKey, session.sdpCtx) + Log.Warnf("[%s] audio unpacker not support for this type yet. logicCtx=%+v", session.uniqueKey, session.sdpCtx) } if session.sdpCtx.IsVideoUnpackable() { session.videoUnpacker = rtprtcp.DefaultRtpUnpackerFactory(session.sdpCtx.GetVideoPayloadTypeBase(), session.sdpCtx.VideoClockRate, unpackerItemMaxSize, session.onAvPacketUnpacked) } else { - nazalog.Warnf("[%s] video unpacker not support this type yet. logicCtx=%+v", session.uniqueKey, session.sdpCtx) + Log.Warnf("[%s] video unpacker not support this type yet. logicCtx=%+v", session.uniqueKey, session.sdpCtx) } session.audioRrProducer = rtprtcp.NewRrProducer(session.sdpCtx.AudioClockRate) @@ -144,7 +142,8 @@ func (session *BaseInSession) InitWithSdp(sdpCtx sdp.LogicContext) { } } -// 如果没有设置回调监听对象,可以通过该函数设置,调用方保证调用该函数发生在调用InitWithSdp之后 +// SetObserver 如果没有设置回调监听对象,可以通过该函数设置,调用方保证调用该函数发生在调用InitWithSdp之后 +// func (session *BaseInSession) SetObserver(observer BaseInSessionObserver) { session.observer = observer @@ -221,11 +220,11 @@ func (session *BaseInSession) HandleInterleavedPacket(b []byte, channel int) { case session.videoRtcpChannel: _ = session.handleRtcpPacket(b, nil) default: - nazalog.Errorf("[%s] read interleaved packet but channel invalid. channel=%d", session.uniqueKey, channel) + Log.Errorf("[%s] read interleaved packet but channel invalid. channel=%d", session.uniqueKey, channel) } } -// 发现pull时,需要先给对端发送数据,才能收到数据 +// WriteRtpRtcpDummy 发现pull时,需要先给对端发送数据,才能收到数据 func (session *BaseInSession) WriteRtpRtcpDummy() { if session.videoRtpConn != nil { _ = session.videoRtpConn.Write(dummyRtpPacket) @@ -303,7 +302,7 @@ func (session *BaseInSession) onReadRtpPacket(b []byte, rAddr *net.UDPAddr, err // TODO(chef): // read udp [::]:30008: use of closed network connection // 可以退出loop,看是在上层退还是下层退,但是要注意每次read都判断的开销 - nazalog.Warnf("[%s] read udp packet failed. err=%+v", session.uniqueKey, err) + Log.Warnf("[%s] read udp packet failed. err=%+v", session.uniqueKey, err) return true } @@ -314,7 +313,7 @@ func (session *BaseInSession) onReadRtpPacket(b []byte, rAddr *net.UDPAddr, err // callback by UDPConnection func (session *BaseInSession) onReadRtcpPacket(b []byte, rAddr *net.UDPAddr, err error) bool { if err != nil { - nazalog.Warnf("[%s] read udp packet failed. err=%+v", session.uniqueKey, err) + Log.Warnf("[%s] read udp packet failed. err=%+v", session.uniqueKey, err) return true } @@ -327,7 +326,7 @@ func (session *BaseInSession) handleRtcpPacket(b []byte, rAddr *net.UDPAddr) err session.currConnStat.ReadBytesSum.Add(uint64(len(b))) if len(b) <= 0 { - nazalog.Errorf("[%s] handleRtcpPacket but length invalid. len=%d", session.uniqueKey, len(b)) + Log.Errorf("[%s] handleRtcpPacket but length invalid. len=%d", session.uniqueKey, len(b)) return nazaerrors.Wrap(base.ErrRtsp) } @@ -369,11 +368,11 @@ func (session *BaseInSession) handleRtcpPacket(b []byte, rAddr *net.UDPAddr) err // noop // // ffmpeg推流时,会在发送第一个RTP包之前就发送一个SR,所以关闭这个警告日志 - //nazalog.Warnf("[%s] read rtcp sr but senderSsrc invalid. senderSsrc=%d, audio=%d, video=%d", + //Log.Warnf("[%s] read rtcp sr but senderSsrc invalid. senderSsrc=%d, audio=%d, video=%d", // p.uniqueKey, sr.SenderSsrc, p.audioSsrc, p.videoSsrc) } default: - nazalog.Warnf("[%s] handleRtcpPacket but type unknown. type=%d, len=%d, hex=%s", + Log.Warnf("[%s] handleRtcpPacket but type unknown. type=%d, len=%d, hex=%s", session.uniqueKey, b[1], len(b), hex.Dump(nazabytes.Prefix(b, 32))) return nazaerrors.Wrap(base.ErrRtsp) } @@ -385,19 +384,19 @@ func (session *BaseInSession) handleRtpPacket(b []byte) error { session.currConnStat.ReadBytesSum.Add(uint64(len(b))) if len(b) < rtprtcp.RtpFixedHeaderLength { - nazalog.Errorf("[%s] handleRtpPacket but length invalid. len=%d", session.uniqueKey, len(b)) + Log.Errorf("[%s] handleRtpPacket but length invalid. len=%d", session.uniqueKey, len(b)) return nazaerrors.Wrap(base.ErrRtsp) } packetType := int(b[1] & 0x7F) if !session.sdpCtx.IsPayloadTypeOrigin(packetType) { - nazalog.Errorf("[%s] handleRtpPacket but type invalid. type=%d", session.uniqueKey, packetType) + Log.Errorf("[%s] handleRtpPacket but type invalid. type=%d", session.uniqueKey, packetType) return nazaerrors.Wrap(base.ErrRtsp) } h, err := rtprtcp.ParseRtpHeader(b) if err != nil { - nazalog.Errorf("[%s] handleRtpPacket invalid rtp packet. err=%+v", session.uniqueKey, err) + Log.Errorf("[%s] handleRtpPacket invalid rtp packet. err=%+v", session.uniqueKey, err) return err } @@ -446,7 +445,7 @@ func (session *BaseInSession) handleRtpPacket(b []byte) error { func (session *BaseInSession) dispose(err error) error { var retErr error session.disposeOnce.Do(func() { - nazalog.Infof("[%s] lifecycle dispose rtsp BaseInSession. session=%p", session.uniqueKey, session) + Log.Infof("[%s] lifecycle dispose rtsp BaseInSession. session=%p", session.uniqueKey, session) var e1, e2, e3, e4 error if session.audioRtpConn != nil { e1 = session.audioRtpConn.Dispose() diff --git a/pkg/rtsp/base_out_session.go b/pkg/rtsp/base_out_session.go index 4363e4b..f03b6df 100644 --- a/pkg/rtsp/base_out_session.go +++ b/pkg/rtsp/base_out_session.go @@ -12,7 +12,6 @@ import ( "encoding/hex" "net" "sync" - "time" "github.com/q191201771/naza/pkg/nazaatomic" @@ -23,11 +22,10 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/sdp" "github.com/q191201771/naza/pkg/connection" - "github.com/q191201771/naza/pkg/nazalog" "github.com/q191201771/naza/pkg/nazanet" ) -// out的含义是音视频由本端发送至对端 +// BaseOutSession out的含义是音视频由本端发送至对端 // type BaseOutSession struct { uniqueKey string @@ -67,14 +65,14 @@ func NewBaseOutSession(uniqueKey string, cmdSession IInterleavedPacketWriter) *B stat: base.StatSession{ Protocol: base.ProtocolRtsp, SessionId: uniqueKey, - StartTime: time.Now().Format("2006-01-02 15:04:05.999"), + StartTime: base.ReadableNowTime(), }, audioRtpChannel: -1, videoRtpChannel: -1, debugLogMaxCount: 3, waitChan: make(chan error, 1), } - nazalog.Infof("[%s] lifecycle new rtsp BaseOutSession. session=%p", uniqueKey, s) + Log.Infof("[%s] lifecycle new rtsp BaseOutSession. session=%p", uniqueKey, s) return s } @@ -138,13 +136,13 @@ func (session *BaseOutSession) HandleInterleavedPacket(b []byte, channel int) { case session.audioRtpChannel: fallthrough case session.videoRtpChannel: - nazalog.Warnf("[%s] not supposed to read packet in rtp channel of BaseOutSession. channel=%d, len=%d", session.uniqueKey, channel, len(b)) + Log.Warnf("[%s] not supposed to read packet in rtp channel of BaseOutSession. channel=%d, len=%d", session.uniqueKey, channel, len(b)) case session.audioRtcpChannel: fallthrough case session.videoRtcpChannel: - nazalog.Debugf("[%s] read interleaved rtcp packet. b=%s", session.uniqueKey, hex.Dump(nazabytes.Prefix(b, 32))) + Log.Debugf("[%s] read interleaved rtcp packet. b=%s", session.uniqueKey, hex.Dump(nazabytes.Prefix(b, 32))) default: - nazalog.Errorf("[%s] read interleaved packet but channel invalid. channel=%d", session.uniqueKey, channel) + Log.Errorf("[%s] read interleaved packet but channel invalid. channel=%d", session.uniqueKey, channel) } } @@ -155,7 +153,7 @@ func (session *BaseOutSession) WriteRtpPacket(packet rtprtcp.RtpPacket) error { t := int(packet.Header.PacketType) if session.sdpCtx.IsAudioPayloadTypeOrigin(t) { if session.loggedWriteAudioRtpCount < session.debugLogMaxCount { - nazalog.Debugf("[%s] LOGPACKET. write audio rtp=%+v", session.uniqueKey, packet.Header) + Log.Debugf("[%s] LOGPACKET. write audio rtp=%+v", session.uniqueKey, packet.Header) session.loggedWriteAudioRtpCount++ } @@ -167,7 +165,7 @@ func (session *BaseOutSession) WriteRtpPacket(packet rtprtcp.RtpPacket) error { } } else if session.sdpCtx.IsVideoPayloadTypeOrigin(t) { if session.loggedWriteVideoRtpCount < session.debugLogMaxCount { - nazalog.Debugf("[%s] LOGPACKET. write video rtp=%+v", session.uniqueKey, packet.Header) + Log.Debugf("[%s] LOGPACKET. write video rtp=%+v", session.uniqueKey, packet.Header) session.loggedWriteVideoRtpCount++ } @@ -178,7 +176,7 @@ func (session *BaseOutSession) WriteRtpPacket(packet rtprtcp.RtpPacket) error { err = session.cmdSession.WriteInterleavedPacket(packet.Raw, session.videoRtpChannel) } } else { - nazalog.Errorf("[%s] write rtp packet but type invalid. type=%d", session.uniqueKey, t) + Log.Errorf("[%s] write rtp packet but type invalid. type=%d", session.uniqueKey, t) err = nazaerrors.Wrap(base.ErrRtsp) } @@ -229,7 +227,7 @@ func (session *BaseOutSession) UniqueKey() string { func (session *BaseOutSession) onReadRtpPacket(b []byte, rAddr *net.UDPAddr, err error) bool { if session.loggedReadRtpCount.Load() < int32(session.debugLogMaxCount) { - nazalog.Debugf("[%s] LOGPACKET. read rtp=%s", session.uniqueKey, hex.Dump(nazabytes.Prefix(b, 32))) + Log.Debugf("[%s] LOGPACKET. read rtp=%s", session.uniqueKey, hex.Dump(nazabytes.Prefix(b, 32))) session.loggedReadRtpCount.Increment() } return true @@ -239,7 +237,7 @@ func (session *BaseOutSession) onReadRtcpPacket(b []byte, rAddr *net.UDPAddr, er // TODO chef: impl me if session.loggedReadRtcpCount.Load() < int32(session.debugLogMaxCount) { - nazalog.Debugf("[%s] LOGPACKET. read rtcp=%s", session.uniqueKey, hex.Dump(nazabytes.Prefix(b, 32))) + Log.Debugf("[%s] LOGPACKET. read rtcp=%s", session.uniqueKey, hex.Dump(nazabytes.Prefix(b, 32))) session.loggedReadRtcpCount.Increment() } return true @@ -248,7 +246,7 @@ func (session *BaseOutSession) onReadRtcpPacket(b []byte, rAddr *net.UDPAddr, er func (session *BaseOutSession) dispose(err error) error { var retErr error session.disposeOnce.Do(func() { - nazalog.Infof("[%s] lifecycle dispose rtsp BaseOutSession. session=%p", session.uniqueKey, session) + Log.Infof("[%s] lifecycle dispose rtsp BaseOutSession. session=%p", session.uniqueKey, session) var e1, e2, e3, e4 error if session.audioRtpConn != nil { e1 = session.audioRtpConn.Dispose() diff --git a/pkg/rtsp/client_command_session.go b/pkg/rtsp/client_command_session.go index a57aec3..f062736 100644 --- a/pkg/rtsp/client_command_session.go +++ b/pkg/rtsp/client_command_session.go @@ -24,7 +24,6 @@ import ( "github.com/q191201771/lal/pkg/sdp" "github.com/q191201771/naza/pkg/connection" "github.com/q191201771/naza/pkg/nazahttp" - "github.com/q191201771/naza/pkg/nazalog" "github.com/q191201771/naza/pkg/nazanet" ) @@ -53,7 +52,7 @@ var defaultClientCommandSessionOption = ClientCommandSessionOption{ type ClientCommandSessionObserver interface { OnConnectResult() - // only for PullSession + // OnDescribeResponse only for PullSession OnDescribeResponse(sdpCtx sdp.LogicContext) OnSetupWithConn(uri string, rtpConn, rtcpConn *nazanet.UdpConnection) @@ -63,7 +62,7 @@ type ClientCommandSessionObserver interface { OnInterleavedPacket(packet []byte, channel int) } -// Push和Pull共用,封装了客户端底层信令信令部分。 +// ClientCommandSession Push和Pull共用,封装了客户端底层信令信令部分。 // 业务方应该使用PushSession和PullSession,而不是直接使用ClientCommandSession,除非你确定要这么做。 type ClientCommandSession struct { uniqueKey string @@ -100,11 +99,11 @@ func NewClientCommandSession(t ClientCommandSessionType, uniqueKey string, obser observer: observer, option: option, } - nazalog.Infof("[%s] lifecycle new rtsp ClientCommandSession. session=%p", uniqueKey, s) + Log.Infof("[%s] lifecycle new rtsp ClientCommandSession. session=%p", uniqueKey, s) return s } -// only for PushSession +// InitWithSdp only for PushSession func (session *ClientCommandSession) InitWithSdp(sdpCtx sdp.LogicContext) { session.sdpCtx = sdpCtx } @@ -275,7 +274,7 @@ func (session *ClientCommandSession) runReadLoop() { // 对端支持get_parameter,需要定时向对端发送get_parameter进行保活 - nazalog.Debugf("[%s] start get_parameter timer.", session.uniqueKey) + Log.Debugf("[%s] start get_parameter timer.", session.uniqueKey) var r = bufio.NewReader(session.conn) t := time.NewTicker(writeGetParameterIntervalMs * time.Millisecond) defer t.Stop() @@ -333,7 +332,7 @@ func (session *ClientCommandSession) connect(rawUrl string) (err error) { return err } - nazalog.Debugf("[%s] > tcp connect.", session.uniqueKey) + Log.Debugf("[%s] > tcp connect.", session.uniqueKey) // # 建立连接 conn, err := net.Dial("tcp", session.urlCtx.HostWithPort) @@ -343,7 +342,7 @@ func (session *ClientCommandSession) connect(rawUrl string) (err error) { session.conn = connection.New(conn, func(option *connection.Option) { option.ReadBufSize = readBufSize }) - nazalog.Debugf("[%s] < tcp connect. laddr=%s, raddr=%s", session.uniqueKey, conn.LocalAddr().String(), conn.RemoteAddr().String()) + Log.Debugf("[%s] < tcp connect. laddr=%s, raddr=%s", session.uniqueKey, conn.LocalAddr().String(), conn.RemoteAddr().String()) session.observer.OnConnectResult() return nil @@ -448,7 +447,7 @@ func (session *ClientCommandSession) writeOneSetup(setupUri string) error { return err } - nazalog.Debugf("[%s] init conn. lRtpPort=%d, lRtcpPort=%d, rRtpPort=%d, rRtcpPort=%d", + Log.Debugf("[%s] init conn. lRtpPort=%d, lRtcpPort=%d, rRtpPort=%d, rRtcpPort=%d", session.uniqueKey, lRtpPort, lRtcpPort, rRtpPort, rRtcpPort) rtpConn, err := nazanet.NewUdpConnection(func(option *nazanet.UdpConnectionOption) { @@ -538,8 +537,8 @@ func (session *ClientCommandSession) writeCmd(method, uri string, headers map[st } req := PackRequest(method, uri, headers, body) - nazalog.Debugf("[%s] > write %s.", session.uniqueKey, method) - //nazalog.Debugf("[%s] > write %s. req=%s", session.uniqueKey, method, req) + Log.Debugf("[%s] > write %s.", session.uniqueKey, method) + //Log.Debugf("[%s] > write %s. req=%s", session.uniqueKey, method, req) _, err := session.conn.Write([]byte(req)) return err } @@ -556,7 +555,7 @@ func (session *ClientCommandSession) writeCmdReadResp(method, uri string, header if err != nil { return } - nazalog.Debugf("[%s] < read response. version=%s, code=%s, reason=%s, headers=%+v, body=%s", + Log.Debugf("[%s] < read response. version=%s, code=%s, reason=%s, headers=%+v, body=%s", session.uniqueKey, ctx.Version, ctx.StatusCode, ctx.Reason, ctx.Headers, string(ctx.Body)) if ctx.StatusCode != "401" { @@ -574,7 +573,7 @@ func (session *ClientCommandSession) writeCmdReadResp(method, uri string, header func (session *ClientCommandSession) dispose(err error) error { var retErr error session.disposeOnce.Do(func() { - nazalog.Infof("[%s] lifecycle dispose rtsp ClientCommandSession. session=%p, err=%+v", session.uniqueKey, session, err) + Log.Infof("[%s] lifecycle dispose rtsp ClientCommandSession. session=%p, err=%+v", session.uniqueKey, session, err) if session.conn == nil { retErr = base.ErrSessionNotStarted return diff --git a/pkg/rtsp/client_pull_session.go b/pkg/rtsp/client_pull_session.go index 78fea25..d6ddbd8 100644 --- a/pkg/rtsp/client_pull_session.go +++ b/pkg/rtsp/client_pull_session.go @@ -14,7 +14,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/sdp" "github.com/q191201771/naza/pkg/nazaerrors" - "github.com/q191201771/naza/pkg/nazalog" "github.com/q191201771/naza/pkg/nazanet" ) @@ -64,14 +63,14 @@ func NewPullSession(observer PullSessionObserver, modOptions ...ModPullSessionOp baseInSession := NewBaseInSessionWithObserver(uk, s, observer) s.baseInSession = baseInSession s.cmdSession = cmdSession - nazalog.Infof("[%s] lifecycle new rtsp PullSession. session=%p", uk, s) + Log.Infof("[%s] lifecycle new rtsp PullSession. session=%p", uk, s) return s } // Pull 阻塞直到和对端完成拉流前,握手部分的工作(也即收到RTSP Play response),或者发生错误 // func (session *PullSession) Pull(rawUrl string) error { - nazalog.Debugf("[%s] pull. url=%s", session.uniqueKey, rawUrl) + Log.Debugf("[%s] pull. url=%s", session.uniqueKey, rawUrl) if err := session.cmdSession.Do(rawUrl); err != nil { return err } @@ -92,7 +91,7 @@ func (session *PullSession) Pull(rawUrl string) error { _ = session.baseInSession.Dispose() } if cmdSessionDisposed { - nazalog.Errorf("[%s] cmd session disposed already.", session.uniqueKey) + Log.Errorf("[%s] cmd session disposed already.", session.uniqueKey) } cmdSessionDisposed = true case err = <-session.baseInSession.WaitChan(): @@ -101,7 +100,7 @@ func (session *PullSession) Pull(rawUrl string) error { _ = session.cmdSession.Dispose() } if baseInSessionDisposed { - nazalog.Errorf("[%s] base in session disposed already.", session.uniqueKey) + Log.Errorf("[%s] base in session disposed already.", session.uniqueKey) } baseInSessionDisposed = true } // select loop @@ -144,79 +143,79 @@ func (session *PullSession) WaitChan() <-chan error { // --------------------------------------------------------------------------------------------------------------------- -// 文档请参考: interface ISessionUrlContext +// Url 文档请参考: interface ISessionUrlContext func (session *PullSession) Url() string { return session.cmdSession.Url() } -// 文档请参考: interface ISessionUrlContext +// AppName 文档请参考: interface ISessionUrlContext func (session *PullSession) AppName() string { return session.cmdSession.AppName() } -// 文档请参考: interface ISessionUrlContext +// StreamName 文档请参考: interface ISessionUrlContext func (session *PullSession) StreamName() string { return session.cmdSession.StreamName() } -// 文档请参考: interface ISessionUrlContext +// RawQuery 文档请参考: interface ISessionUrlContext func (session *PullSession) RawQuery() string { return session.cmdSession.RawQuery() } -// 文档请参考: interface IObject +// UniqueKey 文档请参考: interface IObject func (session *PullSession) UniqueKey() string { return session.uniqueKey } -// 文档请参考: interface ISessionStat +// GetStat 文档请参考: interface ISessionStat func (session *PullSession) GetStat() base.StatSession { stat := session.baseInSession.GetStat() stat.RemoteAddr = session.cmdSession.RemoteAddr() return stat } -// 文档请参考: interface ISessionStat +// UpdateStat 文档请参考: interface ISessionStat func (session *PullSession) UpdateStat(intervalSec uint32) { session.baseInSession.UpdateStat(intervalSec) } -// 文档请参考: interface ISessionStat +// IsAlive 文档请参考: interface ISessionStat func (session *PullSession) IsAlive() (readAlive, writeAlive bool) { return session.baseInSession.IsAlive() } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnConnectResult ClientCommandSessionObserver, callback by ClientCommandSession func (session *PullSession) OnConnectResult() { // noop } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnDescribeResponse ClientCommandSessionObserver, callback by ClientCommandSession func (session *PullSession) OnDescribeResponse(sdpCtx sdp.LogicContext) { session.baseInSession.InitWithSdp(sdpCtx) } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnSetupWithConn ClientCommandSessionObserver, callback by ClientCommandSession func (session *PullSession) OnSetupWithConn(uri string, rtpConn, rtcpConn *nazanet.UdpConnection) { _ = session.baseInSession.SetupWithConn(uri, rtpConn, rtcpConn) } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnSetupWithChannel ClientCommandSessionObserver, callback by ClientCommandSession func (session *PullSession) OnSetupWithChannel(uri string, rtpChannel, rtcpChannel int) { _ = session.baseInSession.SetupWithChannel(uri, rtpChannel, rtcpChannel) } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnSetupResult ClientCommandSessionObserver, callback by ClientCommandSession func (session *PullSession) OnSetupResult() { session.baseInSession.WriteRtpRtcpDummy() } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnInterleavedPacket ClientCommandSessionObserver, callback by ClientCommandSession func (session *PullSession) OnInterleavedPacket(packet []byte, channel int) { session.baseInSession.HandleInterleavedPacket(packet, channel) } -// IInterleavedPacketWriter, callback by BaseInSession +// WriteInterleavedPacket IInterleavedPacketWriter, callback by BaseInSession func (session *PullSession) WriteInterleavedPacket(packet []byte, channel int) error { return session.cmdSession.WriteInterleavedPacket(packet, channel) } @@ -224,7 +223,7 @@ func (session *PullSession) WriteInterleavedPacket(packet []byte, channel int) e func (session *PullSession) dispose(err error) error { var retErr error session.disposeOnce.Do(func() { - nazalog.Infof("[%s] lifecycle dispose rtsp PullSession. session=%p", session.uniqueKey, session) + Log.Infof("[%s] lifecycle dispose rtsp PullSession. session=%p", session.uniqueKey, session) e1 := session.cmdSession.Dispose() e2 := session.baseInSession.Dispose() retErr = nazaerrors.CombineErrors(e1, e2) diff --git a/pkg/rtsp/client_push_session.go b/pkg/rtsp/client_push_session.go index cc1f2ba..ada9474 100644 --- a/pkg/rtsp/client_push_session.go +++ b/pkg/rtsp/client_push_session.go @@ -15,7 +15,6 @@ import ( "github.com/q191201771/lal/pkg/rtprtcp" "github.com/q191201771/lal/pkg/sdp" "github.com/q191201771/naza/pkg/nazaerrors" - "github.com/q191201771/naza/pkg/nazalog" "github.com/q191201771/naza/pkg/nazanet" ) @@ -58,14 +57,14 @@ func NewPushSession(modOptions ...ModPushSessionOption) *PushSession { baseOutSession := NewBaseOutSession(uk, s) s.cmdSession = cmdSession s.baseOutSession = baseOutSession - nazalog.Infof("[%s] lifecycle new rtsp PushSession. session=%p", uk, s) + Log.Infof("[%s] lifecycle new rtsp PushSession. session=%p", uk, s) return s } // Push 阻塞直到和对端完成推流前,握手部分的工作(也即收到RTSP Record response),或者发生错误 // func (session *PushSession) Push(rawUrl string, sdpCtx sdp.LogicContext) error { - nazalog.Debugf("[%s] push. url=%s", session.uniqueKey, rawUrl) + Log.Debugf("[%s] push. url=%s", session.uniqueKey, rawUrl) session.cmdSession.InitWithSdp(sdpCtx) session.baseOutSession.InitWithSdp(sdpCtx) if err := session.cmdSession.Do(rawUrl); err != nil { @@ -85,7 +84,7 @@ func (session *PushSession) Push(rawUrl string, sdpCtx sdp.LogicContext) error { _ = session.baseOutSession.Dispose() } if cmdSessionDisposed { - nazalog.Errorf("[%s] cmd session disposed already.", session.uniqueKey) + Log.Errorf("[%s] cmd session disposed already.", session.uniqueKey) } cmdSessionDisposed = true case err = <-session.baseOutSession.WaitChan(): @@ -94,7 +93,7 @@ func (session *PushSession) Push(rawUrl string, sdpCtx sdp.LogicContext) error { _ = session.cmdSession.Dispose() } if baseInSessionDisposed { - nazalog.Errorf("[%s] base in session disposed already.", session.uniqueKey) + Log.Errorf("[%s] base in session disposed already.", session.uniqueKey) } baseInSessionDisposed = true } // select loop @@ -137,79 +136,79 @@ func (session *PushSession) WaitChan() <-chan error { // --------------------------------------------------------------------------------------------------------------------- -// 文档请参考: interface ISessionUrlContext +// Url 文档请参考: interface ISessionUrlContext func (session *PushSession) Url() string { return session.cmdSession.Url() } -// 文档请参考: interface ISessionUrlContext +// AppName 文档请参考: interface ISessionUrlContext func (session *PushSession) AppName() string { return session.cmdSession.AppName() } -// 文档请参考: interface ISessionUrlContext +// StreamName 文档请参考: interface ISessionUrlContext func (session *PushSession) StreamName() string { return session.cmdSession.StreamName() } -// 文档请参考: interface ISessionUrlContext +// RawQuery 文档请参考: interface ISessionUrlContext func (session *PushSession) RawQuery() string { return session.cmdSession.RawQuery() } -// 文档请参考: interface IObject +// UniqueKey 文档请参考: interface IObject func (session *PushSession) UniqueKey() string { return session.uniqueKey } -// 文档请参考: interface ISessionStat +// GetStat 文档请参考: interface ISessionStat func (session *PushSession) GetStat() base.StatSession { stat := session.baseOutSession.GetStat() stat.RemoteAddr = session.cmdSession.RemoteAddr() return stat } -// 文档请参考: interface ISessionStat +// UpdateStat 文档请参考: interface ISessionStat func (session *PushSession) UpdateStat(intervalSec uint32) { session.baseOutSession.UpdateStat(intervalSec) } -// 文档请参考: interface ISessionStat +// IsAlive 文档请参考: interface ISessionStat func (session *PushSession) IsAlive() (readAlive, writeAlive bool) { return session.baseOutSession.IsAlive() } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnConnectResult ClientCommandSessionObserver, callback by ClientCommandSession func (session *PushSession) OnConnectResult() { // noop } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnDescribeResponse ClientCommandSessionObserver, callback by ClientCommandSession func (session *PushSession) OnDescribeResponse(sdpCtx sdp.LogicContext) { // noop } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnSetupWithConn ClientCommandSessionObserver, callback by ClientCommandSession func (session *PushSession) OnSetupWithConn(uri string, rtpConn, rtcpConn *nazanet.UdpConnection) { _ = session.baseOutSession.SetupWithConn(uri, rtpConn, rtcpConn) } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnSetupWithChannel ClientCommandSessionObserver, callback by ClientCommandSession func (session *PushSession) OnSetupWithChannel(uri string, rtpChannel, rtcpChannel int) { _ = session.baseOutSession.SetupWithChannel(uri, rtpChannel, rtcpChannel) } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnSetupResult ClientCommandSessionObserver, callback by ClientCommandSession func (session *PushSession) OnSetupResult() { // noop } -// ClientCommandSessionObserver, callback by ClientCommandSession +// OnInterleavedPacket ClientCommandSessionObserver, callback by ClientCommandSession func (session *PushSession) OnInterleavedPacket(packet []byte, channel int) { session.baseOutSession.HandleInterleavedPacket(packet, channel) } -// IInterleavedPacketWriter, callback by BaseOutSession +// WriteInterleavedPacket IInterleavedPacketWriter, callback by BaseOutSession func (session *PushSession) WriteInterleavedPacket(packet []byte, channel int) error { return session.cmdSession.WriteInterleavedPacket(packet, channel) } @@ -217,7 +216,7 @@ func (session *PushSession) WriteInterleavedPacket(packet []byte, channel int) e func (session *PushSession) dispose(err error) error { var retErr error session.disposeOnce.Do(func() { - nazalog.Infof("[%s] lifecycle dispose rtsp PushSession. session=%p", session.uniqueKey, session) + Log.Infof("[%s] lifecycle dispose rtsp PushSession. session=%p", session.uniqueKey, session) e1 := session.cmdSession.Dispose() e2 := session.baseOutSession.Dispose() retErr = nazaerrors.CombineErrors(e1, e2) diff --git a/pkg/rtsp/pack.go b/pkg/rtsp/pack.go index 84e2ebc..294111d 100644 --- a/pkg/rtsp/pack.go +++ b/pkg/rtsp/pack.go @@ -17,7 +17,7 @@ import ( // rfc2326 10.1 OPTIONS -// CSeq +// ResponseOptionsTmpl CSeq var ResponseOptionsTmpl = "RTSP/1.0 200 OK\r\n" + "Server: " + base.LalRtspOptionsResponseServer + "\r\n" + "CSeq: %s\r\n" + @@ -27,14 +27,14 @@ var ResponseOptionsTmpl = "RTSP/1.0 200 OK\r\n" + // rfc2326 10.3 ANNOUNCE //var RequestAnnounceTmpl = "not impl" -// CSeq +// ResponseAnnounceTmpl CSeq var ResponseAnnounceTmpl = "RTSP/1.0 200 OK\r\n" + "CSeq: %s\r\n" + "\r\n" // rfc2326 10.2 DESCRIBE -// CSeq, Date, Content-Length, +// ResponseDescribeTmpl CSeq, Date, Content-Length, var ResponseDescribeTmpl = "RTSP/1.0 200 OK\r\n" + "CSeq: %s\r\n" + "Date: %s\r\n" + @@ -43,7 +43,7 @@ var ResponseDescribeTmpl = "RTSP/1.0 200 OK\r\n" + "\r\n" + "%s" -// rfc2326 10.4 SETUP +// ResponseSetupTmpl rfc2326 10.4 SETUP // CSeq, Date, Session, Transport var ResponseSetupTmpl = "RTSP/1.0 200 OK\r\n" + "CSeq: %s\r\n" + @@ -55,7 +55,7 @@ var ResponseSetupTmpl = "RTSP/1.0 200 OK\r\n" + // rfc2326 10.11 RECORD //var RequestRecordTmpl = "not impl" -// CSeq, Session +// ResponseRecordTmpl CSeq, Session var ResponseRecordTmpl = "RTSP/1.0 200 OK\r\n" + "CSeq: %s\r\n" + "Session: %s\r\n" + @@ -63,7 +63,7 @@ var ResponseRecordTmpl = "RTSP/1.0 200 OK\r\n" + // rfc2326 10.5 PLAY -// CSeq Date +// ResponsePlayTmpl CSeq Date var ResponsePlayTmpl = "RTSP/1.0 200 OK\r\n" + "CSeq: %s\r\n" + "Date: %s\r\n" + @@ -72,7 +72,7 @@ var ResponsePlayTmpl = "RTSP/1.0 200 OK\r\n" + // rfc2326 10.7 TEARDOWN //var RequestTeardownTmpl = "not impl" -// CSeq +// ResponseTeardownTmpl CSeq var ResponseTeardownTmpl = "RTSP/1.0 200 OK\r\n" + "CSeq: %s\r\n" + "\r\n" @@ -109,7 +109,7 @@ func PackResponseTeardown(cseq string) string { return fmt.Sprintf(ResponseTeardownTmpl, cseq) } -// @param body 可以为空 +// PackRequest @param body 可以为空 func PackRequest(method, uri string, headers map[string]string, body string) (ret string) { ret = method + " " + uri + " RTSP/1.0\r\n" for k, v := range headers { diff --git a/pkg/rtsp/rtsp.go b/pkg/rtsp/rtsp.go index a4c1e8a..424ee40 100644 --- a/pkg/rtsp/rtsp.go +++ b/pkg/rtsp/rtsp.go @@ -41,7 +41,7 @@ const ( ) const ( - // header key + // HeaderAccept header key HeaderAccept = "Accept" HeaderUserAgent = "User-Agent" HeaderCSeq = "CSeq" @@ -53,7 +53,7 @@ const ( HeaderAuthorization = "Authorization" HeaderPublic = "Public" - // header value + // HeaderAcceptApplicationSdp header value HeaderAcceptApplicationSdp = "application/sdp" HeaderRangeDefault = "npt=0.000-" HeaderTransportClientPlayTmpl = "RTP/AVP/UDP;unicast;client_port=%d-%d" // localRtpPort, localRtcpPort @@ -61,8 +61,11 @@ const ( HeaderTransportClientRecordTmpl = "RTP/AVP/UDP;unicast;client_port=%d-%d;mode=record" HeaderTransportClientRecordTcpTmpl = "RTP/AVP/TCP;unicast;interleaved=%d-%d;mode=record" HeaderTransportServerPlayTmpl = "RTP/AVP/UDP;unicast;client_port=%d-%d;server_port=%d-%d" + //HeaderTransportServerPlayTCPTmpl = "RTP/AVP/TCP;unicast;interleaved=%d-%d" + HeaderTransportServerRecordTmpl = "RTP/AVP/UDP;unicast;client_port=%d-%d;server_port=%d-%d;mode=record" + //HeaderTransportServerRecordTCPTmpl = "RTP/AVP/TCP;unicast;interleaved=%d-%d;mode=record" ) diff --git a/pkg/rtsp/server.go b/pkg/rtsp/server.go index d88428a..7f98f38 100644 --- a/pkg/rtsp/server.go +++ b/pkg/rtsp/server.go @@ -10,15 +10,13 @@ package rtsp import ( "net" - - "github.com/q191201771/naza/pkg/nazalog" ) type ServerObserver interface { - // @brief 使得上层有能力管理未进化到Pub、Sub阶段的Session + // OnNewRtspSessionConnect @brief 使得上层有能力管理未进化到Pub、Sub阶段的Session OnNewRtspSessionConnect(session *ServerCommandSession) - // @brief 注意,对于已经进化到了Pub、Sub阶段的Session,该回调依然会被调用 + // OnDelRtspSession @brief 注意,对于已经进化到了Pub、Sub阶段的Session,该回调依然会被调用 OnDelRtspSession(session *ServerCommandSession) /////////////////////////////////////////////////////////////////////////// @@ -70,7 +68,7 @@ func (s *Server) Listen() (err error) { if err != nil { return } - nazalog.Infof("start rtsp server listen. addr=%s", s.addr) + Log.Infof("start rtsp server listen. addr=%s", s.addr) return } @@ -89,7 +87,7 @@ func (s *Server) Dispose() { return } if err := s.ln.Close(); err != nil { - nazalog.Error(err) + Log.Error(err) } } @@ -122,7 +120,7 @@ func (s *Server) handleTcpConnect(conn net.Conn) { s.observer.OnNewRtspSessionConnect(session) err := session.RunLoop() - nazalog.Info(err) + Log.Info(err) if session.pubSession != nil { s.observer.OnDelRtspPubSession(session.pubSession) diff --git a/pkg/rtsp/server_command_session.go b/pkg/rtsp/server_command_session.go index 667139e..c3b5f2d 100644 --- a/pkg/rtsp/server_command_session.go +++ b/pkg/rtsp/server_command_session.go @@ -21,7 +21,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/sdp" "github.com/q191201771/naza/pkg/nazahttp" - "github.com/q191201771/naza/pkg/nazalog" ) type ServerCommandSessionObserver interface { @@ -71,7 +70,7 @@ func NewServerCommandSession(observer ServerCommandSessionObserver, conn net.Con }), } - nazalog.Infof("[%s] lifecycle new rtsp ServerSession. session=%p, laddr=%s, raddr=%s", uk, s, conn.LocalAddr().String(), conn.RemoteAddr().String()) + Log.Infof("[%s] lifecycle new rtsp ServerSession. session=%p, laddr=%s, raddr=%s", uk, s, conn.LocalAddr().String(), conn.RemoteAddr().String()) return s } @@ -80,7 +79,7 @@ func (session *ServerCommandSession) RunLoop() error { } func (session *ServerCommandSession) Dispose() error { - nazalog.Infof("[%s] lifecycle dispose rtsp ServerCommandSession. session=%p", session.uniqueKey, session) + Log.Infof("[%s] lifecycle dispose rtsp ServerCommandSession. session=%p", session.uniqueKey, session) return session.conn.Close() } @@ -148,7 +147,7 @@ Loop: for { isInterleaved, packet, channel, err := readInterleaved(r) if err != nil { - nazalog.Errorf("[%s] read interleaved error. err=%+v", session.uniqueKey, err) + Log.Errorf("[%s] read interleaved error. err=%+v", session.uniqueKey, err) break Loop } if isInterleaved { @@ -157,7 +156,7 @@ Loop: } else if session.subSession != nil { session.subSession.HandleInterleavedPacket(packet, int(channel)) } else { - nazalog.Errorf("[%s] read interleaved packet but pub or sub not exist.", session.uniqueKey) + Log.Errorf("[%s] read interleaved packet but pub or sub not exist.", session.uniqueKey) break Loop } continue @@ -166,11 +165,11 @@ Loop: // 读取一个message requestCtx, err := nazahttp.ReadHttpRequestMessage(r) if err != nil { - nazalog.Errorf("[%s] read rtsp message error. err=%+v", session.uniqueKey, err) + Log.Errorf("[%s] read rtsp message error. err=%+v", session.uniqueKey, err) break Loop } - nazalog.Debugf("[%s] read http request. method=%s, uri=%s, version=%s, headers=%+v, body=%s", + Log.Debugf("[%s] read http request. method=%s, uri=%s, version=%s, headers=%+v, body=%s", session.uniqueKey, requestCtx.Method, requestCtx.Uri, requestCtx.Version, requestCtx.Headers, string(requestCtx.Body)) var handleMsgErr error @@ -198,44 +197,44 @@ Loop: handleMsgErr = session.handleTeardown(requestCtx) break Loop default: - nazalog.Errorf("[%s] unknown rtsp message. method=%s", session.uniqueKey, requestCtx.Method) + Log.Errorf("[%s] unknown rtsp message. method=%s", session.uniqueKey, requestCtx.Method) } if handleMsgErr != nil { - nazalog.Errorf("[%s] handle rtsp message error. err=%+v, ctx=%+v", session.uniqueKey, handleMsgErr, requestCtx) + Log.Errorf("[%s] handle rtsp message error. err=%+v, ctx=%+v", session.uniqueKey, handleMsgErr, requestCtx) break } } _ = session.conn.Close() - nazalog.Debugf("[%s] < handleTcpConnect.", session.uniqueKey) + Log.Debugf("[%s] < handleTcpConnect.", session.uniqueKey) return nil } func (session *ServerCommandSession) handleOptions(requestCtx nazahttp.HttpReqMsgCtx) error { - nazalog.Infof("[%s] < R OPTIONS", session.uniqueKey) + Log.Infof("[%s] < R OPTIONS", session.uniqueKey) resp := PackResponseOptions(requestCtx.Headers.Get(HeaderCSeq)) _, err := session.conn.Write([]byte(resp)) return err } func (session *ServerCommandSession) handleAnnounce(requestCtx nazahttp.HttpReqMsgCtx) error { - nazalog.Infof("[%s] < R ANNOUNCE", session.uniqueKey) + Log.Infof("[%s] < R ANNOUNCE", session.uniqueKey) urlCtx, err := base.ParseRtspUrl(requestCtx.Uri) if err != nil { - nazalog.Errorf("[%s] parse presentation failed. uri=%s", session.uniqueKey, requestCtx.Uri) + Log.Errorf("[%s] parse presentation failed. uri=%s", session.uniqueKey, requestCtx.Uri) return err } sdpCtx, err := sdp.ParseSdp2LogicContext(requestCtx.Body) if err != nil { - nazalog.Errorf("[%s] parse sdp failed. err=%v", session.uniqueKey, err) + Log.Errorf("[%s] parse sdp failed. err=%v", session.uniqueKey, err) return err } session.pubSession = NewPubSession(urlCtx, session) - nazalog.Infof("[%s] link new PubSession. [%s]", session.uniqueKey, session.pubSession.uniqueKey) + Log.Infof("[%s] link new PubSession. [%s]", session.uniqueKey, session.pubSession.uniqueKey) session.pubSession.InitWithSdp(sdpCtx) if err = session.observer.OnNewRtspPubSession(session.pubSession); err != nil { @@ -248,19 +247,19 @@ func (session *ServerCommandSession) handleAnnounce(requestCtx nazahttp.HttpReqM } func (session *ServerCommandSession) handleDescribe(requestCtx nazahttp.HttpReqMsgCtx) error { - nazalog.Infof("[%s] < R DESCRIBE", session.uniqueKey) + Log.Infof("[%s] < R DESCRIBE", session.uniqueKey) urlCtx, err := base.ParseRtspUrl(requestCtx.Uri) if err != nil { - nazalog.Errorf("[%s] parse presentation failed. uri=%s", session.uniqueKey, requestCtx.Uri) + Log.Errorf("[%s] parse presentation failed. uri=%s", session.uniqueKey, requestCtx.Uri) return err } session.subSession = NewSubSession(urlCtx, session) - nazalog.Infof("[%s] link new SubSession. [%s]", session.uniqueKey, session.subSession.uniqueKey) + Log.Infof("[%s] link new SubSession. [%s]", session.uniqueKey, session.subSession.uniqueKey) ok, rawSdp := session.observer.OnNewRtspSubSessionDescribe(session.subSession) if !ok { - nazalog.Warnf("[%s] force close subSession.", session.uniqueKey) + Log.Warnf("[%s] force close subSession.", session.uniqueKey) return base.ErrRtspClosedByObserver } @@ -274,7 +273,7 @@ func (session *ServerCommandSession) handleDescribe(requestCtx nazahttp.HttpReqM // 一次SETUP对应一路流(音频或视频) func (session *ServerCommandSession) handleSetup(requestCtx nazahttp.HttpReqMsgCtx) error { - nazalog.Infof("[%s] < R SETUP", session.uniqueKey) + Log.Infof("[%s] < R SETUP", session.uniqueKey) remoteAddr := session.conn.RemoteAddr().String() host, _, _ := net.SplitHostPort(remoteAddr) @@ -284,21 +283,21 @@ func (session *ServerCommandSession) handleSetup(requestCtx nazahttp.HttpReqMsgC if strings.Contains(htv, TransportFieldInterleaved) { rtpChannel, rtcpChannel, err := parseRtpRtcpChannel(htv) if err != nil { - nazalog.Errorf("[%s] parse rtp rtcp channel error. err=%+v", session.uniqueKey, err) + Log.Errorf("[%s] parse rtp rtcp channel error. err=%+v", session.uniqueKey, err) return err } if session.pubSession != nil { if err := session.pubSession.SetupWithChannel(requestCtx.Uri, int(rtpChannel), int(rtcpChannel)); err != nil { - nazalog.Errorf("[%s] setup channel error. err=%+v", session.uniqueKey, err) + Log.Errorf("[%s] setup channel error. err=%+v", session.uniqueKey, err) return err } } else if session.subSession != nil { if err := session.subSession.SetupWithChannel(requestCtx.Uri, int(rtpChannel), int(rtcpChannel)); err != nil { - nazalog.Errorf("[%s] setup channel error. err=%+v", session.uniqueKey, err) + Log.Errorf("[%s] setup channel error. err=%+v", session.uniqueKey, err) return err } } else { - nazalog.Errorf("[%s] setup but session not exist.", session.uniqueKey) + Log.Errorf("[%s] setup but session not exist.", session.uniqueKey) return nazaerrors.Wrap(base.ErrRtsp) } @@ -309,31 +308,31 @@ func (session *ServerCommandSession) handleSetup(requestCtx nazahttp.HttpReqMsgC rRtpPort, rRtcpPort, err := parseClientPort(requestCtx.Headers.Get(HeaderTransport)) if err != nil { - nazalog.Errorf("[%s] parseClientPort failed. err=%+v", session.uniqueKey, err) + Log.Errorf("[%s] parseClientPort failed. err=%+v", session.uniqueKey, err) return err } rtpConn, rtcpConn, lRtpPort, lRtcpPort, err := initConnWithClientPort(host, rRtpPort, rRtcpPort) if err != nil { - nazalog.Errorf("[%s] initConnWithClientPort failed. err=%+v", session.uniqueKey, err) + Log.Errorf("[%s] initConnWithClientPort failed. err=%+v", session.uniqueKey, err) return err } - nazalog.Debugf("[%s] init conn. lRtpPort=%d, lRtcpPort=%d, rRtpPort=%d, rRtcpPort=%d", + Log.Debugf("[%s] init conn. lRtpPort=%d, lRtcpPort=%d, rRtpPort=%d, rRtcpPort=%d", session.uniqueKey, lRtpPort, lRtcpPort, rRtpPort, rRtcpPort) if session.pubSession != nil { if err = session.pubSession.SetupWithConn(requestCtx.Uri, rtpConn, rtcpConn); err != nil { - nazalog.Errorf("[%s] setup conn error. err=%+v", session.uniqueKey, err) + Log.Errorf("[%s] setup conn error. err=%+v", session.uniqueKey, err) return err } htv = fmt.Sprintf(HeaderTransportServerRecordTmpl, rRtpPort, rRtcpPort, lRtpPort, lRtcpPort) } else if session.subSession != nil { if err = session.subSession.SetupWithConn(requestCtx.Uri, rtpConn, rtcpConn); err != nil { - nazalog.Errorf("[%s] setup conn error. err=%+v", session.uniqueKey, err) + Log.Errorf("[%s] setup conn error. err=%+v", session.uniqueKey, err) return err } htv = fmt.Sprintf(HeaderTransportServerPlayTmpl, rRtpPort, rRtcpPort, lRtpPort, lRtcpPort) } else { - nazalog.Errorf("[%s] setup but session not exist.", session.uniqueKey) + Log.Errorf("[%s] setup but session not exist.", session.uniqueKey) return nazaerrors.Wrap(base.ErrRtsp) } @@ -343,14 +342,14 @@ func (session *ServerCommandSession) handleSetup(requestCtx nazahttp.HttpReqMsgC } func (session *ServerCommandSession) handleRecord(requestCtx nazahttp.HttpReqMsgCtx) error { - nazalog.Infof("[%s] < R RECORD", session.uniqueKey) + Log.Infof("[%s] < R RECORD", session.uniqueKey) resp := PackResponseRecord(requestCtx.Headers.Get(HeaderCSeq)) _, err := session.conn.Write([]byte(resp)) return err } func (session *ServerCommandSession) handlePlay(requestCtx nazahttp.HttpReqMsgCtx) error { - nazalog.Infof("[%s] < R PLAY", session.uniqueKey) + Log.Infof("[%s] < R PLAY", session.uniqueKey) // TODO(chef): [opt] 上层关闭,可以考虑回复非200状态码再关闭 if err := session.observer.OnNewRtspSubSessionPlay(session.subSession); err != nil { return err @@ -361,7 +360,7 @@ func (session *ServerCommandSession) handlePlay(requestCtx nazahttp.HttpReqMsgCt } func (session *ServerCommandSession) handleTeardown(requestCtx nazahttp.HttpReqMsgCtx) error { - nazalog.Infof("[%s] < R TEARDOWN", session.uniqueKey) + Log.Infof("[%s] < R TEARDOWN", session.uniqueKey) resp := PackResponseTeardown(requestCtx.Headers.Get(HeaderCSeq)) _, err := session.conn.Write([]byte(resp)) return err diff --git a/pkg/rtsp/server_pub_session.go b/pkg/rtsp/server_pub_session.go index 4d73c16..cdfd169 100644 --- a/pkg/rtsp/server_pub_session.go +++ b/pkg/rtsp/server_pub_session.go @@ -14,8 +14,6 @@ import ( "github.com/q191201771/lal/pkg/base" "github.com/q191201771/lal/pkg/sdp" - - "github.com/q191201771/naza/pkg/nazalog" ) type PubSessionObserver interface { @@ -40,7 +38,7 @@ func NewPubSession(urlCtx base.UrlContext, cmdSession *ServerCommandSession) *Pu } baseInSession := NewBaseInSession(uk, s) s.baseInSession = baseInSession - nazalog.Infof("[%s] lifecycle new rtsp PubSession. session=%p, streamName=%s", uk, s, urlCtx.LastItemOfPath) + Log.Infof("[%s] lifecycle new rtsp PubSession. session=%p, streamName=%s", uk, s, urlCtx.LastItemOfPath) return s } @@ -61,7 +59,7 @@ func (session *PubSession) SetupWithChannel(uri string, rtpChannel, rtcpChannel } func (session *PubSession) Dispose() error { - nazalog.Infof("[%s] lifecycle dispose rtsp PubSession. session=%p", session.uniqueKey, session) + Log.Infof("[%s] lifecycle dispose rtsp PubSession. session=%p", session.uniqueKey, session) e1 := session.cmdSession.Dispose() e2 := session.baseInSession.Dispose() return nazaerrors.CombineErrors(e1, e2) @@ -109,7 +107,7 @@ func (session *PubSession) IsAlive() (readAlive, writeAlive bool) { return session.baseInSession.IsAlive() } -// IInterleavedPacketWriter, callback by BaseInSession +// WriteInterleavedPacket IInterleavedPacketWriter, callback by BaseInSession func (session *PubSession) WriteInterleavedPacket(packet []byte, channel int) error { return session.cmdSession.WriteInterleavedPacket(packet, channel) } diff --git a/pkg/rtsp/server_sub_session.go b/pkg/rtsp/server_sub_session.go index e2e1abc..e6471dd 100644 --- a/pkg/rtsp/server_sub_session.go +++ b/pkg/rtsp/server_sub_session.go @@ -14,7 +14,6 @@ import ( "github.com/q191201771/naza/pkg/nazaerrors" "github.com/q191201771/lal/pkg/base" - "github.com/q191201771/naza/pkg/nazalog" "github.com/q191201771/naza/pkg/nazanet" ) @@ -38,7 +37,7 @@ func NewSubSession(urlCtx base.UrlContext, cmdSession *ServerCommandSession) *Su } baseOutSession := NewBaseOutSession(uk, s) s.baseOutSession = baseOutSession - nazalog.Infof("[%s] lifecycle new rtsp SubSession. session=%p, streamName=%s", uk, s, urlCtx.LastItemOfPath) + Log.Infof("[%s] lifecycle new rtsp SubSession. session=%p, streamName=%s", uk, s, urlCtx.LastItemOfPath) return s } @@ -59,7 +58,7 @@ func (session *SubSession) WriteRtpPacket(packet rtprtcp.RtpPacket) { } func (session *SubSession) Dispose() error { - nazalog.Infof("[%s] lifecycle dispose rtsp SubSession. session=%p", session.uniqueKey, session) + Log.Infof("[%s] lifecycle dispose rtsp SubSession. session=%p", session.uniqueKey, session) e1 := session.baseOutSession.Dispose() e2 := session.cmdSession.Dispose() return nazaerrors.CombineErrors(e1, e2) @@ -103,7 +102,7 @@ func (session *SubSession) IsAlive() (readAlive, writeAlive bool) { return session.baseOutSession.IsAlive() } -// IInterleavedPacketWriter, callback by BaseOutSession +// WriteInterleavedPacket IInterleavedPacketWriter, callback by BaseOutSession func (session *SubSession) WriteInterleavedPacket(packet []byte, channel int) error { return session.cmdSession.WriteInterleavedPacket(packet, channel) } diff --git a/pkg/rtsp/var.go b/pkg/rtsp/var.go new file mode 100644 index 0000000..e86b6e7 --- /dev/null +++ b/pkg/rtsp/var.go @@ -0,0 +1,13 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package rtsp + +import "github.com/q191201771/naza/pkg/nazalog" + +var Log = nazalog.GetGlobalLogger() diff --git a/pkg/sdp/parse_logic.go b/pkg/sdp/parse_logic.go index b1c34e5..3452bab 100644 --- a/pkg/sdp/parse_logic.go +++ b/pkg/sdp/parse_logic.go @@ -12,8 +12,6 @@ import ( "fmt" "strings" - "github.com/q191201771/naza/pkg/nazalog" - "github.com/q191201771/lal/pkg/base" ) @@ -122,10 +120,10 @@ func ParseSdp2LogicContext(b []byte) (LogicContext, error) { if md.AFmtPBase != nil { ret.Asc, err = ParseAsc(md.AFmtPBase) if err != nil { - nazalog.Warnf("parse asc from afmtp failed. err=%+v", err) + Log.Warnf("parse asc from afmtp failed. err=%+v", err) } } else { - nazalog.Warnf("aac afmtp not exist.") + Log.Warnf("aac afmtp not exist.") } } else { ret.audioPayloadTypeBase = base.AvPacketPtUnknown @@ -142,20 +140,20 @@ func ParseSdp2LogicContext(b []byte) (LogicContext, error) { if md.AFmtPBase != nil { ret.Sps, ret.Pps, err = ParseSpsPps(md.AFmtPBase) if err != nil { - nazalog.Warnf("parse sps pps from afmtp failed. err=%+v", err) + Log.Warnf("parse sps pps from afmtp failed. err=%+v", err) } } else { - nazalog.Warnf("avc afmtp not exist.") + Log.Warnf("avc afmtp not exist.") } case ARtpMapEncodingNameH265: ret.videoPayloadTypeBase = base.AvPacketPtHevc if md.AFmtPBase != nil { ret.Vps, ret.Sps, ret.Pps, err = ParseVpsSpsPps(md.AFmtPBase) if err != nil { - nazalog.Warnf("parse vps sps pps from afmtp failed. err=%+v", err) + Log.Warnf("parse vps sps pps from afmtp failed. err=%+v", err) } } else { - nazalog.Warnf("hevc afmtp not exist.") + Log.Warnf("hevc afmtp not exist.") } default: ret.videoPayloadTypeBase = base.AvPacketPtUnknown diff --git a/pkg/sdp/parse_raw.go b/pkg/sdp/parse_raw.go index 65d0311..7777d4c 100644 --- a/pkg/sdp/parse_raw.go +++ b/pkg/sdp/parse_raw.go @@ -92,7 +92,7 @@ func ParseM(s string) (ret M, err error) { return } -// 例子见单元测试 +// ParseARtpMap 例子见单元测试 func ParseARtpMap(s string) (ret ARtpMap, err error) { // rfc 3640 3.3.1. General // rfc 3640 3.3.6. High Bit-rate AAC @@ -131,7 +131,7 @@ func ParseARtpMap(s string) (ret ARtpMap, err error) { return } -// 例子见单元测试 +// ParseAFmtPBase 例子见单元测试 func ParseAFmtPBase(s string) (ret AFmtPBase, err error) { // rfc 3640 4.4.1. The a=fmtp Keyword // diff --git a/pkg/sdp/parse_test.go b/pkg/sdp/parse_test.go index 79866bb..8171079 100644 --- a/pkg/sdp/parse_test.go +++ b/pkg/sdp/parse_test.go @@ -15,8 +15,6 @@ import ( "github.com/q191201771/lal/pkg/base" - "github.com/q191201771/naza/pkg/nazalog" - "github.com/q191201771/naza/pkg/assert" ) @@ -48,7 +46,7 @@ var goldenPps = []byte{ func TestParseSdp2RawContext(t *testing.T) { sdpCtx, err := ParseSdp2RawContext([]byte(goldenSdp)) assert.Equal(t, nil, err) - nazalog.Debugf("sdp=%+v", sdpCtx) + Log.Debugf("sdp=%+v", sdpCtx) } func TestParseARtpMap(t *testing.T) { @@ -145,9 +143,9 @@ func TestParseVpsSpsPps(t *testing.T) { assert.Equal(t, nil, err) vps, sps, pps, err := ParseVpsSpsPps(&f) assert.Equal(t, nil, err) - nazalog.Debugf("%s", hex.Dump(vps)) - nazalog.Debugf("%s", hex.Dump(sps)) - nazalog.Debugf("%s", hex.Dump(pps)) + Log.Debugf("%s", hex.Dump(vps)) + Log.Debugf("%s", hex.Dump(sps)) + Log.Debugf("%s", hex.Dump(pps)) } func TestParseSdp2LogicContext(t *testing.T) { @@ -198,7 +196,7 @@ a=recvonly` assert.IsNotNil(t, ctx.Vps) assert.IsNotNil(t, ctx.Sps) assert.IsNotNil(t, ctx.Pps) - nazalog.Debugf("%+v", ctx) + Log.Debugf("%+v", ctx) } func TestCase3(t *testing.T) { @@ -239,7 +237,7 @@ a=recvonly` assert.Equal(t, nil, ctx.Vps) assert.IsNotNil(t, ctx.Sps) assert.IsNotNil(t, ctx.Pps) - nazalog.Debugf("%+v", ctx) + Log.Debugf("%+v", ctx) } func TestCase4(t *testing.T) { @@ -283,7 +281,7 @@ a=appversion:1.0` assert.Equal(t, nil, ctx.Vps) assert.IsNotNil(t, ctx.Sps) assert.IsNotNil(t, ctx.Pps) - nazalog.Debugf("%+v", ctx) + Log.Debugf("%+v", ctx) } func TestCase5(t *testing.T) { @@ -314,7 +312,7 @@ a=recvonly` assert.Equal(t, nil, ctx.Vps) assert.IsNotNil(t, ctx.Sps) assert.IsNotNil(t, ctx.Pps) - nazalog.Debugf("%+v", ctx) + Log.Debugf("%+v", ctx) } func TestCase6(t *testing.T) { @@ -358,7 +356,7 @@ a=appversion:1.0` assert.Equal(t, nil, ctx.Pps) assert.Equal(t, true, ctx.hasAudio) assert.Equal(t, true, ctx.hasVideo) - nazalog.Debugf("%+v", ctx) + Log.Debugf("%+v", ctx) } // #85 diff --git a/pkg/sdp/var.go b/pkg/sdp/var.go new file mode 100644 index 0000000..054428e --- /dev/null +++ b/pkg/sdp/var.go @@ -0,0 +1,13 @@ +// Copyright 2022, Chef. All rights reserved. +// https://github.com/q191201771/lal +// +// Use of this source code is governed by a MIT-style license +// that can be found in the License file. +// +// Author: Chef (191201771@qq.com) + +package sdp + +import "github.com/q191201771/naza/pkg/nazalog" + +var Log = nazalog.GetGlobalLogger() diff --git a/test.sh b/test.sh index 312c72c..64f4229 100755 --- a/test.sh +++ b/test.sh @@ -53,7 +53,7 @@ mkdir "./testdata/conf" cp ./conf/cert.pem ./conf/key.pem ./testdata/conf/ cp ./conf/cert.pem ./conf/key.pem ./testdata/conf/ -## +## 执行所有pkg里的单元测试,并生成测试覆盖文件 echo "" > coverage.txt for d in $(go list ./... | grep -v vendor | grep pkg | grep -v innertest); do go test -race -coverprofile=profile.out -covermode=atomic $d @@ -63,8 +63,8 @@ for d in $(go list ./... | grep -v vendor | grep pkg | grep -v innertest); do fi done -rm -rf ./pkg/logic/logs ./pkg/rtmp/logs ./pkg/httpflv/logs ./pkg/hls/logs -rm -rf ./pkg/logic/testdata ./pkg/rtmp/testdata ./pkg/httpflv/testdata ./pkg/hls/testdata -rm -rf ./pkg/logic/lal_record ./pkg/rtmp/lal_record ./pkg/httpflv/lal_record ./pkg/hls/lal_record +## 删除测试生成的垃圾文件 +find ./pkg -name 'lal_record' | xargs rm -rf +find ./pkg -name 'logs' | xargs rm -rf echo 'done.'