149 lines
3.5 KiB
Go
149 lines
3.5 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type Config struct {
|
|
LogLevel string `yaml:"log_level"`
|
|
Auth bool `yaml:"auth"`
|
|
AuthSecret string `yaml:"auth_secret"`
|
|
Port int `yaml:"port"`
|
|
UStreamer UStreamer `yaml:"ustreamer"`
|
|
Video FFmpeg `yaml:"video"`
|
|
Audio []string `yaml:"audio"`
|
|
WebRtc WebRtc `yaml:"webrtc"`
|
|
Stream Stream `yaml:"stream"`
|
|
|
|
ISOPath string `yaml:"iso_path"`
|
|
NanoKVMUISupport bool `yaml:"nano_kvm_ui_support"`
|
|
}
|
|
|
|
type WebRtc struct {
|
|
Host string `yaml:"host"`
|
|
Port int `yaml:"port"`
|
|
}
|
|
|
|
type ExtProcess struct {
|
|
Path string `yaml:"path"`
|
|
Args string `yaml:"args"`
|
|
}
|
|
|
|
type Stream struct {
|
|
Source string `yaml:"source"` // mjpeg or h264
|
|
}
|
|
|
|
const (
|
|
StreamSourceMjpeg = "mjpeg"
|
|
StreamSourceH264 = "h264"
|
|
StreamSourceHevc = "hevc"
|
|
)
|
|
|
|
type StreamInput string
|
|
|
|
const (
|
|
StreamInputVideo = "v"
|
|
StreamInputVideoAudio = "va"
|
|
)
|
|
|
|
type FFmpeg struct {
|
|
Commands map[StreamInput]string `yaml:"commands"`
|
|
FPS int `yaml:"fps"`
|
|
Bitrate int `yaml:"bitrate"`
|
|
Height int `yaml:"height"`
|
|
GOP int `yaml:"gop"`
|
|
Codec string `yaml:"codec"`
|
|
}
|
|
|
|
func (f FFmpeg) FormatCmd(cmd string) string {
|
|
return fmt.Sprintf(cmd, f.Height, f.Codec, f.Bitrate*1000, f.FPS, f.GOP)
|
|
}
|
|
|
|
type UStreamer struct {
|
|
Host string `yaml:"host"`
|
|
Port int `yaml:"port"`
|
|
ExtProcess
|
|
}
|
|
|
|
var c Config
|
|
|
|
func Get() Config {
|
|
return c
|
|
}
|
|
|
|
func Init() {
|
|
c = Config{
|
|
LogLevel: "debug",
|
|
Auth: false,
|
|
Port: 8080,
|
|
UStreamer: UStreamer{
|
|
Host: "0.0.0.0",
|
|
Port: 8888,
|
|
ExtProcess: ExtProcess{
|
|
Path: "/app/ustreamer",
|
|
Args: "--host 0.0.0.0 --port 8888 -m BGR24 -f 60",
|
|
},
|
|
},
|
|
Video: FFmpeg{
|
|
Commands: map[StreamInput]string{
|
|
StreamInputVideoAudio: "/usr/bin/arecord -D hw:0,0 -f dat -r 48000 -c 2 --buffer-size=150 | /app/ffmpeg -init_hw_device rkmpp=hw -filter_hw_device hw" +
|
|
" -f wav -i pipe:0 -map 0:a -c:a libopus -b:a 48000 -sample_fmt s16 -ssrc 1 -payload_type 111 -f rtp -max_delay 0 -application lowdelay" +
|
|
" -f rtp rtp://127.0.0.1:5006?pkt_size=1200" +
|
|
" -i /dev/video0 -map 1:v -vf hwupload,scale_rkrga=h=%d:force_original_aspect_ratio=1 -c:v %s_rkmpp -flags +low_delay -b:v %d -framerate %d -g %d" +
|
|
" -f rtp rtp://127.0.0.1:5004?pkt_size=1200",
|
|
StreamInputVideo: "/app/ffmpeg -hide_banner -loglevel error -init_hw_device rkmpp=hw -filter_hw_device hw" +
|
|
" -i /dev/video0 -vf hwupload,scale_rkrga=h=%d:force_original_aspect_ratio=1 -c:v %s_rkmpp -flags +low_delay -b:v %d -framerate %d -g %d" +
|
|
" -f rtp rtp://127.0.0.1:5004?pkt_size=1200",
|
|
},
|
|
FPS: 60,
|
|
Bitrate: 6000,
|
|
Height: 720,
|
|
GOP: 5,
|
|
Codec: "h264",
|
|
},
|
|
WebRtc: WebRtc{
|
|
Host: "127.0.0.1",
|
|
Port: 5004,
|
|
},
|
|
Stream: Stream{
|
|
Source: StreamSourceH264,
|
|
},
|
|
ISOPath: "/data",
|
|
NanoKVMUISupport: true,
|
|
}
|
|
}
|
|
|
|
func Load(fname string) error {
|
|
yamlData, err := os.ReadFile(fname)
|
|
if err != nil {
|
|
return fmt.Errorf("config: couldn't read config file: %w", err)
|
|
}
|
|
|
|
var cfg Config
|
|
err = yaml.Unmarshal(yamlData, &cfg)
|
|
if err != nil {
|
|
return fmt.Errorf("config: couldn't parse config file: %w", err)
|
|
}
|
|
|
|
c = cfg
|
|
|
|
return nil
|
|
}
|
|
|
|
func Save(fname string) error {
|
|
data, err := yaml.Marshal(c)
|
|
if err != nil {
|
|
return fmt.Errorf("config: failed to marshal config: %w", err)
|
|
}
|
|
|
|
err = os.WriteFile(fname, data, 0o660)
|
|
if err != nil {
|
|
return fmt.Errorf("config: failed to write config: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|