input/gvctrl/gvctrl-cli/main.go: added sub package gvctrl-cli under gvctrl

gvctrl-cli provides a command line interface for controlling the geovision camera. Good for
testing purposes.
This commit is contained in:
Saxon 2019-10-13 21:47:50 +10:30
parent b3c3b842c8
commit ab71c2cb06
3 changed files with 123 additions and 26 deletions

View File

@ -0,0 +1,96 @@
/*
DESCRIPTION
See package description.
AUTHORS
Saxon A. Nelson-Milton <saxon@ausocean.org>
LICENSE
Copyright (C) 2019 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
in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
package main
import (
"flag"
"fmt"
"strconv"
"bitbucket.org/ausocean/av/input/gvctrl"
)
func main() {
var (
hostPtr = flag.String("host", "192.168.1.50", "IP of GeoVision camera.")
codecPtr = flag.String("codec", "", "h264, h265 or mjpeg")
heightPtr = flag.Int("height", 0, "256, 360 or 720")
fpsPtr = flag.Int("fps", 0, "Frame rate in frames per second.")
vbrPtr = flag.Bool("vbr", false, "If true, variable bitrate.")
vbrQualityPtr = flag.Int("quality", -1, "General quality under variable bitrate, 0 to 4 inclusive.")
vbrRatePtr = flag.Int("vbr-rate", 0, "Variable bitrate maximal bitrate in kbps.")
cbrRatePtr = flag.Int("cbr-rate", 0, "Constant bitrate, bitrate in kbps.")
refreshPtr = flag.Float64("refresh", 0, "Inter refresh period in seconds.")
)
flag.Parse()
var options []gvctrl.Option
if *codecPtr != "" {
var c gvctrl.Codec
switch *codecPtr {
case "h264":
c = gvctrl.CodecH264
case "h265":
c = gvctrl.CodecH265
case "mjpeg":
c = gvctrl.CodecMJPEG
default:
panic(fmt.Sprintf("invalid codec: %s", *codecPtr))
}
options = append(options, gvctrl.CodecOut(c))
}
if *heightPtr != 0 {
options = append(options, gvctrl.Height(*heightPtr))
}
if *fpsPtr != 0 {
options = append(options, gvctrl.FrameRate(*fpsPtr))
}
options = append(options, gvctrl.VariableBitRate(*vbrPtr))
if *vbrQualityPtr != -1 {
options = append(options, gvctrl.VBRQuality(gvctrl.Quality(strconv.Itoa(*vbrQualityPtr))))
}
if *vbrRatePtr != 0 {
options = append(options, gvctrl.VBRBitRate(*vbrRatePtr))
}
if *cbrRatePtr != 0 {
options = append(options, gvctrl.CBRBitRate(*cbrRatePtr))
}
if *refreshPtr != 0 {
options = append(options, gvctrl.Refresh(*refreshPtr))
}
err := gvctrl.Set(*hostPtr, options...)
if err != nil {
panic(fmt.Sprintf("error from gvctrl.Set: %v", err))
}
}

View File

@ -12,7 +12,7 @@ LICENSE
It is free software: you can redistribute it and/or modify them 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 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 Free Software Foundation, either version 3 of the License, or (at your
option) any later version. Option) any later version.
It is distributed in the hope that it will be useful, but WITHOUT It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -34,9 +34,9 @@ import (
"time" "time"
) )
type option func(s settings) (settings, error) type Option func(s settings) (settings, error)
func Set(host string, options ...option) error { func Set(host string, options ...Option) error {
// Randomly generate an ID our client will use. // Randomly generate an ID our client will use.
const ( const (
minID = 10000 minID = 10000
@ -73,7 +73,7 @@ func Set(host string, options ...option) error {
for _, op := range options { for _, op := range options {
s, err = op(s) s, err = op(s)
if err != nil { if err != nil {
return fmt.Errorf("could not action option: %v", err) return fmt.Errorf("could not action Option: %v", err)
} }
} }
@ -93,7 +93,7 @@ const (
CodecMJPEG Codec = "4" CodecMJPEG Codec = "4"
) )
func CodecOut(c Codec) option { func CodecOut(c Codec) Option {
return func(s settings) (settings, error) { return func(s settings) (settings, error) {
switch c { switch c {
case CodecH265, CodecH264, CodecMJPEG: case CodecH265, CodecH264, CodecMJPEG:
@ -105,7 +105,7 @@ func CodecOut(c Codec) option {
} }
} }
func Height(h int) option { func Height(h int) Option {
return func(s settings) (settings, error) { return func(s settings) (settings, error) {
v, ok := map[int]string{256: res256, 360: res360, 720: res720}[h] v, ok := map[int]string{256: res256, 360: res360, 720: res720}[h]
if !ok { if !ok {
@ -116,7 +116,7 @@ func Height(h int) option {
} }
} }
func FrameRate(f int) option { func FrameRate(f int) Option {
return func(s settings) (settings, error) { return func(s settings) (settings, error) {
if 1 > f || f > 30 { if 1 > f || f > 30 {
return s, fmt.Errorf("invalid frame rate: %d", f) return s, fmt.Errorf("invalid frame rate: %d", f)
@ -126,7 +126,7 @@ func FrameRate(f int) option {
} }
} }
func VariableBitRate(b bool) option { func VariableBitRate(b bool) Option {
return func(s settings) (settings, error) { return func(s settings) (settings, error) {
s.vbr = "0" s.vbr = "0"
if b { if b {
@ -139,14 +139,14 @@ func VariableBitRate(b bool) option {
type Quality string type Quality string
const ( const (
QualityStandard Quality = "0" QualityStandard Quality = "4"
QualityFair Quality = "1" QualityFair Quality = "3"
QualityGood Quality = "2" QualityGood Quality = "2"
QualityGreat Quality = "3" QualityGreat Quality = "1"
QualityExcellent Quality = "4" QualityExcellent Quality = "0"
) )
func VBRQuality(q Quality) option { func VBRQuality(q Quality) Option {
return func(s settings) (settings, error) { return func(s settings) (settings, error) {
switch q { switch q {
case QualityStandard, QualityFair, QualityGood, QualityGreat, QualityExcellent: case QualityStandard, QualityFair, QualityGood, QualityGreat, QualityExcellent:
@ -158,7 +158,7 @@ func VBRQuality(q Quality) option {
} }
} }
func VBRBitRate(r int) option { func VBRBitRate(r int) Option {
return func(s settings) (settings, error) { return func(s settings) (settings, error) {
var vbrRates = []int{250, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500} var vbrRates = []int{250, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500}
if s.vbr == "1" { if s.vbr == "1" {
@ -169,7 +169,7 @@ func VBRBitRate(r int) option {
} }
} }
func CBRBitRate(r int) option { func CBRBitRate(r int) Option {
return func(s settings) (settings, error) { return func(s settings) (settings, error) {
var ( var (
cbrRates256 = []int{128, 256, 512, 1024} cbrRates256 = []int{128, 256, 512, 1024}
@ -191,7 +191,7 @@ func CBRBitRate(r int) option {
} }
} }
func Refresh(r float64) option { func Refresh(r float64) Option {
return func(s settings) (settings, error) { return func(s settings) (settings, error) {
const ( const (
maxRefreshPeriod = 5 maxRefreshPeriod = 5

View File

@ -42,6 +42,7 @@ const (
settingsURL = baseURL + "/VideoSetting.cgi" settingsURL = baseURL + "/VideoSetting.cgi"
) )
// TODO: make this configurable.
const ( const (
user = "admin" user = "admin"
pass = "admin" pass = "admin"
@ -83,17 +84,17 @@ func genLogIn(c *http.Client, id, host string) (string, error) {
cc[i] = exp[5 : len(exp)-1] cc[i] = exp[5 : len(exp)-1]
} }
var data url.Values f := url.Values{}
data.Set("grp", "-1") f.Set("grp", "-1")
data.Set("username", "") f.Set("username", "")
data.Set("password", "") f.Set("password", "")
data.Set("Apply", "Apply") f.Set("Apply", "Apply")
data.Set("umd5", md5Hex(cc[0]+user+cc[1])) f.Set("umd5", md5Hex(cc[0]+user+cc[1]))
data.Set("pmd5", md5Hex(cc[1]+pass+cc[0])) f.Set("pmd5", md5Hex(cc[1]+pass+cc[0]))
data.Set("browser", "1") f.Set("browser", "1")
data.Set("is_check_OCX_OK", "0") f.Set("is_check_OCX_OK", "0")
return data.Encode(), nil return f.Encode(), nil
} }
func logIn(c *http.Client, id, host, b string) error { func logIn(c *http.Client, id, host, b string) error {