change flvio.Tag from interface to struct
This commit is contained in:
parent
a76cfa1413
commit
b3b189ca28
@ -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
|
||||
}
|
||||
|
||||
|
@ -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,85 +120,6 @@ type Audiodata struct {
|
||||
*/
|
||||
AACPacketType uint8
|
||||
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func (self Audiodata) Type() uint8 {
|
||||
return TAG_AUDIO
|
||||
}
|
||||
|
||||
func (self Audiodata) ChannelLayout() av.ChannelLayout {
|
||||
if self.SoundType == SOUND_MONO {
|
||||
return av.CH_MONO
|
||||
} else {
|
||||
return av.CH_STEREO
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Audiodata) ParseHeader(b []byte) (n int, err error) {
|
||||
if len(b) < n+1 {
|
||||
err = fmt.Errorf("audiodata: parse invalid")
|
||||
return
|
||||
}
|
||||
|
||||
flags := b[n]
|
||||
n++
|
||||
self.SoundFormat = flags >> 4
|
||||
self.SoundRate = (flags >> 2) & 0x3
|
||||
self.SoundSize = (flags >> 1) & 0x1
|
||||
self.SoundType = flags & 0x1
|
||||
|
||||
switch self.SoundFormat {
|
||||
case SOUND_AAC:
|
||||
if len(b) < n+1 {
|
||||
err = fmt.Errorf("audiodata: parse invalid")
|
||||
return
|
||||
}
|
||||
self.AACPacketType = b[n]
|
||||
n++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (self Audiodata) FillHeader(b []byte) (n int) {
|
||||
var flags uint8
|
||||
flags |= self.SoundFormat << 4
|
||||
flags |= self.SoundRate << 2
|
||||
flags |= self.SoundSize << 1
|
||||
flags |= self.SoundType
|
||||
b[n] = flags
|
||||
n++
|
||||
|
||||
switch self.SoundFormat {
|
||||
case SOUND_AAC:
|
||||
b[n] = self.AACPacketType
|
||||
n++
|
||||
}
|
||||
|
||||
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)
|
||||
@ -245,15 +147,64 @@ type Videodata struct {
|
||||
*/
|
||||
AVCPacketType uint8
|
||||
|
||||
Data []byte
|
||||
CompositionTime int32
|
||||
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func (self Videodata) Type() uint8 {
|
||||
return TAG_VIDEO
|
||||
func (self Tag) ChannelLayout() av.ChannelLayout {
|
||||
if self.SoundType == SOUND_MONO {
|
||||
return av.CH_MONO
|
||||
} else {
|
||||
return av.CH_STEREO
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Videodata) 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
|
||||
}
|
||||
|
||||
flags := b[n]
|
||||
n++
|
||||
self.SoundFormat = flags >> 4
|
||||
self.SoundRate = (flags >> 2) & 0x3
|
||||
self.SoundSize = (flags >> 1) & 0x1
|
||||
self.SoundType = flags & 0x1
|
||||
|
||||
switch self.SoundFormat {
|
||||
case SOUND_AAC:
|
||||
if len(b) < n+1 {
|
||||
err = fmt.Errorf("audiodata: parse invalid")
|
||||
return
|
||||
}
|
||||
self.AACPacketType = b[n]
|
||||
n++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (self Tag) audioFillHeader(b []byte) (n int) {
|
||||
var flags uint8
|
||||
flags |= self.SoundFormat << 4
|
||||
flags |= self.SoundRate << 2
|
||||
flags |= self.SoundSize << 1
|
||||
flags |= self.SoundType
|
||||
b[n] = flags
|
||||
n++
|
||||
|
||||
switch self.SoundFormat {
|
||||
case SOUND_AAC:
|
||||
b[n] = self.AACPacketType
|
||||
n++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
netconn net.Conn
|
||||
writebuf []byte
|
||||
readbuf []byte
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user