mirror of https://bitbucket.org/ausocean/av.git
ran go fmt
This commit is contained in:
parent
de56364c0c
commit
99515edee5
237
RevidCLI.go
237
RevidCLI.go
|
@ -28,16 +28,16 @@ LICENSE
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"os/exec"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/ausocean/av/revid"
|
||||
_"bitbucket.org/ausocean/utils/smartLogger"
|
||||
"bitbucket.org/ausocean/iot/pi/netsender"
|
||||
_ "bitbucket.org/ausocean/utils/smartLogger"
|
||||
|
||||
linuxproc "github.com/c9s/goprocinfo/linux"
|
||||
)
|
||||
|
@ -63,18 +63,18 @@ const (
|
|||
quantizationPtr = 16
|
||||
timeoutPtr = 17
|
||||
intraRefreshPeriodPtr = 18
|
||||
verticalFlipPtr = 19
|
||||
horizontalFlipPtr = 20
|
||||
verticalFlipPtr = 19
|
||||
horizontalFlipPtr = 20
|
||||
)
|
||||
|
||||
// Other misc consts
|
||||
const (
|
||||
sleepTime = 2 * 43200
|
||||
sleepTime = 2 * 43200
|
||||
defaultRunDuration = 2 * 43200
|
||||
noOfConfigFlags = 21
|
||||
revidStopTime = 5
|
||||
prepTime = 20
|
||||
loggerVerbosity = 3
|
||||
noOfConfigFlags = 21
|
||||
revidStopTime = 5
|
||||
prepTime = 20
|
||||
loggerVerbosity = 3
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -93,39 +93,39 @@ const (
|
|||
// Globals
|
||||
var (
|
||||
configReceived bool = true
|
||||
varSum int = 0
|
||||
vars = make(map[string]string)
|
||||
revidInst revid.Revid
|
||||
config revid.Config
|
||||
varSum int = 0
|
||||
vars = make(map[string]string)
|
||||
revidInst revid.Revid
|
||||
config revid.Config
|
||||
)
|
||||
|
||||
func main() {
|
||||
flagNames := [noOfConfigFlags][2]string{
|
||||
{"Input", "The input type"},
|
||||
{"InputCodec", "The codec of the input"},
|
||||
{"Output", "The output type"},
|
||||
{"RtmpMethod", "The method used to send over rtmp (ffmpeg or librtmp)"},
|
||||
{"Packetization", "The method of data packetisation"},
|
||||
{"QuantizationMode", "The level of quantization"},
|
||||
{"Verbosity", "Verbosity on or off"},
|
||||
{"FramesPerClip", "Number of frames per clip sent"},
|
||||
{"RtmpUrl", "Url of rtmp endpoint"},
|
||||
{"Bitrate", "Bitrate of recorded video"},
|
||||
{"OutputFileName", "The directory of the output file"},
|
||||
{"InputFileName", "The directory of the input file"},
|
||||
{"Height", "Height in pixels"},
|
||||
{"Width", "Width in pixels"},
|
||||
{"FrameRate", "Frame rate of captured video"},
|
||||
{"HttpAddress", "Destination address of http posts"},
|
||||
{"Quantization", "Desired quantization value"},
|
||||
{"Timeout", "Http timeout in seconds"},
|
||||
{"IntraRefreshPeriod", "The IntraRefreshPeriod i.e. how many keyframes we send"},
|
||||
{"VerticalFlip", "Flip video vertically"},
|
||||
{"Input", "The input type"},
|
||||
{"InputCodec", "The codec of the input"},
|
||||
{"Output", "The output type"},
|
||||
{"RtmpMethod", "The method used to send over rtmp (ffmpeg or librtmp)"},
|
||||
{"Packetization", "The method of data packetisation"},
|
||||
{"QuantizationMode", "The level of quantization"},
|
||||
{"Verbosity", "Verbosity on or off"},
|
||||
{"FramesPerClip", "Number of frames per clip sent"},
|
||||
{"RtmpUrl", "Url of rtmp endpoint"},
|
||||
{"Bitrate", "Bitrate of recorded video"},
|
||||
{"OutputFileName", "The directory of the output file"},
|
||||
{"InputFileName", "The directory of the input file"},
|
||||
{"Height", "Height in pixels"},
|
||||
{"Width", "Width in pixels"},
|
||||
{"FrameRate", "Frame rate of captured video"},
|
||||
{"HttpAddress", "Destination address of http posts"},
|
||||
{"Quantization", "Desired quantization value"},
|
||||
{"Timeout", "Http timeout in seconds"},
|
||||
{"IntraRefreshPeriod", "The IntraRefreshPeriod i.e. how many keyframes we send"},
|
||||
{"VerticalFlip", "Flip video vertically"},
|
||||
{"HorizontalFlip", "Flip video horizontally"},
|
||||
}
|
||||
|
||||
// Create the configFlags based on the flagNames array
|
||||
configFlags := make([](*string),noOfConfigFlags)
|
||||
configFlags := make([](*string), noOfConfigFlags)
|
||||
for i := 0; i < noOfConfigFlags; i++ {
|
||||
configFlags[i] = flag.String(flagNames[i][0], "", flagNames[i][1])
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ func main() {
|
|||
// Do we want a netsender session
|
||||
netSenderFlagPtr := flag.Bool("NetSender", false, "Are we checking vars through netsender?")
|
||||
// User might also want to define how long revid runs for
|
||||
runDurationPtr := flag.Int("runDuration",defaultRunDuration,"How long do you want revid to run for?")
|
||||
runDurationPtr := flag.Int("runDuration", defaultRunDuration, "How long do you want revid to run for?")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
|
@ -235,26 +235,24 @@ func main() {
|
|||
fmt.Println("Bad vertical flip option!")
|
||||
}
|
||||
|
||||
config.FramesPerClip = *configFlags[framesPerClipPtr]
|
||||
config.RtmpUrl = *configFlags[rtmpUrlPtr]
|
||||
config.Bitrate = *configFlags[bitratePtr]
|
||||
config.OutputFileName = *configFlags[outputFileNamePtr]
|
||||
config.InputFileName = *configFlags[inputFileNamePtr]
|
||||
config.Height = *configFlags[heightPtr]
|
||||
config.Width = *configFlags[widthPtr]
|
||||
config.FrameRate = *configFlags[frameRatePtr]
|
||||
config.HttpAddress = *configFlags[httpAddressPtr]
|
||||
config.Quantization = *configFlags[quantizationPtr]
|
||||
config.Timeout = *configFlags[timeoutPtr]
|
||||
config.IntraRefreshPeriod = *configFlags[intraRefreshPeriodPtr]
|
||||
config.FramesPerClip = *configFlags[framesPerClipPtr]
|
||||
config.RtmpUrl = *configFlags[rtmpUrlPtr]
|
||||
config.Bitrate = *configFlags[bitratePtr]
|
||||
config.OutputFileName = *configFlags[outputFileNamePtr]
|
||||
config.InputFileName = *configFlags[inputFileNamePtr]
|
||||
config.Height = *configFlags[heightPtr]
|
||||
config.Width = *configFlags[widthPtr]
|
||||
config.FrameRate = *configFlags[frameRatePtr]
|
||||
config.HttpAddress = *configFlags[httpAddressPtr]
|
||||
config.Quantization = *configFlags[quantizationPtr]
|
||||
config.Timeout = *configFlags[timeoutPtr]
|
||||
config.IntraRefreshPeriod = *configFlags[intraRefreshPeriodPtr]
|
||||
|
||||
// Also give the config a logger object
|
||||
//config.Logger = smartLogger.New(loggerVerbosity, smartLogger.White)
|
||||
|
||||
|
||||
|
||||
//init netsender
|
||||
if *netSenderFlagPtr{
|
||||
if *netSenderFlagPtr {
|
||||
netsenderInit()
|
||||
}
|
||||
|
||||
|
@ -271,7 +269,7 @@ func main() {
|
|||
|
||||
// If we're not running a netsender session then we run revid for the amount
|
||||
// of time the user defined or the default 2 days
|
||||
time.Sleep( time.Duration(*runDurationPtr) * time.Second )
|
||||
time.Sleep(time.Duration(*runDurationPtr) * time.Second)
|
||||
revidInst.Stop()
|
||||
}
|
||||
|
||||
|
@ -286,18 +284,18 @@ func netsenderInit() {
|
|||
//default to a config?????
|
||||
config.Logger.Log("Error", err.Error())
|
||||
} else {
|
||||
configReceived = true;
|
||||
configReceived = true
|
||||
}
|
||||
}
|
||||
|
||||
//periodicNetsenderReport is called by the main function every monPeriod seconds. It makes sure a config has been recieved, and then
|
||||
//reports back CPU stats and updates vars
|
||||
func periodicNetsenderReport(){
|
||||
func periodicNetsenderReport() {
|
||||
if !configReceived {
|
||||
if err := netsender.GetConfig(); err != nil {
|
||||
config.Logger.Log("Error", err.Error())
|
||||
} else {
|
||||
configReceived = true;
|
||||
configReceived = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,76 +320,75 @@ func periodicNetsenderReport(){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
func updateRevid() {
|
||||
revidInst.Stop()
|
||||
time.Sleep( time.Duration(revidStopTime) * time.Second )
|
||||
time.Sleep(time.Duration(revidStopTime) * time.Second)
|
||||
//look through var map and update revid where needed
|
||||
|
||||
for key, value := range vars {
|
||||
switch key {
|
||||
case "FramesPerClip":
|
||||
asInt,err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.FramesPerClip = value
|
||||
}
|
||||
case "RtmpUrl":
|
||||
config.RtmpUrl = value
|
||||
case "Bitrate":
|
||||
asInt,err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.Bitrate = value
|
||||
}
|
||||
case "OutputFileName":
|
||||
config.OutputFileName = value
|
||||
case "InputFileName":
|
||||
config.InputFileName = value
|
||||
case "Height":
|
||||
asInt,err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.Height = value
|
||||
}
|
||||
case "Width":
|
||||
asInt,err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.Width = value
|
||||
}
|
||||
case "FrameRate":
|
||||
asInt,err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.FrameRate = value
|
||||
}
|
||||
case "HttpAddress":
|
||||
config.HttpAddress = value
|
||||
case "Quantization":
|
||||
asInt,err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.Quantization = value
|
||||
}
|
||||
case "Timeout":
|
||||
asInt,err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.Timeout = value
|
||||
}
|
||||
case "IntraRefreshPeriod":
|
||||
asInt,err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.IntraRefreshPeriod = value
|
||||
}
|
||||
case "HorizontalFlip":
|
||||
switch value {
|
||||
case "Yes":
|
||||
config.HorizontalFlip = revid.Yes
|
||||
case "No":
|
||||
config.HorizontalFlip = revid.No
|
||||
}
|
||||
case "VerticalFlip":
|
||||
switch value {
|
||||
case "Yes":
|
||||
config.VerticalFlip = revid.Yes
|
||||
case "No":
|
||||
config.VerticalFlip = revid.No
|
||||
}
|
||||
case "FramesPerClip":
|
||||
asInt, err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.FramesPerClip = value
|
||||
}
|
||||
case "RtmpUrl":
|
||||
config.RtmpUrl = value
|
||||
case "Bitrate":
|
||||
asInt, err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.Bitrate = value
|
||||
}
|
||||
case "OutputFileName":
|
||||
config.OutputFileName = value
|
||||
case "InputFileName":
|
||||
config.InputFileName = value
|
||||
case "Height":
|
||||
asInt, err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.Height = value
|
||||
}
|
||||
case "Width":
|
||||
asInt, err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.Width = value
|
||||
}
|
||||
case "FrameRate":
|
||||
asInt, err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.FrameRate = value
|
||||
}
|
||||
case "HttpAddress":
|
||||
config.HttpAddress = value
|
||||
case "Quantization":
|
||||
asInt, err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.Quantization = value
|
||||
}
|
||||
case "Timeout":
|
||||
asInt, err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.Timeout = value
|
||||
}
|
||||
case "IntraRefreshPeriod":
|
||||
asInt, err := strconv.Atoi(value)
|
||||
if asInt > 0 && err == nil {
|
||||
config.IntraRefreshPeriod = value
|
||||
}
|
||||
case "HorizontalFlip":
|
||||
switch value {
|
||||
case "Yes":
|
||||
config.HorizontalFlip = revid.Yes
|
||||
case "No":
|
||||
config.HorizontalFlip = revid.No
|
||||
}
|
||||
case "VerticalFlip":
|
||||
switch value {
|
||||
case "Yes":
|
||||
config.VerticalFlip = revid.Yes
|
||||
case "No":
|
||||
config.VerticalFlip = revid.No
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,7 +486,7 @@ func revidReportActions(pin int) (int, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func createRevidInstance(){
|
||||
func createRevidInstance() {
|
||||
// Try to create the revid instance with the given config
|
||||
var err error
|
||||
for revidInst, err = revid.NewRevid(config); err != nil; {
|
||||
|
|
|
@ -51,15 +51,15 @@ var dummyAudioTag2Data = []byte{0x01, 0xdc, 0x00, 0x4c, 0x61, 0x76, 0x63, 0x35,
|
|||
// flvGenerator provides properties required for the generation of flv video
|
||||
// from raw video data
|
||||
type flvGenerator struct {
|
||||
fps uint
|
||||
inputChan chan []byte
|
||||
outputChan chan []byte
|
||||
audioFlag bool
|
||||
videoFlag bool
|
||||
lastTagSize int
|
||||
header flv.Header
|
||||
startTime time.Time
|
||||
firstTag bool
|
||||
fps uint
|
||||
inputChan chan []byte
|
||||
outputChan chan []byte
|
||||
audioFlag bool
|
||||
videoFlag bool
|
||||
lastTagSize int
|
||||
header flv.Header
|
||||
startTime time.Time
|
||||
firstTag bool
|
||||
isGenerating bool
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ func NewFlvGenerator(audio bool, video bool, fps uint) (g *flvGenerator) {
|
|||
// Start begins the generation routine - i.e. if raw data is given to the input
|
||||
// channel flv tags will be produced and available from the output channel.
|
||||
func (g *flvGenerator) Start() {
|
||||
g.isGenerating = true;
|
||||
g.isGenerating = true
|
||||
go g.generate()
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,7 @@ func (g *flvGenerator) generate() {
|
|||
g.outputChan <- tag.ToByteSlice()
|
||||
}
|
||||
default:
|
||||
time.Sleep(time.Duration(5)*time.Millisecond)
|
||||
time.Sleep(time.Duration(5) * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,12 +50,12 @@ var (
|
|||
func genPatAndPmt() {
|
||||
patTable = make([]byte, 0, mpegtsPacketSize)
|
||||
patTable = append(patTable, patTableStart...)
|
||||
for i := len(pmtTableStart); i < mpegtsPacketSize - len(pmtTableStart); i++ {
|
||||
for i := len(pmtTableStart); i < mpegtsPacketSize-len(pmtTableStart); i++ {
|
||||
pmtTable[i] = 255
|
||||
}
|
||||
pmtTable = make([]byte, 0, mpegtsPacketSize)
|
||||
pmtTable = append(pmtTable, pmtTableStart...)
|
||||
for i := len(patTableStart); i < mpegtsPacketSize - len(patTableStart); i++ {
|
||||
for i := len(patTableStart); i < mpegtsPacketSize-len(patTableStart); i++ {
|
||||
pmtTable[i] = 255
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ type tsGenerator struct {
|
|||
fps uint
|
||||
pesPktChan chan []byte
|
||||
ccMap map[int]int
|
||||
isGenerating bool
|
||||
isGenerating bool
|
||||
}
|
||||
|
||||
// getInputChan returns a handle to the nalInputChan (inputChan) so that nal units
|
||||
|
|
|
@ -62,7 +62,7 @@ func TestMpegTsToByteSlice(t *testing.T) {
|
|||
expectedOutput = append(expectedOutput, payload...)
|
||||
tsPktAsByteSlice, err := tsPkt.ToByteSlice()
|
||||
if err != nil {
|
||||
t.Errorf("Should not have got error!: %v",err)
|
||||
t.Errorf("Should not have got error!: %v", err)
|
||||
}
|
||||
for i := 0; i < 188; i++ {
|
||||
if tsPktAsByteSlice[i] != expectedOutput[i] {
|
||||
|
|
|
@ -29,8 +29,8 @@ package revid
|
|||
|
||||
import (
|
||||
"errors"
|
||||
_ "fmt"
|
||||
"strconv"
|
||||
_"fmt"
|
||||
|
||||
"bitbucket.org/ausocean/utils/smartLogger"
|
||||
//"../../utils/smartLogger"
|
||||
|
@ -46,8 +46,8 @@ type Config struct {
|
|||
Packetization uint8
|
||||
QuantizationMode uint8
|
||||
Verbosity uint8
|
||||
HorizontalFlip uint8
|
||||
VerticalFlip uint8
|
||||
HorizontalFlip uint8
|
||||
VerticalFlip uint8
|
||||
FramesPerClip string
|
||||
RtmpUrl string
|
||||
Bitrate string
|
||||
|
@ -83,15 +83,15 @@ const (
|
|||
Yes = 17
|
||||
No = 18
|
||||
NativeRtmp = 19
|
||||
FfmpegRtmp = 20
|
||||
FfmpegRtmp = 20
|
||||
)
|
||||
|
||||
// Default config settings
|
||||
const (
|
||||
defaultInput = Raspivid
|
||||
defaultOutput = NativeRtmp
|
||||
defaultPacketization = Flv
|
||||
defaultRtmpUrl = "rtmp://a.rtmp.youtube.com/live2/xt13-r4dh-f2w1-bh4s"
|
||||
defaultInput = Raspivid
|
||||
defaultOutput = NativeRtmp
|
||||
defaultPacketization = Flv
|
||||
defaultRtmpUrl = "rtmp://a.rtmp.youtube.com/live2/xt13-r4dh-f2w1-bh4s"
|
||||
defaultFrameRate = "25"
|
||||
defaultWidth = "1280"
|
||||
defaultHeight = "720"
|
||||
|
@ -101,8 +101,8 @@ const (
|
|||
defaultBitrate = "500000"
|
||||
defaultQuantizationMode = QuantizationOff
|
||||
defaultFramesPerClip = "1"
|
||||
defaultVerticalFlip = No
|
||||
defaultHorizontalFlip = No
|
||||
defaultVerticalFlip = No
|
||||
defaultHorizontalFlip = No
|
||||
)
|
||||
|
||||
// Validate checks for any errors in the config fields and defaults settings
|
||||
|
|
103
revid/Revid.go
103
revid/Revid.go
|
@ -39,10 +39,10 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
"path/filepath"
|
||||
|
||||
"bitbucket.org/ausocean/av/generator"
|
||||
"bitbucket.org/ausocean/av/parser"
|
||||
|
@ -57,24 +57,24 @@ import (
|
|||
|
||||
// Misc constants
|
||||
const (
|
||||
clipDuration = 1 // s
|
||||
mp2tPacketSize = 188 // MPEG-TS packet size
|
||||
mp2tMaxPackets = 2016 * clipDuration // # first multiple of 7 and 8 greater than 2000
|
||||
ringBufferSize = 500
|
||||
ringBufferElementSize = 150000
|
||||
httpTimeOut = 5 // s
|
||||
packetsPerFrame = 7
|
||||
bitrateTime = 60 // s
|
||||
mjpegParserInChanLen = 100000
|
||||
ffmpegPath = "/usr/local/bin/ffmpeg"
|
||||
rtmpConnectionTimout = 10
|
||||
outputChanSize = 1000
|
||||
cameraRetryPeriod = 5 * time.Second
|
||||
sendFailedDelay = 5
|
||||
clipDuration = 1 // s
|
||||
mp2tPacketSize = 188 // MPEG-TS packet size
|
||||
mp2tMaxPackets = 2016 * clipDuration // # first multiple of 7 and 8 greater than 2000
|
||||
ringBufferSize = 500
|
||||
ringBufferElementSize = 150000
|
||||
httpTimeOut = 5 // s
|
||||
packetsPerFrame = 7
|
||||
bitrateTime = 60 // s
|
||||
mjpegParserInChanLen = 100000
|
||||
ffmpegPath = "/usr/local/bin/ffmpeg"
|
||||
rtmpConnectionTimout = 10
|
||||
outputChanSize = 1000
|
||||
cameraRetryPeriod = 5 * time.Second
|
||||
sendFailedDelay = 5
|
||||
maxSendFailedErrorCount = 500
|
||||
clipSizeThreshold = 11
|
||||
rtmpConnectionMaxTries = 5
|
||||
raspividNoOfTries = 3
|
||||
clipSizeThreshold = 11
|
||||
rtmpConnectionMaxTries = 5
|
||||
raspividNoOfTries = 3
|
||||
)
|
||||
|
||||
// Log Types
|
||||
|
@ -85,7 +85,6 @@ const (
|
|||
Debug = "Debug"
|
||||
)
|
||||
|
||||
|
||||
// Revid provides methods to control a revid session; providing methods
|
||||
// to start, stop and change the state of an instance using the Config struct.
|
||||
type Revid interface {
|
||||
|
@ -99,26 +98,26 @@ type Revid interface {
|
|||
|
||||
// The revid struct provides fields to describe the state of a Revid.
|
||||
type revid struct {
|
||||
ffmpegPath string
|
||||
tempDir string
|
||||
ringBuffer ringbuffer.RingBuffer
|
||||
config Config
|
||||
isRunning bool
|
||||
outputFile *os.File
|
||||
inputFile *os.File
|
||||
generator generator.Generator
|
||||
parser parser.Parser
|
||||
cmd *exec.Cmd
|
||||
ffmpegCmd *exec.Cmd
|
||||
inputReader *bufio.Reader
|
||||
ffmpegStdin io.WriteCloser
|
||||
outputChan chan []byte
|
||||
setupInput func() error
|
||||
setupOutput func() error
|
||||
getFrame func() []byte
|
||||
sendClip func(clip []byte) error
|
||||
rtmpInst rtmp.RTMPSession
|
||||
mutex sync.Mutex
|
||||
ffmpegPath string
|
||||
tempDir string
|
||||
ringBuffer ringbuffer.RingBuffer
|
||||
config Config
|
||||
isRunning bool
|
||||
outputFile *os.File
|
||||
inputFile *os.File
|
||||
generator generator.Generator
|
||||
parser parser.Parser
|
||||
cmd *exec.Cmd
|
||||
ffmpegCmd *exec.Cmd
|
||||
inputReader *bufio.Reader
|
||||
ffmpegStdin io.WriteCloser
|
||||
outputChan chan []byte
|
||||
setupInput func() error
|
||||
setupOutput func() error
|
||||
getFrame func() []byte
|
||||
sendClip func(clip []byte) error
|
||||
rtmpInst rtmp.RTMPSession
|
||||
mutex sync.Mutex
|
||||
currentBitrate int64
|
||||
}
|
||||
|
||||
|
@ -326,7 +325,7 @@ func (r *revid) flushData() {
|
|||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
done:
|
||||
}
|
||||
|
||||
// packClips takes data segments; whether that be tsPackets or mjpeg frames and
|
||||
|
@ -351,7 +350,7 @@ func (r *revid) packClips() {
|
|||
frame := r.getFrame()
|
||||
lenOfFrame := len(frame)
|
||||
if lenOfFrame > ringBufferElementSize {
|
||||
r.Log(Warning,fmt.Sprintf("Frame was too big: %v bytes, getting another one!", lenOfFrame))
|
||||
r.Log(Warning, fmt.Sprintf("Frame was too big: %v bytes, getting another one!", lenOfFrame))
|
||||
frame = r.getFrame()
|
||||
lenOfFrame = len(frame)
|
||||
}
|
||||
|
@ -359,7 +358,7 @@ func (r *revid) packClips() {
|
|||
copy(clip[clipSize:upperBound], frame)
|
||||
packetCount++
|
||||
clipSize += lenOfFrame
|
||||
fpcAsInt,err := strconv.Atoi(r.config.FramesPerClip)
|
||||
fpcAsInt, err := strconv.Atoi(r.config.FramesPerClip)
|
||||
if err != nil {
|
||||
r.Log(Error, "Frames per clip not quite right! Defaulting to 1!")
|
||||
r.config.FramesPerClip = "1"
|
||||
|
@ -398,9 +397,9 @@ func (r *revid) outputClips() {
|
|||
if clip, err := r.ringBuffer.Read(); err == nil && r.isRunning {
|
||||
bytes += len(clip)
|
||||
errorCount := 0
|
||||
r.Log(Debug,"About to send!")
|
||||
r.Log(Debug, "About to send!")
|
||||
err2 := r.sendClip(clip)
|
||||
r.Log(Debug,"Finished send!")
|
||||
r.Log(Debug, "Finished send!")
|
||||
|
||||
for ; err2 != nil; errorCount++ {
|
||||
r.Log(Warning, "Send failed trying again!")
|
||||
|
@ -433,8 +432,8 @@ func (r *revid) outputClips() {
|
|||
now = time.Now()
|
||||
deltaTime := now.Sub(prevTime)
|
||||
if deltaTime > time.Duration(bitrateTime)*time.Second {
|
||||
r.currentBitrate = int64(float64(bytes*8)/float64(deltaTime/1e9))
|
||||
r.Log(Info, fmt.Sprintf("Bitrate: %v bits/s\n", r.currentBitrate ))
|
||||
r.currentBitrate = int64(float64(bytes*8) / float64(deltaTime/1e9))
|
||||
r.Log(Info, fmt.Sprintf("Bitrate: %v bits/s\n", r.currentBitrate))
|
||||
r.Log(Info, fmt.Sprintf("Ring buffer size: %v\n", r.ringBuffer.GetNoOfElements()))
|
||||
prevTime = now
|
||||
bytes = 0
|
||||
|
@ -552,7 +551,7 @@ func (r *revid) setupInputForRaspivid() error {
|
|||
r.Log(Info, "Starting raspivid!")
|
||||
switch r.config.InputCodec {
|
||||
case H264:
|
||||
arguments := []string{ "-cd", "H264",
|
||||
arguments := []string{"-cd", "H264",
|
||||
"-o", "-",
|
||||
"-n",
|
||||
"-t", r.config.Timeout,
|
||||
|
@ -564,9 +563,9 @@ func (r *revid) setupInputForRaspivid() error {
|
|||
"-g", r.config.IntraRefreshPeriod,
|
||||
}
|
||||
|
||||
if r.config.QuantizationMode == QuantizationOn{
|
||||
arguments = append(arguments,"-qp")
|
||||
arguments = append(arguments,r.config.Quantization);
|
||||
if r.config.QuantizationMode == QuantizationOn {
|
||||
arguments = append(arguments, "-qp")
|
||||
arguments = append(arguments, r.config.Quantization)
|
||||
}
|
||||
|
||||
if r.config.HorizontalFlip == Yes {
|
||||
|
@ -612,7 +611,7 @@ func (r *revid) setupInputForRaspivid() error {
|
|||
}
|
||||
return err
|
||||
}
|
||||
raspividSuccess:
|
||||
raspividSuccess:
|
||||
r.inputReader = bufio.NewReader(stdout)
|
||||
go r.readCamera()
|
||||
return nil
|
||||
|
@ -646,7 +645,7 @@ func (r *revid) readCamera() {
|
|||
_, err := io.ReadFull(r.inputReader, data)
|
||||
switch {
|
||||
// We know this means we're getting nothing from the cam
|
||||
case ( err != nil && err.Error() == "EOF" && r.isRunning ) || ( err != nil && r.isRunning):
|
||||
case (err != nil && err.Error() == "EOF" && r.isRunning) || (err != nil && r.isRunning):
|
||||
r.Log(Error, "No data from camera!")
|
||||
time.Sleep(cameraRetryPeriod)
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue