diff --git a/format/flv/flv.go b/format/flv/flv.go index 76f29137..694d980a 100644 --- a/format/flv/flv.go +++ b/format/flv/flv.go @@ -1,17 +1,17 @@ package flv import ( + "bufio" "fmt" + "github.com/nareix/bits/pio" "github.com/nareix/joy4/av" "github.com/nareix/joy4/av/avutil" - "github.com/nareix/joy4/codec/h264parser" "github.com/nareix/joy4/codec" - "github.com/nareix/joy4/codec/fake" "github.com/nareix/joy4/codec/aacparser" - "github.com/nareix/bits/pio" + "github.com/nareix/joy4/codec/fake" + "github.com/nareix/joy4/codec/h264parser" "github.com/nareix/joy4/format/flv/flvio" "io" - "bufio" ) var MaxProbePacketCount = 20 @@ -60,12 +60,12 @@ func NewMetadataByStreams(streams []av.CodecData) (metadata flvio.AMFMap, err er } type Prober struct { - HasAudio, HasVideo bool - GotAudio, GotVideo bool + HasAudio, HasVideo bool + GotAudio, GotVideo bool VideoStreamIdx, AudioStreamIdx int - PushedCount int - Streams []av.CodecData - CachedPkts []av.Packet + PushedCount int + Streams []av.CodecData + CachedPkts []av.Packet } func (self *Prober) CacheTag(_tag flvio.Tag, timestamp int32) { @@ -73,7 +73,7 @@ func (self *Prober) CacheTag(_tag flvio.Tag, timestamp int32) { self.CachedPkts = append(self.CachedPkts, pkt) } -func (self *Prober) PushTag(_tag flvio.Tag, timestamp int32) (err error) { +func (self *Prober) PushTag(tag flvio.Tag, timestamp int32) (err error) { self.PushedCount++ if self.PushedCount > MaxProbePacketCount { @@ -81,8 +81,8 @@ func (self *Prober) PushTag(_tag flvio.Tag, timestamp int32) (err error) { return } - switch tag := _tag.(type) { - case *flvio.Videodata: + switch tag.Type { + case flvio.TAG_VIDEO: switch tag.AVCPacketType { case flvio.AVC_SEQHDR: if !self.GotVideo { @@ -100,7 +100,7 @@ func (self *Prober) PushTag(_tag flvio.Tag, timestamp int32) (err error) { self.CacheTag(tag, timestamp) } - case *flvio.Audiodata: + case flvio.TAG_AUDIO: switch tag.SoundFormat { case flvio.SOUND_AAC: switch tag.AACPacketType { @@ -132,9 +132,9 @@ func (self *Prober) PushTag(_tag flvio.Tag, timestamp int32) (err error) { case flvio.SOUND_NELLYMOSER: if !self.GotAudio { stream := fake.CodecData{ - CodecType_: av.NELLYMOSER, - SampleRate_: 16000, - SampleFormat_: av.S16, + CodecType_: av.NELLYMOSER, + SampleRate_: 16000, + SampleFormat_: av.S16, ChannelLayout_: tag.ChannelLayout(), } self.AudioStreamIdx = len(self.Streams) @@ -162,9 +162,9 @@ func (self *Prober) Probed() (ok bool) { return } -func (self *Prober) TagToPacket(_tag flvio.Tag, timestamp int32) (pkt av.Packet, ok bool) { - switch tag := _tag.(type) { - case *flvio.Videodata: +func (self *Prober) TagToPacket(tag flvio.Tag, timestamp int32) (pkt av.Packet, ok bool) { + switch tag.Type { + case flvio.TAG_VIDEO: pkt.Idx = int8(self.VideoStreamIdx) switch tag.AVCPacketType { case flvio.AVC_NALU: @@ -174,7 +174,7 @@ func (self *Prober) TagToPacket(_tag flvio.Tag, timestamp int32) (pkt av.Packet, pkt.IsKeyFrame = tag.FrameType == flvio.FRAME_KEY } - case *flvio.Audiodata: + case flvio.TAG_AUDIO: pkt.Idx = int8(self.AudioStreamIdx) switch tag.SoundFormat { case flvio.SOUND_AAC: @@ -212,11 +212,12 @@ func CodecDataToTag(stream av.CodecData) (_tag flvio.Tag, ok bool, err error) { switch stream.Type() { case av.H264: h264 := stream.(h264parser.CodecData) - tag := &flvio.Videodata{ + tag := flvio.Tag{ + Type: flvio.TAG_VIDEO, AVCPacketType: flvio.AVC_SEQHDR, - CodecID: flvio.VIDEO_H264, - Data: h264.AVCDecoderConfRecordBytes(), - FrameType: flvio.FRAME_KEY, + CodecID: flvio.VIDEO_H264, + Data: h264.AVCDecoderConfRecordBytes(), + FrameType: flvio.FRAME_KEY, } ok = true _tag = tag @@ -226,11 +227,12 @@ func CodecDataToTag(stream av.CodecData) (_tag flvio.Tag, ok bool, err error) { case av.AAC: aac := stream.(aacparser.CodecData) - tag := &flvio.Audiodata{ - SoundFormat: flvio.SOUND_AAC, - SoundRate: flvio.SOUND_44Khz, + tag := flvio.Tag{ + Type: flvio.TAG_AUDIO, + SoundFormat: flvio.SOUND_AAC, + SoundRate: flvio.SOUND_44Khz, AACPacketType: flvio.AAC_SEQHDR, - Data: aac.MPEG4AudioConfigBytes(), + Data: aac.MPEG4AudioConfigBytes(), } switch aac.SampleFormat().BytesPerSample() { case 1: @@ -254,13 +256,14 @@ func CodecDataToTag(stream av.CodecData) (_tag flvio.Tag, ok bool, err error) { return } -func PacketToTag(pkt av.Packet, stream av.CodecData) (_tag flvio.Tag, timestamp int32) { +func PacketToTag(pkt av.Packet, stream av.CodecData) (tag flvio.Tag, timestamp int32) { switch stream.Type() { case av.H264: - tag := &flvio.Videodata{ - AVCPacketType: flvio.AVC_NALU, - CodecID: flvio.VIDEO_H264, - Data: pkt.Data, + tag = flvio.Tag{ + Type: flvio.TAG_VIDEO, + AVCPacketType: flvio.AVC_NALU, + CodecID: flvio.VIDEO_H264, + Data: pkt.Data, CompositionTime: flvio.TimeToTs(pkt.CompositionTime), } if pkt.IsKeyFrame { @@ -268,14 +271,14 @@ func PacketToTag(pkt av.Packet, stream av.CodecData) (_tag flvio.Tag, timestamp } else { tag.FrameType = flvio.FRAME_INTER } - _tag = tag case av.AAC: - tag := &flvio.Audiodata{ - SoundFormat: flvio.SOUND_AAC, - SoundRate: flvio.SOUND_44Khz, + tag = flvio.Tag{ + Type: flvio.TAG_AUDIO, + SoundFormat: flvio.SOUND_AAC, + SoundRate: flvio.SOUND_44Khz, AACPacketType: flvio.AAC_RAW, - Data: pkt.Data, + Data: pkt.Data, } astream := stream.(av.AudioCodecData) switch astream.SampleFormat().BytesPerSample() { @@ -290,21 +293,20 @@ func PacketToTag(pkt av.Packet, stream av.CodecData) (_tag flvio.Tag, timestamp case 2: tag.SoundType = flvio.SOUND_STEREO } - _tag = tag case av.SPEEX: - tag := &flvio.Audiodata{ + tag = flvio.Tag{ + Type: flvio.TAG_AUDIO, SoundFormat: flvio.SOUND_SPEEX, - Data: pkt.Data, + Data: pkt.Data, } - _tag = tag case av.NELLYMOSER: - tag := &flvio.Audiodata{ + tag = flvio.Tag{ + Type: flvio.TAG_AUDIO, SoundFormat: flvio.SOUND_NELLYMOSER, - Data: pkt.Data, + Data: pkt.Data, } - _tag = tag } timestamp = flvio.TimeToTs(pkt.Time) @@ -312,8 +314,8 @@ func PacketToTag(pkt av.Packet, stream av.CodecData) (_tag flvio.Tag, timestamp } type Muxer struct { - bufw writeFlusher - b []byte + bufw writeFlusher + b []byte streams []av.CodecData } @@ -325,7 +327,7 @@ type writeFlusher interface { func NewMuxerWriteFlusher(w writeFlusher) *Muxer { return &Muxer{ bufw: w, - b: make([]byte, 256), + b: make([]byte, 256), } } @@ -386,16 +388,16 @@ func (self *Muxer) WriteTrailer() (err error) { type Demuxer struct { prober *Prober - bufr *bufio.Reader - b []byte - stage int + bufr *bufio.Reader + b []byte + stage int } func NewDemuxer(r io.Reader) *Demuxer { return &Demuxer{ - bufr: bufio.NewReaderSize(r, pio.RecommendBufioSize), + bufr: bufio.NewReaderSize(r, pio.RecommendBufioSize), prober: &Prober{}, - b: make([]byte, 256), + b: make([]byte, 256), } } @@ -414,10 +416,10 @@ func (self *Demuxer) prepare() (err error) { if _, err = self.bufr.Discard(skip); err != nil { return } - if flags & flvio.FILE_HAS_AUDIO != 0 { + if flags&flvio.FILE_HAS_AUDIO != 0 { self.prober.HasAudio = true } - if flags & flvio.FILE_HAS_VIDEO != 0 { + if flags&flvio.FILE_HAS_VIDEO != 0 { self.prober.HasVideo = true } self.stage++ @@ -490,4 +492,3 @@ func Handler(h *avutil.RegisterHandler) { h.CodecTypes = CodecTypes } - diff --git a/format/flv/flvio/flvio.go b/format/flv/flvio/flvio.go index 9acc2737..eb063a5c 100644 --- a/format/flv/flvio/flvio.go +++ b/format/flv/flvio/flvio.go @@ -1,70 +1,38 @@ package flvio import ( - "io" - "time" "fmt" "github.com/nareix/bits/pio" "github.com/nareix/joy4/av" + "io" + "time" ) func TsToTime(ts int32) time.Duration { - return time.Millisecond*time.Duration(ts) + return time.Millisecond * time.Duration(ts) } func TimeToTs(tm time.Duration) int32 { return int32(tm / time.Millisecond) } +const MaxTagSubHeaderLength = 16 + const ( TAG_AUDIO = 8 TAG_VIDEO = 9 TAG_SCRIPTDATA = 18 ) -const MaxTagSubHeaderLength = 16 - -type Tag interface { - Type() uint8 - GetData() []byte - SetData([]byte) - FillHeader([]byte) int - ParseHeader([]byte) (int,error) -} - -type Scriptdata struct { - Data []byte -} - -func (self Scriptdata) Type() uint8 { - return TAG_SCRIPTDATA -} - -func (self *Scriptdata) FillHeader(b []byte) (n int) { - return -} - -func (self *Scriptdata) ParseHeader(b []byte) (n int, err error) { - return -} - -func (self Scriptdata) GetData() []byte { - return self.Data -} - -func (self *Scriptdata) SetData(b []byte) { - self.Data = b -} - const ( - SOUND_MP3 = 2 + SOUND_MP3 = 2 SOUND_NELLYMOSER_16KHZ_MONO = 4 - SOUND_NELLYMOSER_8KHZ_MONO = 5 - SOUND_NELLYMOSER = 6 - SOUND_ALAW = 7 - SOUND_MULAW = 8 - SOUND_AAC = 10 - SOUND_SPEEX = 11 + SOUND_NELLYMOSER_8KHZ_MONO = 5 + SOUND_NELLYMOSER = 6 + SOUND_ALAW = 7 + SOUND_MULAW = 8 + SOUND_AAC = 10 + SOUND_SPEEX = 11 SOUND_5_5Khz = 0 SOUND_11Khz = 1 @@ -81,7 +49,20 @@ const ( AAC_RAW = 1 ) -type Audiodata struct { +const ( + AVC_SEQHDR = 0 + AVC_NALU = 1 + AVC_EOS = 2 + + FRAME_KEY = 1 + FRAME_INTER = 2 + + VIDEO_H264 = 7 +) + +type Tag struct { + Type uint8 + /* SoundFormat: UB[4] 0 = Linear PCM, platform endian @@ -139,14 +120,39 @@ type Audiodata struct { */ AACPacketType uint8 - Data []byte -} + /* + 1: keyframe (for AVC, a seekable frame) + 2: inter frame (for AVC, a non- seekable frame) + 3: disposable inter frame (H.263 only) + 4: generated keyframe (reserved for server use only) + 5: video info/command frame + */ + FrameType uint8 + + /* + 1: JPEG (currently unused) + 2: Sorenson H.263 + 3: Screen video + 4: On2 VP6 + 5: On2 VP6 with alpha channel + 6: Screen video version 2 + 7: AVC + */ + CodecID uint8 + + /* + 0: AVC sequence header + 1: AVC NALU + 2: AVC end of sequence (lower level NALU sequence ender is not required or supported) + */ + AVCPacketType uint8 + + CompositionTime int32 -func (self Audiodata) Type() uint8 { - return TAG_AUDIO + Data []byte } -func (self Audiodata) ChannelLayout() av.ChannelLayout { +func (self Tag) ChannelLayout() av.ChannelLayout { if self.SoundType == SOUND_MONO { return av.CH_MONO } else { @@ -154,7 +160,7 @@ func (self Audiodata) ChannelLayout() av.ChannelLayout { } } -func (self *Audiodata) ParseHeader(b []byte) (n int, err error) { +func (self *Tag) audioParseHeader(b []byte) (n int, err error) { if len(b) < n+1 { err = fmt.Errorf("audiodata: parse invalid") return @@ -180,7 +186,7 @@ func (self *Audiodata) ParseHeader(b []byte) (n int, err error) { return } -func (self Audiodata) FillHeader(b []byte) (n int) { +func (self Tag) audioFillHeader(b []byte) (n int) { var flags uint8 flags |= self.SoundFormat << 4 flags |= self.SoundRate << 2 @@ -198,62 +204,7 @@ func (self Audiodata) FillHeader(b []byte) (n int) { return } -func (self Audiodata) GetData() []byte { - return self.Data -} - -func (self *Audiodata) SetData(b []byte) { - self.Data = b -} - -const ( - AVC_SEQHDR = 0 - AVC_NALU = 1 - AVC_EOS = 2 - - FRAME_KEY = 1 - FRAME_INTER = 2 - - VIDEO_H264 = 7 -) - -type Videodata struct { - /* - 1: keyframe (for AVC, a seekable frame) - 2: inter frame (for AVC, a non- seekable frame) - 3: disposable inter frame (H.263 only) - 4: generated keyframe (reserved for server use only) - 5: video info/command frame - */ - FrameType uint8 - - /* - 1: JPEG (currently unused) - 2: Sorenson H.263 - 3: Screen video - 4: On2 VP6 - 5: On2 VP6 with alpha channel - 6: Screen video version 2 - 7: AVC - */ - CodecID uint8 - - /* - 0: AVC sequence header - 1: AVC NALU - 2: AVC end of sequence (lower level NALU sequence ender is not required or supported) - */ - AVCPacketType uint8 - - Data []byte - CompositionTime int32 -} - -func (self Videodata) Type() uint8 { - return TAG_VIDEO -} - -func (self *Videodata) ParseHeader(b []byte) (n int, err error) { +func (self *Tag) videoParseHeader(b []byte) (n int, err error) { if len(b) < n+1 { err = fmt.Errorf("videodata: parse invalid") return @@ -278,7 +229,7 @@ func (self *Videodata) ParseHeader(b []byte) (n int, err error) { return } -func (self Videodata) FillHeader(b []byte) (n int) { +func (self Tag) videoFillHeader(b []byte) (n int) { flags := self.FrameType<<4 | self.CodecID b[n] = flags n++ @@ -289,12 +240,28 @@ func (self Videodata) FillHeader(b []byte) (n int) { return } -func (self Videodata) GetData() []byte { - return self.Data +func (self Tag) FillHeader(b []byte) (n int) { + switch self.Type { + case TAG_AUDIO: + return self.audioFillHeader(b) + + case TAG_VIDEO: + return self.videoFillHeader(b) + } + + return } -func (self *Videodata) SetData(b []byte) { - self.Data = b +func (self *Tag) ParseHeader(b []byte) (n int, err error) { + switch self.Type { + case TAG_AUDIO: + return self.audioParseHeader(b) + + case TAG_VIDEO: + return self.videoParseHeader(b) + } + + return } const ( @@ -313,14 +280,8 @@ func ParseTagHeader(b []byte) (tag Tag, ts int32, datalen int, err error) { tagtype := b[0] switch tagtype { - case TAG_AUDIO: - tag = &Audiodata{} - - case TAG_VIDEO: - tag = &Videodata{} - - case TAG_SCRIPTDATA: - tag = &Scriptdata{} + case TAG_AUDIO, TAG_VIDEO, TAG_SCRIPTDATA: + tag = Tag{Type: tagtype} default: err = fmt.Errorf("flvio: ReadTag tagtype=%d invalid", tagtype) @@ -333,7 +294,7 @@ func ParseTagHeader(b []byte) (tag Tag, ts int32, datalen int, err error) { var tshi uint8 tslo = pio.U24BE(b[4:7]) tshi = b[7] - ts = int32(tslo|uint32(tshi)<<24) + ts = int32(tslo | uint32(tshi)<<24) return } @@ -353,10 +314,10 @@ func ReadTag(r io.Reader, b []byte) (tag Tag, ts int32, err error) { } var n int - if n, err = tag.ParseHeader(data); err != nil { + if n, err = (&tag).ParseHeader(data); err != nil { return } - tag.SetData(data[n:]) + tag.Data = data[n:] if _, err = io.ReadFull(r, b[:4]); err != nil { return @@ -369,7 +330,7 @@ func FillTagHeader(b []byte, tagtype uint8, datalen int, ts int32) (n int) { n++ pio.PutU24BE(b[n:], uint32(datalen)) n += 3 - pio.PutU24BE(b[n:], uint32(ts & 0xffffff)) + pio.PutU24BE(b[n:], uint32(ts&0xffffff)) n += 3 b[n] = uint8(ts >> 24) n++ @@ -385,12 +346,12 @@ func FillTagTrailer(b []byte, datalen int) (n int) { } func WriteTag(w io.Writer, tag Tag, ts int32, b []byte) (err error) { - data := tag.GetData() + data := tag.Data n := tag.FillHeader(b[TagHeaderLength:]) - datalen := len(data)+n + datalen := len(data) + n - n += FillTagHeader(b, tag.Type(), datalen, ts) + n += FillTagHeader(b, tag.Type, datalen, ts) if _, err = w.Write(b[:n]); err != nil { return @@ -439,7 +400,7 @@ func ParseFileHeader(b []byte) (flags uint8, skip int, err error) { flags = b[4] - skip = int(pio.U32BE(b[5:9]))-9+4 + skip = int(pio.U32BE(b[5:9])) - 9 + 4 if skip < 0 { err = fmt.Errorf("flvio: file header datasize invalid") return @@ -447,5 +408,3 @@ func ParseFileHeader(b []byte) (flags uint8, skip int, err error) { return } - - diff --git a/format/rtmp/rtmp.go b/format/rtmp/rtmp.go index fefa585b..4023afc8 100644 --- a/format/rtmp/rtmp.go +++ b/format/rtmp/rtmp.go @@ -1,27 +1,26 @@ - package rtmp import ( - "strings" - "bytes" - "net" - "net/url" "bufio" - "time" - "fmt" + "bytes" + "crypto/hmac" + "crypto/rand" + "crypto/sha256" "encoding/hex" - "io" + "fmt" "github.com/nareix/bits/pio" - "github.com/nareix/joy4/format/flv" - "github.com/nareix/joy4/format/flv/flvio" "github.com/nareix/joy4/av" "github.com/nareix/joy4/av/avutil" - "crypto/hmac" - "crypto/sha256" - "crypto/rand" + "github.com/nareix/joy4/format/flv" + "github.com/nareix/joy4/format/flv/flvio" + "io" + "net" + "net/url" + "strings" + "time" ) -var Debug bool +var Debug bool func ParseURL(uri string) (u *url.URL, err error) { if u, err = url.Parse(uri); err != nil { @@ -55,10 +54,10 @@ func DialTimeout(uri string, timeout time.Duration) (conn *Conn, err error) { } type Server struct { - Addr string + Addr string HandlePublish func(*Conn) - HandlePlay func(*Conn) - HandleConn func(*Conn) + HandlePlay func(*Conn) + HandleConn func(*Conn) } func (self *Server) handleConn(conn *Conn) (err error) { @@ -125,21 +124,21 @@ func (self *Server) ListenAndServe() (err error) { } const ( - stageHandshakeDone = iota+1 + stageHandshakeDone = iota + 1 stageCommandDone stageCodecDataDone ) const ( - prepareReading = iota+1 + prepareReading = iota + 1 prepareWriting ) type Conn struct { - URL *url.URL - OnPlayOrPublish func(string,flvio.AMFMap) error + URL *url.URL + OnPlayOrPublish func(string, flvio.AMFMap) error - prober *flv.Prober + prober *flv.Prober streams []av.CodecData txbytes uint64 @@ -148,37 +147,37 @@ type Conn struct { bufr *bufio.Reader bufw *bufio.Writer ackn uint32 + writebuf []byte - readbuf []byte + readbuf []byte - netconn net.Conn + netconn net.Conn txrxcount *txrxcount writeMaxChunkSize int - readMaxChunkSize int - readAckSize uint32 - readcsmap map[uint32]*chunkStream + readMaxChunkSize int + readAckSize uint32 + readcsmap map[uint32]*chunkStream - isserver bool + isserver bool publishing, playing bool - reading, writing bool - stage int + reading, writing bool + stage int avmsgsid uint32 - gotcommand bool - commandname string + gotcommand bool + commandname string commandtransid float64 - commandobj flvio.AMFMap - commandparams []interface{} + commandobj flvio.AMFMap + commandparams []interface{} - gotmsg bool - timestamp uint32 - msgdata []byte - msgtypeid uint8 + gotmsg bool + timestamp uint32 + msgdata []byte + msgtypeid uint8 datamsgvals []interface{} - videodata *flvio.Videodata - audiodata *flvio.Audiodata + avtag flvio.Tag eventtype uint16 } @@ -217,15 +216,15 @@ func NewConn(netconn net.Conn) *Conn { } type chunkStream struct { - timenow uint32 - timedelta uint32 - hastimeext bool - msgsid uint32 - msgtypeid uint8 - msgdatalen uint32 + timenow uint32 + timedelta uint32 + hastimeext bool + msgsid uint32 + msgtypeid uint8 + msgdatalen uint32 msgdataleft uint32 - msghdrtype uint8 - msgdata []byte + msghdrtype uint8 + msgdata []byte } func (self *chunkStream) Start() { @@ -234,22 +233,22 @@ func (self *chunkStream) Start() { } const ( - msgtypeidUserControl = 4 - msgtypeidAck = 3 - msgtypeidWindowAckSize = 5 + msgtypeidUserControl = 4 + msgtypeidAck = 3 + msgtypeidWindowAckSize = 5 msgtypeidSetPeerBandwidth = 6 - msgtypeidSetChunkSize = 1 - msgtypeidCommandMsgAMF0 = 20 - msgtypeidCommandMsgAMF3 = 17 - msgtypeidDataMsgAMF0 = 18 - msgtypeidDataMsgAMF3 = 15 - msgtypeidVideoMsg = 9 - msgtypeidAudioMsg = 8 + msgtypeidSetChunkSize = 1 + msgtypeidCommandMsgAMF0 = 20 + msgtypeidCommandMsgAMF3 = 17 + msgtypeidDataMsgAMF0 = 18 + msgtypeidDataMsgAMF3 = 15 + msgtypeidVideoMsg = 9 + msgtypeidAudioMsg = 8 ) const ( - eventtypeStreamBegin = 0 - eventtypeSetBufferLength = 3 + eventtypeStreamBegin = 0 + eventtypeSetBufferLength = 3 eventtypeStreamIsRecorded = 4 ) @@ -286,11 +285,8 @@ func (self *Conn) pollAVTag() (tag flvio.Tag, err error) { return } switch self.msgtypeid { - case msgtypeidVideoMsg: - tag = self.videodata - return - case msgtypeidAudioMsg: - tag = self.audiodata + case msgtypeidVideoMsg, msgtypeidAudioMsg: + tag = self.avtag return } } @@ -300,8 +296,7 @@ func (self *Conn) pollMsg() (err error) { self.gotmsg = false self.gotcommand = false self.datamsgvals = nil - self.videodata = nil - self.audiodata = nil + self.avtag = flvio.Tag{} for { if err = self.readChunk(); err != nil { return @@ -326,7 +321,7 @@ func SplitPath(u *url.URL) (app, stream string) { func getTcUrl(u *url.URL) string { app, _ := SplitPath(u) nu := *u - nu.Path = "/"+app + nu.Path = "/" + app return nu.String() } @@ -358,7 +353,7 @@ var CodecTypes = flv.CodecTypes func (self *Conn) writeBasicConf() (err error) { // > SetChunkSize - if err = self.writeSetChunkSize(1024*1024*128); err != nil { + if err = self.writeSetChunkSize(1024 * 1024 * 128); err != nil { return } // > WindowAckSize @@ -412,13 +407,13 @@ func (self *Conn) readConnect() (err error) { // > _result("NetConnection.Connect.Success") if err = self.writeCommandMsg(3, 0, "_result", self.commandtransid, flvio.AMFMap{ - "fmtVer": "FMS/3,0,1,123", + "fmtVer": "FMS/3,0,1,123", "capabilities": 31, }, flvio.AMFMap{ - "level": "status", - "code": "NetConnection.Connect.Success", - "description": "Connection succeeded.", + "level": "status", + "code": "NetConnection.Connect.Success", + "description": "Connection succeeded.", "objectEncoding": 3, }, ); err != nil { @@ -478,9 +473,9 @@ func (self *Conn) readConnect() (err error) { if err = self.writeCommandMsg(5, self.avmsgsid, "onStatus", self.commandtransid, nil, flvio.AMFMap{ - "level": "status", - "code": code, - "description": description, + "level": "status", + "code": "NetStream.Publish.Start", + "description": "Start publishing", }, ); err != nil { return @@ -521,8 +516,8 @@ func (self *Conn) readConnect() (err error) { if err = self.writeCommandMsg(5, self.avmsgsid, "onStatus", self.commandtransid, nil, flvio.AMFMap{ - "level": "status", - "code": "NetStream.Play.Start", + "level": "status", + "code": "NetStream.Play.Start", "description": "Start live", }, ); err != nil { @@ -619,13 +614,13 @@ func (self *Conn) writeConnect(path string) (err error) { } if err = self.writeCommandMsg(3, 0, "connect", 1, flvio.AMFMap{ - "app": path, - "flashVer": "MAC 22,0,0,192", - "tcUrl": getTcUrl(self.URL), - "fpad": false, - "capabilities": 15, - "audioCodecs": 4071, - "videoCodecs": 252, + "app": path, + "flashVer": "MAC 22,0,0,192", + "tcUrl": getTcUrl(self.URL), + "fpad": false, + "capabilities": 15, + "audioCodecs": 4071, + "videoCodecs": 252, "videoFunction": 1, }, ); err != nil { @@ -937,7 +932,7 @@ func (self *Conn) tmpwbuf(n int) []byte { func (self *Conn) writeSetChunkSize(size int) (err error) { self.writeMaxChunkSize = size - b := self.tmpwbuf(chunkHeaderLength+4) + b := self.tmpwbuf(chunkHeaderLength + 4) n := self.fillChunkHeader(b, 2, 0, msgtypeidSetChunkSize, 0, 4) pio.PutU32BE(b[n:], uint32(size)) n += 4 @@ -946,7 +941,7 @@ func (self *Conn) writeSetChunkSize(size int) (err error) { } func (self *Conn) writeAck(seqnum uint32) (err error) { - b := self.tmpwbuf(chunkHeaderLength+4) + b := self.tmpwbuf(chunkHeaderLength + 4) n := self.fillChunkHeader(b, 2, 0, msgtypeidAck, 0, 4) pio.PutU32BE(b[n:], seqnum) n += 4 @@ -955,7 +950,7 @@ func (self *Conn) writeAck(seqnum uint32) (err error) { } func (self *Conn) writeWindowAckSize(size uint32) (err error) { - b := self.tmpwbuf(chunkHeaderLength+4) + b := self.tmpwbuf(chunkHeaderLength + 4) n := self.fillChunkHeader(b, 2, 0, msgtypeidWindowAckSize, 0, 4) pio.PutU32BE(b[n:], size) n += 4 @@ -964,7 +959,7 @@ func (self *Conn) writeWindowAckSize(size uint32) (err error) { } func (self *Conn) writeSetPeerBandwidth(acksize uint32, limittype uint8) (err error) { - b := self.tmpwbuf(chunkHeaderLength+5) + b := self.tmpwbuf(chunkHeaderLength + 5) n := self.fillChunkHeader(b, 2, 0, msgtypeidSetPeerBandwidth, 0, 5) pio.PutU32BE(b[n:], acksize) n += 4 @@ -974,21 +969,21 @@ func (self *Conn) writeSetPeerBandwidth(acksize uint32, limittype uint8) (err er return } -func (self *Conn) writeCommandMsg(csid, msgsid uint32, args... interface{}) (err error) { +func (self *Conn) writeCommandMsg(csid, msgsid uint32, args ...interface{}) (err error) { return self.writeAMF0Msg(msgtypeidCommandMsgAMF0, csid, msgsid, args...) } -func (self *Conn) writeDataMsg(csid, msgsid uint32, args... interface{}) (err error) { +func (self *Conn) writeDataMsg(csid, msgsid uint32, args ...interface{}) (err error) { return self.writeAMF0Msg(msgtypeidDataMsgAMF0, csid, msgsid, args...) } -func (self *Conn) writeAMF0Msg(msgtypeid uint8, csid, msgsid uint32, args... interface{}) (err error) { +func (self *Conn) writeAMF0Msg(msgtypeid uint8, csid, msgsid uint32, args ...interface{}) (err error) { size := 0 for _, arg := range args { size += flvio.LenAMF0Val(arg) } - b := self.tmpwbuf(chunkHeaderLength+size) + b := self.tmpwbuf(chunkHeaderLength + size) n := self.fillChunkHeader(b, csid, 0, msgtypeid, msgsid, size) for _, arg := range args { n += flvio.FillAMF0Val(b[n:], arg) @@ -1003,25 +998,25 @@ func (self *Conn) writeAVTag(tag flvio.Tag, ts int32) (err error) { var csid uint32 var data []byte - switch _tag := tag.(type) { - case *flvio.Audiodata: + switch tag.Type { + case flvio.TAG_AUDIO: msgtypeid = msgtypeidAudioMsg csid = 6 - data = _tag.Data + data = tag.Data - case *flvio.Videodata: + case flvio.TAG_VIDEO: msgtypeid = msgtypeidVideoMsg csid = 7 - data = _tag.Data + data = tag.Data } - b := self.tmpwbuf(chunkHeaderLength+flvio.MaxTagSubHeaderLength) + b := self.tmpwbuf(chunkHeaderLength + flvio.MaxTagSubHeaderLength) hdrlen := tag.FillHeader(b[chunkHeaderLength:]) self.fillChunkHeader(b, csid, ts, msgtypeid, self.avmsgsid, hdrlen+len(data)) - n := hdrlen+chunkHeaderLength + n := hdrlen + chunkHeaderLength if n+len(data) > self.writeMaxChunkSize { - if err = self.writeSetChunkSize(n+len(data)); err != nil { + if err = self.writeSetChunkSize(n + len(data)); err != nil { return } } @@ -1034,7 +1029,7 @@ func (self *Conn) writeAVTag(tag flvio.Tag, ts int32) (err error) { } func (self *Conn) writeStreamBegin(msgsid uint32) (err error) { - b := self.tmpwbuf(chunkHeaderLength+6) + b := self.tmpwbuf(chunkHeaderLength + 6) n := self.fillChunkHeader(b, 2, 0, msgtypeidUserControl, 0, 6) pio.PutU16BE(b[n:], eventtypeStreamBegin) n += 2 @@ -1045,7 +1040,7 @@ func (self *Conn) writeStreamBegin(msgsid uint32) (err error) { } func (self *Conn) writeSetBufferLength(msgsid uint32, timestamp uint32) (err error) { - b := self.tmpwbuf(chunkHeaderLength+10) + b := self.tmpwbuf(chunkHeaderLength + 10) n := self.fillChunkHeader(b, 2, 0, msgtypeidUserControl, 0, 10) pio.PutU16BE(b[n:], eventtypeSetBufferLength) n += 2 @@ -1072,7 +1067,7 @@ func (self *Conn) fillChunkHeader(b []byte, csid uint32, timestamp int32, msgtyp // // Figure 9 Chunk Message Header – Type 0 - b[n] = byte(csid)&0x3f + b[n] = byte(csid) & 0x3f n++ pio.PutU24BE(b[n:], uint32(timestamp)) n += 3 @@ -1109,9 +1104,9 @@ func (self *Conn) readChunk() (err error) { var msghdrtype uint8 var csid uint32 - msghdrtype = header>>6 + msghdrtype = header >> 6 - csid = uint32(header)&0x3f + csid = uint32(header) & 0x3f switch csid { default: // Chunk basic header 1 case 0: // Chunk basic header 2 @@ -1119,13 +1114,13 @@ func (self *Conn) readChunk() (err error) { return } n += 1 - csid = uint32(b[0])+64 + csid = uint32(b[0]) + 64 case 1: // Chunk basic header 3 if _, err = io.ReadFull(self.bufr, b[:2]); err != nil { return } n += 2 - csid = uint32(pio.U16BE(b))+64 + csid = uint32(pio.U16BE(b)) + 64 } cs := self.readcsmap[csid] @@ -1282,8 +1277,8 @@ func (self *Conn) readChunk() (err error) { if size > self.readMaxChunkSize { size = self.readMaxChunkSize } - off := cs.msgdatalen-cs.msgdataleft - buf := cs.msgdata[off:int(off)+size] + off := cs.msgdatalen - cs.msgdataleft + buf := cs.msgdata[off : int(off)+size] if _, err = io.ReadFull(self.bufr, buf); err != nil { return } @@ -1408,28 +1403,28 @@ func (self *Conn) handleMsg(timestamp uint32, msgsid uint32, msgtypeid uint8, ms if len(msgdata) == 0 { return } - tag := &flvio.Videodata{} + tag := flvio.Tag{Type: flvio.TAG_VIDEO} var n int - if n, err = tag.ParseHeader(msgdata); err != nil { + if n, err = (&tag).ParseHeader(msgdata); err != nil { return } if !(tag.FrameType == flvio.FRAME_INTER || tag.FrameType == flvio.FRAME_KEY) { return } tag.Data = msgdata[n:] - self.videodata = tag + self.avtag = tag case msgtypeidAudioMsg: if len(msgdata) == 0 { return } - tag := &flvio.Audiodata{} + tag := flvio.Tag{Type: flvio.TAG_AUDIO} var n int - if n, err = tag.ParseHeader(msgdata); err != nil { + if n, err = (&tag).ParseHeader(msgdata); err != nil { return } tag.Data = msgdata[n:] - self.audiodata = tag + self.avtag = tag case msgtypeidSetChunkSize: if len(msgdata) < 4 { @@ -1481,7 +1476,7 @@ func hsCalcDigestPos(p []byte, base int) (pos int) { for i := 0; i < 4; i++ { pos += int(p[base+i]) } - pos = (pos%728)+base+4 + pos = (pos % 728) + base + 4 return } @@ -1519,13 +1514,13 @@ func hsCreate01(p []byte, time uint32, ver uint32, key []byte) { func hsCreate2(p []byte, key []byte) { rand.Read(p) - gap := len(p)-32 + gap := len(p) - 32 digest := hsMakeDigest(key, p, gap) copy(p[gap:], digest) } func (self *Conn) handshakeClient() (err error) { - var random [(1+1536*2)*2]byte + var random [(1 + 1536*2) * 2]byte C0C1C2 := random[:1536*2+1] C0 := C0C1C2[:1] @@ -1535,7 +1530,7 @@ func (self *Conn) handshakeClient() (err error) { S0S1S2 := random[1536*2+1:] //S0 := S0S1S2[:1] - S1 := S0S1S2[1:1536+1] + S1 := S0S1S2[1 : 1536+1] //S0S1 := S0S1S2[:1536+1] //S2 := S0S1S2[1536+1:] @@ -1556,7 +1551,7 @@ func (self *Conn) handshakeClient() (err error) { } if Debug { - fmt.Println("rtmp: handshakeClient: server version", S1[4],S1[5],S1[6],S1[7]) + fmt.Println("rtmp: handshakeClient: server version", S1[4], S1[5], S1[6], S1[7]) } if ver := pio.U32BE(S1[4:8]); ver != 0 { @@ -1575,17 +1570,17 @@ func (self *Conn) handshakeClient() (err error) { } func (self *Conn) handshakeServer() (err error) { - var random [(1+1536*2)*2]byte + var random [(1 + 1536*2) * 2]byte C0C1C2 := random[:1536*2+1] C0 := C0C1C2[:1] - C1 := C0C1C2[1:1536+1] + C1 := C0C1C2[1 : 1536+1] C0C1 := C0C1C2[:1536+1] C2 := C0C1C2[1536+1:] S0S1S2 := random[1536*2+1:] S0 := S0S1S2[:1] - S1 := S0S1S2[1:1536+1] + S1 := S0S1S2[1 : 1536+1] S0S1 := S0S1S2[:1536+1] S2 := S0S1S2[1536+1:] @@ -1749,4 +1744,3 @@ func Handler(h *avutil.RegisterHandler) { h.CodecTypes = CodecTypes } -