av/generator/FLVGenerator.go

118 lines
2.7 KiB
Go
Raw Normal View History

/*
NAME
RtpToTsConverter.go - provides utilities for the conversion of Rtp packets
to equivalent MpegTs packets.
DESCRIPTION
See Readme.md
AUTHOR
Saxon Nelson-Milton <saxon.milton@gmail.com>
LICENSE
RtpToTsConverter.go is Copyright (C) 2017 the Australian Ocean Lab (AusOcean)
It is free software: you can redistribute it and/or modify them
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with revid in gpl.txt. If not, see [GNU licenses](http://www.gnu.org/licenses).
*/
2018-02-10 16:25:55 +03:00
package generator
import (
"../flv"
2018-02-14 10:02:57 +03:00
"fmt"
)
const (
inputChanLength = 1000
outputChanLength = 1000
)
2018-02-10 16:25:55 +03:00
type flvGenerator struct {
fps uint
inputChan chan []byte
outputChan chan []byte
audioFlag bool
videoFlag bool
lastTagSize int
currentTimestamp uint32
header flv.Header
2018-02-10 16:25:55 +03:00
}
func (g *flvGenerator)GetInputChan() chan []byte {
return g.inputChan
}
func (g *flvGenerator)GetOutputChan() chan []byte {
return g.outputChan
}
func NewFlvGenerator(audio bool, video bool, fps uint) (g *flvGenerator) {
2018-02-10 16:25:55 +03:00
g = new(flvGenerator)
g.fps = fps
g.audioFlag = audio
g.videoFlag = video
g.currentTimestamp = 0
g.lastTagSize = 0
g.inputChan = make(chan []byte, inputChanLength)
g.outputChan = make(chan []byte, outputChanLength)
2018-02-10 16:25:55 +03:00
return
}
func (g *flvGenerator) Start(){
go g.generate()
}
func (g *flvGenerator) GenHeader(){
header := flv.Header{
AudioFlag: g.audioFlag,
VideoFlag: g.videoFlag,
2018-02-10 16:25:55 +03:00
}
g.outputChan <- header.ToByteSlice()
2018-02-10 16:25:55 +03:00
}
func (g *flvGenerator) getNextTimestamp() (timestamp uint32){
2018-02-10 16:25:55 +03:00
timestamp = g.currentTimestamp
g.currentTimestamp += uint32(1000) / uint32(g.fps)
2018-02-10 16:25:55 +03:00
return
}
func (g *flvGenerator) ResetTimestamp() {
g.currentTimestamp = 0
2018-02-10 16:25:55 +03:00
}
func (g *flvGenerator) generate() {
g.GenHeader()
2018-02-10 16:25:55 +03:00
for {
2018-02-14 10:02:57 +03:00
fmt.Println("in this loop")
2018-02-10 16:25:55 +03:00
select {
case videoFrame := <-g.inputChan:
2018-02-14 10:02:57 +03:00
fmt.Println("Got video frame!")
tag := flv.VideoTag{
PrevTagSize: uint32(g.lastTagSize),
TagType: uint8(flv.VideoTagType),
DataSize: uint32(len(videoFrame)) + flv.DataHeaderLength,
Timestamp: g.getNextTimestamp(),
TimestampExtended: flv.NoTimestampExtension,
FrameType: flv.KeyFrameType,
Codec: flv.H264,
PacketType: flv.AVCNALU,
CompositionTime: 0,
Data: videoFrame,
}
tagAsByteSlice := tag.ToByteSlice()
g.lastTagSize = len(tagAsByteSlice)
g.outputChan<-tagAsByteSlice
2018-02-10 16:25:55 +03:00
}
}
}