mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-10-05 08:16:55 +08:00
Code refactoring for app module
This commit is contained in:
@@ -1,29 +1,20 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/shell"
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/yaml"
|
|
||||||
"github.com/rs/zerolog"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version = "1.9.2"
|
var (
|
||||||
var UserAgent = "go2rtc/" + Version
|
Version string
|
||||||
|
UserAgent string
|
||||||
var ConfigPath string
|
ConfigPath string
|
||||||
var Info = map[string]any{
|
Info = make(map[string]any)
|
||||||
"version": Version,
|
)
|
||||||
}
|
|
||||||
|
|
||||||
const usage = `Usage of go2rtc:
|
const usage = `Usage of go2rtc:
|
||||||
|
|
||||||
@@ -33,12 +24,12 @@ const usage = `Usage of go2rtc:
|
|||||||
`
|
`
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
var confs Config
|
var config flagConfig
|
||||||
var daemon bool
|
var daemon bool
|
||||||
var version bool
|
var version bool
|
||||||
|
|
||||||
flag.Var(&confs, "config", "")
|
flag.Var(&config, "config", "")
|
||||||
flag.Var(&confs, "c", "")
|
flag.Var(&config, "c", "")
|
||||||
flag.BoolVar(&daemon, "daemon", false, "")
|
flag.BoolVar(&daemon, "daemon", false, "")
|
||||||
flag.BoolVar(&daemon, "d", false, "")
|
flag.BoolVar(&daemon, "d", false, "")
|
||||||
flag.BoolVar(&version, "version", false, "")
|
flag.BoolVar(&version, "version", false, "")
|
||||||
@@ -69,118 +60,30 @@ func Init() {
|
|||||||
// Re-run the program in background and exit
|
// Re-run the program in background and exit
|
||||||
cmd := exec.Command(os.Args[0], args...)
|
cmd := exec.Command(os.Args[0], args...)
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
log.Fatal().Err(err).Send()
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
fmt.Println("Running in daemon mode with PID:", cmd.Process.Pid)
|
fmt.Println("Running in daemon mode with PID:", cmd.Process.Pid)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if confs == nil {
|
UserAgent = "go2rtc/" + Version
|
||||||
confs = []string{"go2rtc.yaml"}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, conf := range confs {
|
|
||||||
if len(conf) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if conf[0] == '{' {
|
|
||||||
// config as raw YAML or JSON
|
|
||||||
configs = append(configs, []byte(conf))
|
|
||||||
} else if data := parseConfString(conf); data != nil {
|
|
||||||
configs = append(configs, data)
|
|
||||||
} else {
|
|
||||||
// config as file
|
|
||||||
if ConfigPath == "" {
|
|
||||||
ConfigPath = conf
|
|
||||||
}
|
|
||||||
|
|
||||||
if data, _ = os.ReadFile(conf); data == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
data = []byte(shell.ReplaceEnvVars(string(data)))
|
|
||||||
configs = append(configs, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ConfigPath != "" {
|
|
||||||
if !filepath.IsAbs(ConfigPath) {
|
|
||||||
if cwd, err := os.Getwd(); err == nil {
|
|
||||||
ConfigPath = filepath.Join(cwd, ConfigPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Info["config_path"] = ConfigPath
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Info["version"] = Version
|
||||||
Info["revision"] = revision
|
Info["revision"] = revision
|
||||||
|
|
||||||
var cfg struct {
|
initConfig(config)
|
||||||
Mod map[string]string `yaml:"log"`
|
initLogger()
|
||||||
}
|
|
||||||
|
|
||||||
cfg.Mod = map[string]string{
|
|
||||||
"format": "", // useless, but anyway
|
|
||||||
"level": "info",
|
|
||||||
"output": "stdout", // TODO: change to stderr someday
|
|
||||||
"time": zerolog.TimeFormatUnixMs,
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadConfig(&cfg)
|
|
||||||
|
|
||||||
log.Logger = NewLogger(cfg.Mod)
|
|
||||||
|
|
||||||
modules = cfg.Mod
|
|
||||||
|
|
||||||
platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
||||||
log.Info().Str("version", Version).Str("platform", platform).Str("revision", revision).Msg("go2rtc")
|
Logger.Info().Str("version", Version).Str("platform", platform).Str("revision", revision).Msg("go2rtc")
|
||||||
log.Debug().Str("version", runtime.Version()).Str("vcs.time", vcsTime).Msg("build")
|
Logger.Debug().Str("version", runtime.Version()).Str("vcs.time", vcsTime).Msg("build")
|
||||||
|
|
||||||
if ConfigPath != "" {
|
if ConfigPath != "" {
|
||||||
log.Info().Str("path", ConfigPath).Msg("config")
|
Logger.Info().Str("path", ConfigPath).Msg("config")
|
||||||
}
|
|
||||||
|
|
||||||
migrateStore()
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadConfig(v any) {
|
|
||||||
for _, data := range configs {
|
|
||||||
if err := yaml.Unmarshal(data, v); err != nil {
|
|
||||||
log.Warn().Err(err).Msg("[app] read config")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PatchConfig(key string, value any, path ...string) error {
|
|
||||||
if ConfigPath == "" {
|
|
||||||
return errors.New("config file disabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
// empty config is OK
|
|
||||||
b, _ := os.ReadFile(ConfigPath)
|
|
||||||
|
|
||||||
b, err := yaml.Patch(b, key, value, path...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.WriteFile(ConfigPath, b, 0644)
|
|
||||||
}
|
|
||||||
|
|
||||||
// internal
|
|
||||||
|
|
||||||
type Config []string
|
|
||||||
|
|
||||||
func (c *Config) String() string {
|
|
||||||
return strings.Join(*c, " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) Set(value string) error {
|
|
||||||
*c = append(*c, value)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var configs [][]byte
|
|
||||||
|
|
||||||
func readRevisionTime() (revision, vcsTime string) {
|
func readRevisionTime() (revision, vcsTime string) {
|
||||||
if info, ok := debug.ReadBuildInfo(); ok {
|
if info, ok := debug.ReadBuildInfo(); ok {
|
||||||
for _, setting := range info.Settings {
|
for _, setting := range info.Settings {
|
||||||
@@ -202,25 +105,3 @@ func readRevisionTime() (revision, vcsTime string) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseConfString(s string) []byte {
|
|
||||||
i := strings.IndexByte(s, '=')
|
|
||||||
if i < 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
items := strings.Split(s[:i], ".")
|
|
||||||
if len(items) < 2 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// `log.level=trace` => `{log: {level: trace}}`
|
|
||||||
var pre string
|
|
||||||
var suf = s[i+1:]
|
|
||||||
for _, item := range items {
|
|
||||||
pre += "{" + item + ": "
|
|
||||||
suf += "}"
|
|
||||||
}
|
|
||||||
|
|
||||||
return []byte(pre + suf)
|
|
||||||
}
|
|
||||||
|
109
internal/app/config.go
Normal file
109
internal/app/config.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/shell"
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadConfig(v any) {
|
||||||
|
for _, data := range configs {
|
||||||
|
if err := yaml.Unmarshal(data, v); err != nil {
|
||||||
|
Logger.Warn().Err(err).Send()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PatchConfig(key string, value any, path ...string) error {
|
||||||
|
if ConfigPath == "" {
|
||||||
|
return errors.New("config file disabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty config is OK
|
||||||
|
b, _ := os.ReadFile(ConfigPath)
|
||||||
|
|
||||||
|
b, err := yaml.Patch(b, key, value, path...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.WriteFile(ConfigPath, b, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
type flagConfig []string
|
||||||
|
|
||||||
|
func (c *flagConfig) String() string {
|
||||||
|
return strings.Join(*c, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *flagConfig) Set(value string) error {
|
||||||
|
*c = append(*c, value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var configs [][]byte
|
||||||
|
|
||||||
|
func initConfig(confs flagConfig) {
|
||||||
|
if confs == nil {
|
||||||
|
confs = []string{"go2rtc.yaml"}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, conf := range confs {
|
||||||
|
if len(conf) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if conf[0] == '{' {
|
||||||
|
// config as raw YAML or JSON
|
||||||
|
configs = append(configs, []byte(conf))
|
||||||
|
} else if data := parseConfString(conf); data != nil {
|
||||||
|
configs = append(configs, data)
|
||||||
|
} else {
|
||||||
|
// config as file
|
||||||
|
if ConfigPath == "" {
|
||||||
|
ConfigPath = conf
|
||||||
|
}
|
||||||
|
|
||||||
|
if data, _ = os.ReadFile(conf); data == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
data = []byte(shell.ReplaceEnvVars(string(data)))
|
||||||
|
configs = append(configs, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ConfigPath != "" {
|
||||||
|
if !filepath.IsAbs(ConfigPath) {
|
||||||
|
if cwd, err := os.Getwd(); err == nil {
|
||||||
|
ConfigPath = filepath.Join(cwd, ConfigPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Info["config_path"] = ConfigPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseConfString(s string) []byte {
|
||||||
|
i := strings.IndexByte(s, '=')
|
||||||
|
if i < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
items := strings.Split(s[:i], ".")
|
||||||
|
if len(items) < 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// `log.level=trace` => `{log: {level: trace}}`
|
||||||
|
var pre string
|
||||||
|
var suf = s[i+1:]
|
||||||
|
for _, item := range items {
|
||||||
|
pre += "{" + item + ": "
|
||||||
|
suf += "}"
|
||||||
|
}
|
||||||
|
|
||||||
|
return []byte(pre + suf)
|
||||||
|
}
|
@@ -6,30 +6,49 @@ import (
|
|||||||
|
|
||||||
"github.com/mattn/go-isatty"
|
"github.com/mattn/go-isatty"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var MemoryLog = newBuffer(16)
|
var MemoryLog = newBuffer(16)
|
||||||
|
|
||||||
// NewLogger support:
|
func GetLogger(module string) zerolog.Logger {
|
||||||
|
if s, ok := modules[module]; ok {
|
||||||
|
lvl, err := zerolog.ParseLevel(s)
|
||||||
|
if err == nil {
|
||||||
|
return Logger.Level(lvl)
|
||||||
|
}
|
||||||
|
Logger.Warn().Err(err).Caller().Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
return Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// initLogger support:
|
||||||
// - output: empty (only to memory), stderr, stdout
|
// - output: empty (only to memory), stderr, stdout
|
||||||
// - format: empty (autodetect color support), color, json, text
|
// - format: empty (autodetect color support), color, json, text
|
||||||
// - time: empty (disable timestamp), UNIXMS, UNIXMICRO, UNIXNANO
|
// - time: empty (disable timestamp), UNIXMS, UNIXMICRO, UNIXNANO
|
||||||
// - level: disabled, trace, debug, info, warn, error...
|
// - level: disabled, trace, debug, info, warn, error...
|
||||||
func NewLogger(config map[string]string) zerolog.Logger {
|
func initLogger() {
|
||||||
|
var cfg struct {
|
||||||
|
Mod map[string]string `yaml:"log"`
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.Mod = modules // defaults
|
||||||
|
|
||||||
|
LoadConfig(&cfg)
|
||||||
|
|
||||||
var writer io.Writer
|
var writer io.Writer
|
||||||
|
|
||||||
switch config["output"] {
|
switch modules["output"] {
|
||||||
case "stderr":
|
case "stderr":
|
||||||
writer = os.Stderr
|
writer = os.Stderr
|
||||||
case "stdout":
|
case "stdout":
|
||||||
writer = os.Stdout
|
writer = os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
timeFormat := config["time"]
|
timeFormat := modules["time"]
|
||||||
|
|
||||||
if writer != nil {
|
if writer != nil {
|
||||||
if format := config["format"]; format != "json" {
|
if format := modules["format"]; format != "json" {
|
||||||
console := &zerolog.ConsoleWriter{Out: writer}
|
console := &zerolog.ConsoleWriter{Out: writer}
|
||||||
|
|
||||||
switch format {
|
switch format {
|
||||||
@@ -61,31 +80,24 @@ func NewLogger(config map[string]string) zerolog.Logger {
|
|||||||
writer = MemoryLog
|
writer = MemoryLog
|
||||||
}
|
}
|
||||||
|
|
||||||
logger := zerolog.New(writer)
|
lvl, _ := zerolog.ParseLevel(modules["level"])
|
||||||
|
Logger = zerolog.New(writer).Level(lvl)
|
||||||
|
|
||||||
if timeFormat != "" {
|
if timeFormat != "" {
|
||||||
zerolog.TimeFieldFormat = timeFormat
|
zerolog.TimeFieldFormat = timeFormat
|
||||||
logger = logger.With().Timestamp().Logger()
|
Logger = Logger.With().Timestamp().Logger()
|
||||||
}
|
}
|
||||||
|
|
||||||
lvl, _ := zerolog.ParseLevel(config["level"])
|
|
||||||
return logger.Level(lvl)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLogger(module string) zerolog.Logger {
|
var Logger zerolog.Logger
|
||||||
if s, ok := modules[module]; ok {
|
|
||||||
lvl, err := zerolog.ParseLevel(s)
|
|
||||||
if err == nil {
|
|
||||||
return log.Level(lvl)
|
|
||||||
}
|
|
||||||
log.Warn().Err(err).Caller().Send()
|
|
||||||
}
|
|
||||||
|
|
||||||
return log.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
// modules log levels
|
// modules log levels
|
||||||
var modules map[string]string
|
var modules = map[string]string{
|
||||||
|
"format": "", // useless, but anyway
|
||||||
|
"level": "info",
|
||||||
|
"output": "stdout", // TODO: change to stderr someday
|
||||||
|
"time": zerolog.TimeFormatUnixMs,
|
||||||
|
}
|
||||||
|
|
||||||
const chunkSize = 1 << 16
|
const chunkSize = 1 << 16
|
||||||
|
|
||||||
|
@@ -1,35 +0,0 @@
|
|||||||
package app
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func migrateStore() {
|
|
||||||
const name = "go2rtc.json"
|
|
||||||
|
|
||||||
data, _ := os.ReadFile(name)
|
|
||||||
if data == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var store struct {
|
|
||||||
Streams map[string]string `json:"streams"`
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.Unmarshal(data, &store); err != nil {
|
|
||||||
log.Warn().Err(err).Caller().Send()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for id, url := range store.Streams {
|
|
||||||
if err := PatchConfig(id, url, "streams"); err != nil {
|
|
||||||
log.Warn().Err(err).Caller().Send()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = os.Remove(name)
|
|
||||||
}
|
|
@@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/AlexxIT/go2rtc/internal/streams"
|
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/dvrip"
|
"github.com/AlexxIT/go2rtc/pkg/dvrip"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -92,10 +91,7 @@ func sendBroadcasts(conn *net.UDPConn) {
|
|||||||
|
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
_, _ = conn.WriteToUDP(data, addr)
|
||||||
if _, err = conn.WriteToUDP(data, addr); err != nil {
|
|
||||||
log.Err(err).Caller().Send()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/AlexxIT/go2rtc/internal/streams"
|
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
|
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -29,6 +30,8 @@ func Init() {
|
|||||||
|
|
||||||
app.LoadConfig(&cfg)
|
app.LoadConfig(&cfg)
|
||||||
|
|
||||||
|
log = app.GetLogger("ffmpeg")
|
||||||
|
|
||||||
// zerolog levels: trace debug info warn error fatal panic disabled
|
// zerolog levels: trace debug info warn error fatal panic disabled
|
||||||
// FFmpeg levels: trace debug verbose info warning error fatal panic quiet
|
// FFmpeg levels: trace debug verbose info warning error fatal panic quiet
|
||||||
if cfg.Log.Level == "warn" {
|
if cfg.Log.Level == "warn" {
|
||||||
@@ -145,6 +148,8 @@ var defaults = map[string]string{
|
|||||||
"h265/videotoolbox": "-c:v hevc_videotoolbox -g 50 -bf 0 -profile:v main -level:v 5.1",
|
"h265/videotoolbox": "-c:v hevc_videotoolbox -g 50 -bf 0 -profile:v main -level:v 5.1",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var log zerolog.Logger
|
||||||
|
|
||||||
// configTemplate - return template from config (defaults) if exist or return raw template
|
// configTemplate - return template from config (defaults) if exist or return raw template
|
||||||
func configTemplate(template string) string {
|
func configTemplate(template string) string {
|
||||||
if s := defaults[template]; s != "" {
|
if s := defaults[template]; s != "" {
|
||||||
|
@@ -7,8 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
|
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -152,7 +150,6 @@ var cache = map[string]string{}
|
|||||||
|
|
||||||
func run(bin string, args string) bool {
|
func run(bin string, args string) bool {
|
||||||
err := exec.Command(bin, strings.Split(args, " ")...).Run()
|
err := exec.Command(bin, strings.Split(args, " ")...).Run()
|
||||||
log.Printf("%v %v", args, err)
|
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,7 +6,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
|
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var verMu sync.Mutex
|
var verMu sync.Mutex
|
||||||
|
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
"github.com/AlexxIT/go2rtc/internal/api/ws"
|
"github.com/AlexxIT/go2rtc/internal/api/ws"
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/app"
|
||||||
"github.com/AlexxIT/go2rtc/internal/ffmpeg"
|
"github.com/AlexxIT/go2rtc/internal/ffmpeg"
|
||||||
"github.com/AlexxIT/go2rtc/internal/streams"
|
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/ascii"
|
"github.com/AlexxIT/go2rtc/pkg/ascii"
|
||||||
@@ -18,7 +19,7 @@ import (
|
|||||||
"github.com/AlexxIT/go2rtc/pkg/mjpeg"
|
"github.com/AlexxIT/go2rtc/pkg/mjpeg"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/tcp"
|
"github.com/AlexxIT/go2rtc/pkg/tcp"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/y4m"
|
"github.com/AlexxIT/go2rtc/pkg/y4m"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -28,8 +29,12 @@ func Init() {
|
|||||||
api.HandleFunc("api/stream.y4m", apiStreamY4M)
|
api.HandleFunc("api/stream.y4m", apiStreamY4M)
|
||||||
|
|
||||||
ws.HandleFunc("mjpeg", handlerWS)
|
ws.HandleFunc("mjpeg", handlerWS)
|
||||||
|
|
||||||
|
log = app.GetLogger("mjpeg")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var log zerolog.Logger
|
||||||
|
|
||||||
func handlerKeyframe(w http.ResponseWriter, r *http.Request) {
|
func handlerKeyframe(w http.ResponseWriter, r *http.Request) {
|
||||||
src := r.URL.Query().Get("src")
|
src := r.URL.Query().Get("src")
|
||||||
stream := streams.Get(src)
|
stream := streams.Get(src)
|
||||||
|
@@ -7,7 +7,6 @@ import (
|
|||||||
"github.com/AlexxIT/go2rtc/internal/streams"
|
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/aac"
|
"github.com/AlexxIT/go2rtc/pkg/aac"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/tcp"
|
"github.com/AlexxIT/go2rtc/pkg/tcp"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func apiStreamAAC(w http.ResponseWriter, r *http.Request) {
|
func apiStreamAAC(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -23,7 +22,6 @@ func apiStreamAAC(w http.ResponseWriter, r *http.Request) {
|
|||||||
cons.UserAgent = r.UserAgent()
|
cons.UserAgent = r.UserAgent()
|
||||||
|
|
||||||
if err := stream.AddConsumer(cons); err != nil {
|
if err := stream.AddConsumer(cons); err != nil {
|
||||||
log.Error().Err(err).Caller().Send()
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,6 @@ import (
|
|||||||
"github.com/AlexxIT/go2rtc/internal/streams"
|
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/mpegts"
|
"github.com/AlexxIT/go2rtc/pkg/mpegts"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/tcp"
|
"github.com/AlexxIT/go2rtc/pkg/tcp"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -36,7 +35,6 @@ func outputMpegTS(w http.ResponseWriter, r *http.Request) {
|
|||||||
cons.UserAgent = r.UserAgent()
|
cons.UserAgent = r.UserAgent()
|
||||||
|
|
||||||
if err := stream.AddConsumer(cons); err != nil {
|
if err := stream.AddConsumer(cons); err != nil {
|
||||||
log.Error().Err(err).Caller().Send()
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
2
main.go
2
main.go
@@ -36,6 +36,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
app.Version = "1.9.2"
|
||||||
|
|
||||||
// 1. Core modules: app, api/ws, streams
|
// 1. Core modules: app, api/ws, streams
|
||||||
|
|
||||||
app.Init() // init config and logs
|
app.Init() // init config and logs
|
||||||
|
@@ -5,7 +5,6 @@ import (
|
|||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
"github.com/pion/rtp"
|
"github.com/pion/rtp"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Log(handler core.HandlerFunc) core.HandlerFunc {
|
func Log(handler core.HandlerFunc) core.HandlerFunc {
|
@@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -138,7 +137,7 @@ func (c *Client) Connect() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
offer := pc.LocalDescription()
|
offer := pc.LocalDescription()
|
||||||
log.Printf("[roborock] offer\n%s", offer.SDP)
|
//log.Printf("[roborock] offer\n%s", offer.SDP)
|
||||||
if err = c.SendSDPtoRobot(offer); err != nil {
|
if err = c.SendSDPtoRobot(offer); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -151,7 +150,7 @@ func (c *Client) Connect() error {
|
|||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
if desc, _ := c.GetDeviceSDP(); desc != nil {
|
if desc, _ := c.GetDeviceSDP(); desc != nil {
|
||||||
log.Printf("[roborock] answer\n%s", desc.SDP)
|
//log.Printf("[roborock] answer\n%s", desc.SDP)
|
||||||
if err = c.conn.SetAnswer(desc.SDP); err != nil {
|
if err = c.conn.SetAnswer(desc.SDP); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -6,12 +6,12 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/mqtt"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"net"
|
"net"
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/mqtt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Codec struct {
|
type Codec struct {
|
||||||
@@ -56,7 +56,7 @@ func (c *Codec) WriteRequest(r *rpc.Request, v any) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[roborock] send: %s", payload)
|
//log.Printf("[roborock] send: %s", payload)
|
||||||
|
|
||||||
payload = c.Encrypt(payload, ts, ts, ts)
|
payload = c.Encrypt(payload, ts, ts, ts)
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ func (c *Codec) ReadResponseHeader(r *rpc.Response) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[roborock] recv %s", payload)
|
//log.Printf("[roborock] recv %s", payload)
|
||||||
|
|
||||||
// get content from response payload:
|
// get content from response payload:
|
||||||
// {"t":1676871268,"dps":{"102":"{\"id\":315003,\"result\":[\"ok\"]}"}}
|
// {"t":1676871268,"dps":{"102":"{\"id\":315003,\"result\":[\"ok\"]}"}}
|
||||||
|
Reference in New Issue
Block a user