change flvio.Tag from interface to struct
This commit is contained in:
parent
a76cfa1413
commit
b3b189ca28
@ -1,17 +1,17 @@
|
|||||||
package flv
|
package flv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/nareix/bits/pio"
|
||||||
"github.com/nareix/joy4/av"
|
"github.com/nareix/joy4/av"
|
||||||
"github.com/nareix/joy4/av/avutil"
|
"github.com/nareix/joy4/av/avutil"
|
||||||
"github.com/nareix/joy4/codec/h264parser"
|
|
||||||
"github.com/nareix/joy4/codec"
|
"github.com/nareix/joy4/codec"
|
||||||
"github.com/nareix/joy4/codec/fake"
|
|
||||||
"github.com/nareix/joy4/codec/aacparser"
|
"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"
|
"github.com/nareix/joy4/format/flv/flvio"
|
||||||
"io"
|
"io"
|
||||||
"bufio"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var MaxProbePacketCount = 20
|
var MaxProbePacketCount = 20
|
||||||
@ -73,7 +73,7 @@ func (self *Prober) CacheTag(_tag flvio.Tag, timestamp int32) {
|
|||||||
self.CachedPkts = append(self.CachedPkts, pkt)
|
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++
|
self.PushedCount++
|
||||||
|
|
||||||
if self.PushedCount > MaxProbePacketCount {
|
if self.PushedCount > MaxProbePacketCount {
|
||||||
@ -81,8 +81,8 @@ func (self *Prober) PushTag(_tag flvio.Tag, timestamp int32) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch tag := _tag.(type) {
|
switch tag.Type {
|
||||||
case *flvio.Videodata:
|
case flvio.TAG_VIDEO:
|
||||||
switch tag.AVCPacketType {
|
switch tag.AVCPacketType {
|
||||||
case flvio.AVC_SEQHDR:
|
case flvio.AVC_SEQHDR:
|
||||||
if !self.GotVideo {
|
if !self.GotVideo {
|
||||||
@ -100,7 +100,7 @@ func (self *Prober) PushTag(_tag flvio.Tag, timestamp int32) (err error) {
|
|||||||
self.CacheTag(tag, timestamp)
|
self.CacheTag(tag, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
case *flvio.Audiodata:
|
case flvio.TAG_AUDIO:
|
||||||
switch tag.SoundFormat {
|
switch tag.SoundFormat {
|
||||||
case flvio.SOUND_AAC:
|
case flvio.SOUND_AAC:
|
||||||
switch tag.AACPacketType {
|
switch tag.AACPacketType {
|
||||||
@ -162,9 +162,9 @@ func (self *Prober) Probed() (ok bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Prober) TagToPacket(_tag flvio.Tag, timestamp int32) (pkt av.Packet, ok bool) {
|
func (self *Prober) TagToPacket(tag flvio.Tag, timestamp int32) (pkt av.Packet, ok bool) {
|
||||||
switch tag := _tag.(type) {
|
switch tag.Type {
|
||||||
case *flvio.Videodata:
|
case flvio.TAG_VIDEO:
|
||||||
pkt.Idx = int8(self.VideoStreamIdx)
|
pkt.Idx = int8(self.VideoStreamIdx)
|
||||||
switch tag.AVCPacketType {
|
switch tag.AVCPacketType {
|
||||||
case flvio.AVC_NALU:
|
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
|
pkt.IsKeyFrame = tag.FrameType == flvio.FRAME_KEY
|
||||||
}
|
}
|
||||||
|
|
||||||
case *flvio.Audiodata:
|
case flvio.TAG_AUDIO:
|
||||||
pkt.Idx = int8(self.AudioStreamIdx)
|
pkt.Idx = int8(self.AudioStreamIdx)
|
||||||
switch tag.SoundFormat {
|
switch tag.SoundFormat {
|
||||||
case flvio.SOUND_AAC:
|
case flvio.SOUND_AAC:
|
||||||
@ -212,7 +212,8 @@ func CodecDataToTag(stream av.CodecData) (_tag flvio.Tag, ok bool, err error) {
|
|||||||
switch stream.Type() {
|
switch stream.Type() {
|
||||||
case av.H264:
|
case av.H264:
|
||||||
h264 := stream.(h264parser.CodecData)
|
h264 := stream.(h264parser.CodecData)
|
||||||
tag := &flvio.Videodata{
|
tag := flvio.Tag{
|
||||||
|
Type: flvio.TAG_VIDEO,
|
||||||
AVCPacketType: flvio.AVC_SEQHDR,
|
AVCPacketType: flvio.AVC_SEQHDR,
|
||||||
CodecID: flvio.VIDEO_H264,
|
CodecID: flvio.VIDEO_H264,
|
||||||
Data: h264.AVCDecoderConfRecordBytes(),
|
Data: h264.AVCDecoderConfRecordBytes(),
|
||||||
@ -226,7 +227,8 @@ func CodecDataToTag(stream av.CodecData) (_tag flvio.Tag, ok bool, err error) {
|
|||||||
|
|
||||||
case av.AAC:
|
case av.AAC:
|
||||||
aac := stream.(aacparser.CodecData)
|
aac := stream.(aacparser.CodecData)
|
||||||
tag := &flvio.Audiodata{
|
tag := flvio.Tag{
|
||||||
|
Type: flvio.TAG_AUDIO,
|
||||||
SoundFormat: flvio.SOUND_AAC,
|
SoundFormat: flvio.SOUND_AAC,
|
||||||
SoundRate: flvio.SOUND_44Khz,
|
SoundRate: flvio.SOUND_44Khz,
|
||||||
AACPacketType: flvio.AAC_SEQHDR,
|
AACPacketType: flvio.AAC_SEQHDR,
|
||||||
@ -254,10 +256,11 @@ func CodecDataToTag(stream av.CodecData) (_tag flvio.Tag, ok bool, err error) {
|
|||||||
return
|
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() {
|
switch stream.Type() {
|
||||||
case av.H264:
|
case av.H264:
|
||||||
tag := &flvio.Videodata{
|
tag = flvio.Tag{
|
||||||
|
Type: flvio.TAG_VIDEO,
|
||||||
AVCPacketType: flvio.AVC_NALU,
|
AVCPacketType: flvio.AVC_NALU,
|
||||||
CodecID: flvio.VIDEO_H264,
|
CodecID: flvio.VIDEO_H264,
|
||||||
Data: pkt.Data,
|
Data: pkt.Data,
|
||||||
@ -268,10 +271,10 @@ func PacketToTag(pkt av.Packet, stream av.CodecData) (_tag flvio.Tag, timestamp
|
|||||||
} else {
|
} else {
|
||||||
tag.FrameType = flvio.FRAME_INTER
|
tag.FrameType = flvio.FRAME_INTER
|
||||||
}
|
}
|
||||||
_tag = tag
|
|
||||||
|
|
||||||
case av.AAC:
|
case av.AAC:
|
||||||
tag := &flvio.Audiodata{
|
tag = flvio.Tag{
|
||||||
|
Type: flvio.TAG_AUDIO,
|
||||||
SoundFormat: flvio.SOUND_AAC,
|
SoundFormat: flvio.SOUND_AAC,
|
||||||
SoundRate: flvio.SOUND_44Khz,
|
SoundRate: flvio.SOUND_44Khz,
|
||||||
AACPacketType: flvio.AAC_RAW,
|
AACPacketType: flvio.AAC_RAW,
|
||||||
@ -290,21 +293,20 @@ func PacketToTag(pkt av.Packet, stream av.CodecData) (_tag flvio.Tag, timestamp
|
|||||||
case 2:
|
case 2:
|
||||||
tag.SoundType = flvio.SOUND_STEREO
|
tag.SoundType = flvio.SOUND_STEREO
|
||||||
}
|
}
|
||||||
_tag = tag
|
|
||||||
|
|
||||||
case av.SPEEX:
|
case av.SPEEX:
|
||||||
tag := &flvio.Audiodata{
|
tag = flvio.Tag{
|
||||||
|
Type: flvio.TAG_AUDIO,
|
||||||
SoundFormat: flvio.SOUND_SPEEX,
|
SoundFormat: flvio.SOUND_SPEEX,
|
||||||
Data: pkt.Data,
|
Data: pkt.Data,
|
||||||
}
|
}
|
||||||
_tag = tag
|
|
||||||
|
|
||||||
case av.NELLYMOSER:
|
case av.NELLYMOSER:
|
||||||
tag := &flvio.Audiodata{
|
tag = flvio.Tag{
|
||||||
|
Type: flvio.TAG_AUDIO,
|
||||||
SoundFormat: flvio.SOUND_NELLYMOSER,
|
SoundFormat: flvio.SOUND_NELLYMOSER,
|
||||||
Data: pkt.Data,
|
Data: pkt.Data,
|
||||||
}
|
}
|
||||||
_tag = tag
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timestamp = flvio.TimeToTs(pkt.Time)
|
timestamp = flvio.TimeToTs(pkt.Time)
|
||||||
@ -414,10 +416,10 @@ func (self *Demuxer) prepare() (err error) {
|
|||||||
if _, err = self.bufr.Discard(skip); err != nil {
|
if _, err = self.bufr.Discard(skip); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if flags & flvio.FILE_HAS_AUDIO != 0 {
|
if flags&flvio.FILE_HAS_AUDIO != 0 {
|
||||||
self.prober.HasAudio = true
|
self.prober.HasAudio = true
|
||||||
}
|
}
|
||||||
if flags & flvio.FILE_HAS_VIDEO != 0 {
|
if flags&flvio.FILE_HAS_VIDEO != 0 {
|
||||||
self.prober.HasVideo = true
|
self.prober.HasVideo = true
|
||||||
}
|
}
|
||||||
self.stage++
|
self.stage++
|
||||||
@ -490,4 +492,3 @@ func Handler(h *avutil.RegisterHandler) {
|
|||||||
|
|
||||||
h.CodecTypes = CodecTypes
|
h.CodecTypes = CodecTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,61 +1,29 @@
|
|||||||
package flvio
|
package flvio
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"time"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/nareix/bits/pio"
|
"github.com/nareix/bits/pio"
|
||||||
"github.com/nareix/joy4/av"
|
"github.com/nareix/joy4/av"
|
||||||
|
"io"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TsToTime(ts int32) time.Duration {
|
func TsToTime(ts int32) time.Duration {
|
||||||
return time.Millisecond*time.Duration(ts)
|
return time.Millisecond * time.Duration(ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TimeToTs(tm time.Duration) int32 {
|
func TimeToTs(tm time.Duration) int32 {
|
||||||
return int32(tm / time.Millisecond)
|
return int32(tm / time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MaxTagSubHeaderLength = 16
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TAG_AUDIO = 8
|
TAG_AUDIO = 8
|
||||||
TAG_VIDEO = 9
|
TAG_VIDEO = 9
|
||||||
TAG_SCRIPTDATA = 18
|
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 (
|
const (
|
||||||
SOUND_MP3 = 2
|
SOUND_MP3 = 2
|
||||||
SOUND_NELLYMOSER_16KHZ_MONO = 4
|
SOUND_NELLYMOSER_16KHZ_MONO = 4
|
||||||
@ -81,7 +49,20 @@ const (
|
|||||||
AAC_RAW = 1
|
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]
|
SoundFormat: UB[4]
|
||||||
0 = Linear PCM, platform endian
|
0 = Linear PCM, platform endian
|
||||||
@ -139,85 +120,6 @@ type Audiodata struct {
|
|||||||
*/
|
*/
|
||||||
AACPacketType uint8
|
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)
|
1: keyframe (for AVC, a seekable frame)
|
||||||
2: inter frame (for AVC, a non- seekable frame)
|
2: inter frame (for AVC, a non- seekable frame)
|
||||||
@ -245,15 +147,64 @@ type Videodata struct {
|
|||||||
*/
|
*/
|
||||||
AVCPacketType uint8
|
AVCPacketType uint8
|
||||||
|
|
||||||
Data []byte
|
|
||||||
CompositionTime int32
|
CompositionTime int32
|
||||||
|
|
||||||
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Videodata) Type() uint8 {
|
func (self Tag) ChannelLayout() av.ChannelLayout {
|
||||||
return TAG_VIDEO
|
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 {
|
if len(b) < n+1 {
|
||||||
err = fmt.Errorf("videodata: parse invalid")
|
err = fmt.Errorf("videodata: parse invalid")
|
||||||
return
|
return
|
||||||
@ -278,7 +229,7 @@ func (self *Videodata) ParseHeader(b []byte) (n int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Videodata) FillHeader(b []byte) (n int) {
|
func (self Tag) videoFillHeader(b []byte) (n int) {
|
||||||
flags := self.FrameType<<4 | self.CodecID
|
flags := self.FrameType<<4 | self.CodecID
|
||||||
b[n] = flags
|
b[n] = flags
|
||||||
n++
|
n++
|
||||||
@ -289,12 +240,28 @@ func (self Videodata) FillHeader(b []byte) (n int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Videodata) GetData() []byte {
|
func (self Tag) FillHeader(b []byte) (n int) {
|
||||||
return self.Data
|
switch self.Type {
|
||||||
|
case TAG_AUDIO:
|
||||||
|
return self.audioFillHeader(b)
|
||||||
|
|
||||||
|
case TAG_VIDEO:
|
||||||
|
return self.videoFillHeader(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Videodata) SetData(b []byte) {
|
func (self *Tag) ParseHeader(b []byte) (n int, err error) {
|
||||||
self.Data = b
|
switch self.Type {
|
||||||
|
case TAG_AUDIO:
|
||||||
|
return self.audioParseHeader(b)
|
||||||
|
|
||||||
|
case TAG_VIDEO:
|
||||||
|
return self.videoParseHeader(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -313,14 +280,8 @@ func ParseTagHeader(b []byte) (tag Tag, ts int32, datalen int, err error) {
|
|||||||
tagtype := b[0]
|
tagtype := b[0]
|
||||||
|
|
||||||
switch tagtype {
|
switch tagtype {
|
||||||
case TAG_AUDIO:
|
case TAG_AUDIO, TAG_VIDEO, TAG_SCRIPTDATA:
|
||||||
tag = &Audiodata{}
|
tag = Tag{Type: tagtype}
|
||||||
|
|
||||||
case TAG_VIDEO:
|
|
||||||
tag = &Videodata{}
|
|
||||||
|
|
||||||
case TAG_SCRIPTDATA:
|
|
||||||
tag = &Scriptdata{}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("flvio: ReadTag tagtype=%d invalid", tagtype)
|
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
|
var tshi uint8
|
||||||
tslo = pio.U24BE(b[4:7])
|
tslo = pio.U24BE(b[4:7])
|
||||||
tshi = b[7]
|
tshi = b[7]
|
||||||
ts = int32(tslo|uint32(tshi)<<24)
|
ts = int32(tslo | uint32(tshi)<<24)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -353,10 +314,10 @@ func ReadTag(r io.Reader, b []byte) (tag Tag, ts int32, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var n int
|
var n int
|
||||||
if n, err = tag.ParseHeader(data); err != nil {
|
if n, err = (&tag).ParseHeader(data); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tag.SetData(data[n:])
|
tag.Data = data[n:]
|
||||||
|
|
||||||
if _, err = io.ReadFull(r, b[:4]); err != nil {
|
if _, err = io.ReadFull(r, b[:4]); err != nil {
|
||||||
return
|
return
|
||||||
@ -369,7 +330,7 @@ func FillTagHeader(b []byte, tagtype uint8, datalen int, ts int32) (n int) {
|
|||||||
n++
|
n++
|
||||||
pio.PutU24BE(b[n:], uint32(datalen))
|
pio.PutU24BE(b[n:], uint32(datalen))
|
||||||
n += 3
|
n += 3
|
||||||
pio.PutU24BE(b[n:], uint32(ts & 0xffffff))
|
pio.PutU24BE(b[n:], uint32(ts&0xffffff))
|
||||||
n += 3
|
n += 3
|
||||||
b[n] = uint8(ts >> 24)
|
b[n] = uint8(ts >> 24)
|
||||||
n++
|
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) {
|
func WriteTag(w io.Writer, tag Tag, ts int32, b []byte) (err error) {
|
||||||
data := tag.GetData()
|
data := tag.Data
|
||||||
|
|
||||||
n := tag.FillHeader(b[TagHeaderLength:])
|
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 {
|
if _, err = w.Write(b[:n]); err != nil {
|
||||||
return
|
return
|
||||||
@ -439,7 +400,7 @@ func ParseFileHeader(b []byte) (flags uint8, skip int, err error) {
|
|||||||
|
|
||||||
flags = b[4]
|
flags = b[4]
|
||||||
|
|
||||||
skip = int(pio.U32BE(b[5:9]))-9+4
|
skip = int(pio.U32BE(b[5:9])) - 9 + 4
|
||||||
if skip < 0 {
|
if skip < 0 {
|
||||||
err = fmt.Errorf("flvio: file header datasize invalid")
|
err = fmt.Errorf("flvio: file header datasize invalid")
|
||||||
return
|
return
|
||||||
@ -447,5 +408,3 @@ func ParseFileHeader(b []byte) (flags uint8, skip int, err error) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,24 +1,23 @@
|
|||||||
|
|
||||||
package rtmp
|
package rtmp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"bytes"
|
|
||||||
"net"
|
|
||||||
"net/url"
|
|
||||||
"bufio"
|
"bufio"
|
||||||
"time"
|
"bytes"
|
||||||
"fmt"
|
"crypto/hmac"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"io"
|
"fmt"
|
||||||
"github.com/nareix/bits/pio"
|
"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"
|
||||||
"github.com/nareix/joy4/av/avutil"
|
"github.com/nareix/joy4/av/avutil"
|
||||||
"crypto/hmac"
|
"github.com/nareix/joy4/format/flv"
|
||||||
"crypto/sha256"
|
"github.com/nareix/joy4/format/flv/flvio"
|
||||||
"crypto/rand"
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Debug bool
|
var Debug bool
|
||||||
@ -125,19 +124,19 @@ func (self *Server) ListenAndServe() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
stageHandshakeDone = iota+1
|
stageHandshakeDone = iota + 1
|
||||||
stageCommandDone
|
stageCommandDone
|
||||||
stageCodecDataDone
|
stageCodecDataDone
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
prepareReading = iota+1
|
prepareReading = iota + 1
|
||||||
prepareWriting
|
prepareWriting
|
||||||
)
|
)
|
||||||
|
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
URL *url.URL
|
URL *url.URL
|
||||||
OnPlayOrPublish func(string,flvio.AMFMap) error
|
OnPlayOrPublish func(string, flvio.AMFMap) error
|
||||||
|
|
||||||
prober *flv.Prober
|
prober *flv.Prober
|
||||||
streams []av.CodecData
|
streams []av.CodecData
|
||||||
@ -148,6 +147,7 @@ type Conn struct {
|
|||||||
bufr *bufio.Reader
|
bufr *bufio.Reader
|
||||||
bufw *bufio.Writer
|
bufw *bufio.Writer
|
||||||
ackn uint32
|
ackn uint32
|
||||||
|
|
||||||
writebuf []byte
|
writebuf []byte
|
||||||
readbuf []byte
|
readbuf []byte
|
||||||
|
|
||||||
@ -177,8 +177,7 @@ type Conn struct {
|
|||||||
msgdata []byte
|
msgdata []byte
|
||||||
msgtypeid uint8
|
msgtypeid uint8
|
||||||
datamsgvals []interface{}
|
datamsgvals []interface{}
|
||||||
videodata *flvio.Videodata
|
avtag flvio.Tag
|
||||||
audiodata *flvio.Audiodata
|
|
||||||
|
|
||||||
eventtype uint16
|
eventtype uint16
|
||||||
}
|
}
|
||||||
@ -286,11 +285,8 @@ func (self *Conn) pollAVTag() (tag flvio.Tag, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch self.msgtypeid {
|
switch self.msgtypeid {
|
||||||
case msgtypeidVideoMsg:
|
case msgtypeidVideoMsg, msgtypeidAudioMsg:
|
||||||
tag = self.videodata
|
tag = self.avtag
|
||||||
return
|
|
||||||
case msgtypeidAudioMsg:
|
|
||||||
tag = self.audiodata
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,8 +296,7 @@ func (self *Conn) pollMsg() (err error) {
|
|||||||
self.gotmsg = false
|
self.gotmsg = false
|
||||||
self.gotcommand = false
|
self.gotcommand = false
|
||||||
self.datamsgvals = nil
|
self.datamsgvals = nil
|
||||||
self.videodata = nil
|
self.avtag = flvio.Tag{}
|
||||||
self.audiodata = nil
|
|
||||||
for {
|
for {
|
||||||
if err = self.readChunk(); err != nil {
|
if err = self.readChunk(); err != nil {
|
||||||
return
|
return
|
||||||
@ -326,7 +321,7 @@ func SplitPath(u *url.URL) (app, stream string) {
|
|||||||
func getTcUrl(u *url.URL) string {
|
func getTcUrl(u *url.URL) string {
|
||||||
app, _ := SplitPath(u)
|
app, _ := SplitPath(u)
|
||||||
nu := *u
|
nu := *u
|
||||||
nu.Path = "/"+app
|
nu.Path = "/" + app
|
||||||
return nu.String()
|
return nu.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +353,7 @@ var CodecTypes = flv.CodecTypes
|
|||||||
|
|
||||||
func (self *Conn) writeBasicConf() (err error) {
|
func (self *Conn) writeBasicConf() (err error) {
|
||||||
// > SetChunkSize
|
// > SetChunkSize
|
||||||
if err = self.writeSetChunkSize(1024*1024*128); err != nil {
|
if err = self.writeSetChunkSize(1024 * 1024 * 128); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// > WindowAckSize
|
// > WindowAckSize
|
||||||
@ -479,8 +474,8 @@ func (self *Conn) readConnect() (err error) {
|
|||||||
"onStatus", self.commandtransid, nil,
|
"onStatus", self.commandtransid, nil,
|
||||||
flvio.AMFMap{
|
flvio.AMFMap{
|
||||||
"level": "status",
|
"level": "status",
|
||||||
"code": code,
|
"code": "NetStream.Publish.Start",
|
||||||
"description": description,
|
"description": "Start publishing",
|
||||||
},
|
},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return
|
return
|
||||||
@ -937,7 +932,7 @@ func (self *Conn) tmpwbuf(n int) []byte {
|
|||||||
|
|
||||||
func (self *Conn) writeSetChunkSize(size int) (err error) {
|
func (self *Conn) writeSetChunkSize(size int) (err error) {
|
||||||
self.writeMaxChunkSize = size
|
self.writeMaxChunkSize = size
|
||||||
b := self.tmpwbuf(chunkHeaderLength+4)
|
b := self.tmpwbuf(chunkHeaderLength + 4)
|
||||||
n := self.fillChunkHeader(b, 2, 0, msgtypeidSetChunkSize, 0, 4)
|
n := self.fillChunkHeader(b, 2, 0, msgtypeidSetChunkSize, 0, 4)
|
||||||
pio.PutU32BE(b[n:], uint32(size))
|
pio.PutU32BE(b[n:], uint32(size))
|
||||||
n += 4
|
n += 4
|
||||||
@ -946,7 +941,7 @@ func (self *Conn) writeSetChunkSize(size int) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Conn) writeAck(seqnum uint32) (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)
|
n := self.fillChunkHeader(b, 2, 0, msgtypeidAck, 0, 4)
|
||||||
pio.PutU32BE(b[n:], seqnum)
|
pio.PutU32BE(b[n:], seqnum)
|
||||||
n += 4
|
n += 4
|
||||||
@ -955,7 +950,7 @@ func (self *Conn) writeAck(seqnum uint32) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Conn) writeWindowAckSize(size 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)
|
n := self.fillChunkHeader(b, 2, 0, msgtypeidWindowAckSize, 0, 4)
|
||||||
pio.PutU32BE(b[n:], size)
|
pio.PutU32BE(b[n:], size)
|
||||||
n += 4
|
n += 4
|
||||||
@ -964,7 +959,7 @@ func (self *Conn) writeWindowAckSize(size uint32) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Conn) writeSetPeerBandwidth(acksize uint32, limittype uint8) (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)
|
n := self.fillChunkHeader(b, 2, 0, msgtypeidSetPeerBandwidth, 0, 5)
|
||||||
pio.PutU32BE(b[n:], acksize)
|
pio.PutU32BE(b[n:], acksize)
|
||||||
n += 4
|
n += 4
|
||||||
@ -974,21 +969,21 @@ func (self *Conn) writeSetPeerBandwidth(acksize uint32, limittype uint8) (err er
|
|||||||
return
|
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...)
|
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...)
|
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
|
size := 0
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
size += flvio.LenAMF0Val(arg)
|
size += flvio.LenAMF0Val(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
b := self.tmpwbuf(chunkHeaderLength+size)
|
b := self.tmpwbuf(chunkHeaderLength + size)
|
||||||
n := self.fillChunkHeader(b, csid, 0, msgtypeid, msgsid, size)
|
n := self.fillChunkHeader(b, csid, 0, msgtypeid, msgsid, size)
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
n += flvio.FillAMF0Val(b[n:], arg)
|
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 csid uint32
|
||||||
var data []byte
|
var data []byte
|
||||||
|
|
||||||
switch _tag := tag.(type) {
|
switch tag.Type {
|
||||||
case *flvio.Audiodata:
|
case flvio.TAG_AUDIO:
|
||||||
msgtypeid = msgtypeidAudioMsg
|
msgtypeid = msgtypeidAudioMsg
|
||||||
csid = 6
|
csid = 6
|
||||||
data = _tag.Data
|
data = tag.Data
|
||||||
|
|
||||||
case *flvio.Videodata:
|
case flvio.TAG_VIDEO:
|
||||||
msgtypeid = msgtypeidVideoMsg
|
msgtypeid = msgtypeidVideoMsg
|
||||||
csid = 7
|
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:])
|
hdrlen := tag.FillHeader(b[chunkHeaderLength:])
|
||||||
self.fillChunkHeader(b, csid, ts, msgtypeid, self.avmsgsid, hdrlen+len(data))
|
self.fillChunkHeader(b, csid, ts, msgtypeid, self.avmsgsid, hdrlen+len(data))
|
||||||
n := hdrlen+chunkHeaderLength
|
n := hdrlen + chunkHeaderLength
|
||||||
|
|
||||||
if n+len(data) > self.writeMaxChunkSize {
|
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
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1034,7 +1029,7 @@ func (self *Conn) writeAVTag(tag flvio.Tag, ts int32) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Conn) writeStreamBegin(msgsid uint32) (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)
|
n := self.fillChunkHeader(b, 2, 0, msgtypeidUserControl, 0, 6)
|
||||||
pio.PutU16BE(b[n:], eventtypeStreamBegin)
|
pio.PutU16BE(b[n:], eventtypeStreamBegin)
|
||||||
n += 2
|
n += 2
|
||||||
@ -1045,7 +1040,7 @@ func (self *Conn) writeStreamBegin(msgsid uint32) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Conn) writeSetBufferLength(msgsid uint32, timestamp 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)
|
n := self.fillChunkHeader(b, 2, 0, msgtypeidUserControl, 0, 10)
|
||||||
pio.PutU16BE(b[n:], eventtypeSetBufferLength)
|
pio.PutU16BE(b[n:], eventtypeSetBufferLength)
|
||||||
n += 2
|
n += 2
|
||||||
@ -1072,7 +1067,7 @@ func (self *Conn) fillChunkHeader(b []byte, csid uint32, timestamp int32, msgtyp
|
|||||||
//
|
//
|
||||||
// Figure 9 Chunk Message Header – Type 0
|
// Figure 9 Chunk Message Header – Type 0
|
||||||
|
|
||||||
b[n] = byte(csid)&0x3f
|
b[n] = byte(csid) & 0x3f
|
||||||
n++
|
n++
|
||||||
pio.PutU24BE(b[n:], uint32(timestamp))
|
pio.PutU24BE(b[n:], uint32(timestamp))
|
||||||
n += 3
|
n += 3
|
||||||
@ -1109,9 +1104,9 @@ func (self *Conn) readChunk() (err error) {
|
|||||||
var msghdrtype uint8
|
var msghdrtype uint8
|
||||||
var csid uint32
|
var csid uint32
|
||||||
|
|
||||||
msghdrtype = header>>6
|
msghdrtype = header >> 6
|
||||||
|
|
||||||
csid = uint32(header)&0x3f
|
csid = uint32(header) & 0x3f
|
||||||
switch csid {
|
switch csid {
|
||||||
default: // Chunk basic header 1
|
default: // Chunk basic header 1
|
||||||
case 0: // Chunk basic header 2
|
case 0: // Chunk basic header 2
|
||||||
@ -1119,13 +1114,13 @@ func (self *Conn) readChunk() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
n += 1
|
n += 1
|
||||||
csid = uint32(b[0])+64
|
csid = uint32(b[0]) + 64
|
||||||
case 1: // Chunk basic header 3
|
case 1: // Chunk basic header 3
|
||||||
if _, err = io.ReadFull(self.bufr, b[:2]); err != nil {
|
if _, err = io.ReadFull(self.bufr, b[:2]); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n += 2
|
n += 2
|
||||||
csid = uint32(pio.U16BE(b))+64
|
csid = uint32(pio.U16BE(b)) + 64
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := self.readcsmap[csid]
|
cs := self.readcsmap[csid]
|
||||||
@ -1282,8 +1277,8 @@ func (self *Conn) readChunk() (err error) {
|
|||||||
if size > self.readMaxChunkSize {
|
if size > self.readMaxChunkSize {
|
||||||
size = self.readMaxChunkSize
|
size = self.readMaxChunkSize
|
||||||
}
|
}
|
||||||
off := cs.msgdatalen-cs.msgdataleft
|
off := cs.msgdatalen - cs.msgdataleft
|
||||||
buf := cs.msgdata[off:int(off)+size]
|
buf := cs.msgdata[off : int(off)+size]
|
||||||
if _, err = io.ReadFull(self.bufr, buf); err != nil {
|
if _, err = io.ReadFull(self.bufr, buf); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1408,28 +1403,28 @@ func (self *Conn) handleMsg(timestamp uint32, msgsid uint32, msgtypeid uint8, ms
|
|||||||
if len(msgdata) == 0 {
|
if len(msgdata) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tag := &flvio.Videodata{}
|
tag := flvio.Tag{Type: flvio.TAG_VIDEO}
|
||||||
var n int
|
var n int
|
||||||
if n, err = tag.ParseHeader(msgdata); err != nil {
|
if n, err = (&tag).ParseHeader(msgdata); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !(tag.FrameType == flvio.FRAME_INTER || tag.FrameType == flvio.FRAME_KEY) {
|
if !(tag.FrameType == flvio.FRAME_INTER || tag.FrameType == flvio.FRAME_KEY) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tag.Data = msgdata[n:]
|
tag.Data = msgdata[n:]
|
||||||
self.videodata = tag
|
self.avtag = tag
|
||||||
|
|
||||||
case msgtypeidAudioMsg:
|
case msgtypeidAudioMsg:
|
||||||
if len(msgdata) == 0 {
|
if len(msgdata) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tag := &flvio.Audiodata{}
|
tag := flvio.Tag{Type: flvio.TAG_AUDIO}
|
||||||
var n int
|
var n int
|
||||||
if n, err = tag.ParseHeader(msgdata); err != nil {
|
if n, err = (&tag).ParseHeader(msgdata); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tag.Data = msgdata[n:]
|
tag.Data = msgdata[n:]
|
||||||
self.audiodata = tag
|
self.avtag = tag
|
||||||
|
|
||||||
case msgtypeidSetChunkSize:
|
case msgtypeidSetChunkSize:
|
||||||
if len(msgdata) < 4 {
|
if len(msgdata) < 4 {
|
||||||
@ -1481,7 +1476,7 @@ func hsCalcDigestPos(p []byte, base int) (pos int) {
|
|||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
pos += int(p[base+i])
|
pos += int(p[base+i])
|
||||||
}
|
}
|
||||||
pos = (pos%728)+base+4
|
pos = (pos % 728) + base + 4
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1519,13 +1514,13 @@ func hsCreate01(p []byte, time uint32, ver uint32, key []byte) {
|
|||||||
|
|
||||||
func hsCreate2(p []byte, key []byte) {
|
func hsCreate2(p []byte, key []byte) {
|
||||||
rand.Read(p)
|
rand.Read(p)
|
||||||
gap := len(p)-32
|
gap := len(p) - 32
|
||||||
digest := hsMakeDigest(key, p, gap)
|
digest := hsMakeDigest(key, p, gap)
|
||||||
copy(p[gap:], digest)
|
copy(p[gap:], digest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Conn) handshakeClient() (err error) {
|
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]
|
C0C1C2 := random[:1536*2+1]
|
||||||
C0 := C0C1C2[:1]
|
C0 := C0C1C2[:1]
|
||||||
@ -1535,7 +1530,7 @@ func (self *Conn) handshakeClient() (err error) {
|
|||||||
|
|
||||||
S0S1S2 := random[1536*2+1:]
|
S0S1S2 := random[1536*2+1:]
|
||||||
//S0 := S0S1S2[:1]
|
//S0 := S0S1S2[:1]
|
||||||
S1 := S0S1S2[1:1536+1]
|
S1 := S0S1S2[1 : 1536+1]
|
||||||
//S0S1 := S0S1S2[:1536+1]
|
//S0S1 := S0S1S2[:1536+1]
|
||||||
//S2 := S0S1S2[1536+1:]
|
//S2 := S0S1S2[1536+1:]
|
||||||
|
|
||||||
@ -1556,7 +1551,7 @@ func (self *Conn) handshakeClient() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if Debug {
|
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 {
|
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) {
|
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]
|
C0C1C2 := random[:1536*2+1]
|
||||||
C0 := C0C1C2[:1]
|
C0 := C0C1C2[:1]
|
||||||
C1 := C0C1C2[1:1536+1]
|
C1 := C0C1C2[1 : 1536+1]
|
||||||
C0C1 := C0C1C2[:1536+1]
|
C0C1 := C0C1C2[:1536+1]
|
||||||
C2 := C0C1C2[1536+1:]
|
C2 := C0C1C2[1536+1:]
|
||||||
|
|
||||||
S0S1S2 := random[1536*2+1:]
|
S0S1S2 := random[1536*2+1:]
|
||||||
S0 := S0S1S2[:1]
|
S0 := S0S1S2[:1]
|
||||||
S1 := S0S1S2[1:1536+1]
|
S1 := S0S1S2[1 : 1536+1]
|
||||||
S0S1 := S0S1S2[:1536+1]
|
S0S1 := S0S1S2[:1536+1]
|
||||||
S2 := S0S1S2[1536+1:]
|
S2 := S0S1S2[1536+1:]
|
||||||
|
|
||||||
@ -1749,4 +1744,3 @@ func Handler(h *avutil.RegisterHandler) {
|
|||||||
|
|
||||||
h.CodecTypes = CodecTypes
|
h.CodecTypes = CodecTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user