Need to do some testing on my flv stuff next

This commit is contained in:
Saxon Milton 2018-02-11 16:36:59 +10:30
parent 2bb1d4cfe0
commit 010b252782
3 changed files with 68 additions and 107 deletions

View File

@ -7,11 +7,17 @@ import (
const ( const (
headerLength = 72 headerLength = 72
version = 0x01 version = 0x01
maxVideoTagSize = 10000
maxAudioTagSize = 10000
)
const (
videoTagType = 9
) )
type Header struct { type Header struct {
audioFlag bool AudioFlag bool
videoFlag bool VideoFlag bool
} }
func (h *Header) toByteSlice() []byte { func (h *Header) toByteSlice() []byte {
@ -25,22 +31,46 @@ func (h *Header) toByteSlice() []byte {
} }
type VideoTag struct { type VideoTag struct {
prevTagSize uint32 PrevTagSize uint32
tagType uint TagType uint8
dataSize uint32 DataSize uint32
timeStamp uint32 Timestamp uint32
timestampExtended uint32 TimestampExtended uint32
data []byte Data []byte
} }
func (t *VideoTag) toByteSlice() (output []byte) { func (t *VideoTag) toByteSlice() (output []byte) {
output = make([]byte, 0, maxVideoTagSize)
output = append(output, []byte{
byte(t.prevTagSize >> 24),
byte(t.prevTagSize >> 16),
byte(t.prevTagSize >> 8),
byte(t.prevTagSize),
byte(t.tageType),
byte(t.dataSize >> 16),
byte(t.dataSize >> 8),
byte(t.dataSize),
byte(t.timeStamp >> 16),
byte(t.timeStamp >> 8),
byte(t.timeStamp),
byte(t.timestampExtended),
0x00, 0x00, 0x00,
}...)
output = append(output, data...)
return
} }
type AudioTag struct { type AudioTag struct {
soundFormat uint8
soundRate uint8
soundSize uint8
soundType uint8
data []byte
} }
func (t *AudioTage) toByteSlice() (output []byte) { func (t *AudioTage) toByteSlice() (output []byte) {
output = make([]byte, 0, maxAudioTagSize)
output = append(output, byte(soundFormat<<4)|byte(soundRate<<2)|byte(soundSize<<1)|byte(soundType))
output = append(output, data...)
return
} }

View File

@ -4,7 +4,7 @@ type flvGenerator struct {
fps uint fps uint
inputChan chan []byte inputChan chan []byte
outputChan chan []byte outputChan chan []byte
headerChan [] header Header
} }
func (g *flvGenerator)GetInputChan() chan []byte { func (g *flvGenerator)GetInputChan() chan []byte {
@ -18,21 +18,23 @@ func (g *flvGenerator)GetOutputChan() chan []byte {
func NewFlvGenerator() (g *flvGenerator) { func NewFlvGenerator() (g *flvGenerator) {
g = new(flvGenerator) g = new(flvGenerator)
g.timestamp = 0 g.timestamp = 0
g.lastTagSize = 0
return return
} }
func (g *flvGenerator) Start(){ func (g *flvGenerator) Start(){
g.GenHeader()
go g.generate() go g.generate()
} }
func (g *flvGenerator) GenHeader(){ func (g *flvGenerator) GenHeader(){
header = flv.Header{ header := flv.Header{
AudioFlag: true,
VideoFlag: true,
} }
g.outputChan <- header g.outputChan <- header.toByteSlice()
} }
func (g *flvGenerator) GetNextTimestamp() (timestamp uint32){ func (g *flvGenerator) getNextTimestamp() (timestamp uint32){
timestamp = g.currentTimestamp timestamp = g.currentTimestamp
g.currentTimeStamp += 100*time.Millisecond() / g.fps g.currentTimeStamp += 100*time.Millisecond() / g.fps
return return
@ -43,9 +45,19 @@ func (g *flvGenerator) ResetTimestamp() {
} }
func (g *tsGenerator) generate() { func (g *tsGenerator) generate() {
g.GenHeader()
for { for {
select { select {
case videoFrame := <-g.inputChan case videoFrame := <-g.inputChan
tag := VideoTage{
PrevTagSize: g.lastTagSize,
TagType: flv.videoTagType,
DataSize: len(videoFrame),
Timestamp: g.getNextTimestamp(),
TimestampExtended: 0,
Data: videoFrame
}
g.outputChan<-tag.toByteSlice()
} }
} }
} }

View File

@ -1,81 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"time"
"github.com/zhangpeihao/goflv"
rtmp "github.com/zhangpeihao/gortmp"
"github.com/zhangpeihao/log"
)
const (
programName = "RtmpPublisher"
version = "0.0.1"
)
var (
url *string = flag.String("URL", "rtmp://video-center.alivecdn.com/AppName/StreamName?vhost=live.gz-app.com", "The rtmp url to connect.")
streamName *string = flag.String("Stream", "camstream", "Stream name to play.")
flvFileName *string = flag.String("FLV", "./v_4097.flv", "FLV file to publishs.")
)
var obConn rtmp.OutboundConn
var createStreamChan chan rtmp.OutboundStream
var videoDataSize int64
var audioDataSize int64
var flvFile *flv.File
var status uint
func publish(stream rtmp.OutboundStream) {
startTs := uint32(0)
startAt := time.Now().UnixNano()
preTs := uint32(0)
for status == rtmp.OUTBOUND_CONN_STATUS_CREATE_STREAM_OK {
fmt.Printf("@@@@@@@@@@@@@@diff1 header(%+v), startTs: %d\n", header, startTs)
if err = stream.PublishData(header.TagType, data, diff1); err != nil {
fmt.Println("PublishData() error:", err)
break
}
}
}
func main() {
createStreamChan = make(chan rtmp.OutboundStream)
testHandler := &TestOutboundConnHandler{}
fmt.Println("to dial")
fmt.Println("a")
var err error
obConn, err = rtmp.Dial(*url, testHandler, 100)
if err != nil {
fmt.Println("Dial error", err)
os.Exit(-1)
}
fmt.Println("b")
defer obConn.Close()
fmt.Println("to connect")
err = obConn.Connect()
if err != nil {
fmt.Printf("Connect error: %s", err.Error())
os.Exit(-1)
}
fmt.Println("c")
for {
select {
case stream := <-createStreamChan:
// Publish
stream.Attach(testHandler)
err = stream.Publish(*streamName, "live")
if err != nil {
fmt.Printf("Publish error: %s", err.Error())
os.Exit(-1)
}
case <-time.After(1 * time.Second):
fmt.Printf("Audio size: %d bytes; Vedio size: %d bytes\n", audioDataSize, videoDataSize)
}
}
}