slight changes, moved around a few things
This commit is contained in:
parent
0e9fbf7ba2
commit
e4a554830d
@ -1,11 +1,20 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/diode"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"n.eko.moe/neko"
|
||||
"n.eko.moe/neko/internal/preflight"
|
||||
)
|
||||
|
||||
func Execute() error {
|
||||
@ -21,8 +30,92 @@ var root = &cobra.Command{
|
||||
|
||||
func init() {
|
||||
cobra.OnInitialize(func() {
|
||||
preflight.Logs("neko")
|
||||
preflight.Config("neko")
|
||||
//////
|
||||
// logs
|
||||
//////
|
||||
zerolog.TimeFieldFormat = ""
|
||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||
|
||||
if viper.GetBool("debug") {
|
||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||
}
|
||||
|
||||
console := zerolog.ConsoleWriter{Out: os.Stdout}
|
||||
|
||||
if !viper.GetBool("logs") {
|
||||
log.Logger = log.Output(console)
|
||||
} else {
|
||||
|
||||
logs := filepath.Join(".", "logs")
|
||||
if runtime.GOOS == "linux" {
|
||||
logs = "/var/log/neko"
|
||||
}
|
||||
|
||||
if _, err := os.Stat(logs); os.IsNotExist(err) {
|
||||
os.Mkdir(logs, os.ModePerm)
|
||||
}
|
||||
|
||||
latest := filepath.Join(logs, "neko-latest.log")
|
||||
_, err := os.Stat(latest)
|
||||
if err == nil {
|
||||
err = os.Rename(latest, filepath.Join(logs, "neko."+time.Now().Format("2006-01-02T15-04-05Z07-00")+".log"))
|
||||
if err != nil {
|
||||
log.Panic().Err(err).Msg("failed to rotate log file")
|
||||
}
|
||||
}
|
||||
|
||||
logf, err := os.OpenFile(latest, os.O_RDWR|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
log.Panic().Err(err).Msg("failed to create log file")
|
||||
}
|
||||
|
||||
logger := diode.NewWriter(logf, 1000, 10*time.Millisecond, func(missed int) {
|
||||
fmt.Printf("logger dropped %d messages", missed)
|
||||
})
|
||||
|
||||
log.Logger = log.Output(io.MultiWriter(console, logger))
|
||||
}
|
||||
|
||||
//////
|
||||
// configs
|
||||
//////
|
||||
config := viper.GetString("config")
|
||||
if config != "" {
|
||||
viper.SetConfigFile(config) // Use config file from the flag.
|
||||
} else {
|
||||
if runtime.GOOS == "linux" {
|
||||
viper.AddConfigPath("/etc/neko/")
|
||||
}
|
||||
|
||||
viper.AddConfigPath(".")
|
||||
viper.SetConfigName("neko")
|
||||
}
|
||||
|
||||
viper.SetEnvPrefix("NEKO")
|
||||
viper.AutomaticEnv() // read in environment variables that match
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
|
||||
log.Error().Err(err)
|
||||
}
|
||||
if config != "" {
|
||||
log.Error().Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
file := viper.ConfigFileUsed()
|
||||
logger := log.With().
|
||||
Bool("debug", viper.GetBool("debug")).
|
||||
Str("logging", viper.GetString("logs")).
|
||||
Str("config", file).
|
||||
Logger()
|
||||
|
||||
if file == "" {
|
||||
logger.Warn().Msg("preflight complete without config file")
|
||||
} else {
|
||||
logger.Info().Msg("preflight complete")
|
||||
}
|
||||
|
||||
neko.Service.Root.Set()
|
||||
})
|
||||
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"n.eko.moe/neko"
|
||||
"n.eko.moe/neko/internal/config"
|
||||
"n.eko.moe/neko/internal/types/config"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -127,7 +127,6 @@ github.com/pion/transport v0.8.10 h1:lTiobMEw2PG6BH/mgIVqTV2mBp/mPT+IJLaN8ZxgdHk
|
||||
github.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8=
|
||||
github.com/pion/turn v1.4.0 h1:7NUMRehQz4fIo53Qv9ui1kJ0Kr1CA82I81RHKHCeM80=
|
||||
github.com/pion/turn v1.4.0/go.mod h1:aDSi6hWX/hd1+gKia9cExZOR0MU95O7zX9p3Gw/P2aU=
|
||||
github.com/pion/webrtc v1.2.0 h1:3LGGPQEMacwG2hcDfhdvwQPz315gvjZXOfY4vaF4+I4=
|
||||
github.com/pion/webrtc/v2 v2.1.18 h1:g0VN0xfEUSlVNfQmlCD6yOeXy/tMaktESBmHMnBS3bk=
|
||||
github.com/pion/webrtc/v2 v2.1.18/go.mod h1:m0rKlYgLRZWyhmcMWegpF6xtK1ASxmOg8DAR74ttzQY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
|
@ -79,7 +79,7 @@ func CreatePipeline(codecName string, pipelineSrc string) (*Pipeline, error) {
|
||||
// gstreamer1.0-plugins-good
|
||||
// vp9enc
|
||||
|
||||
// Causes panic!
|
||||
// Causes panic! not sure why...
|
||||
pipelineStr = pipelineSrc + " ! vp9enc ! " + pipelineStr
|
||||
clockRate = videoClockRate
|
||||
|
||||
@ -88,7 +88,6 @@ func CreatePipeline(codecName string, pipelineSrc string) (*Pipeline, error) {
|
||||
}
|
||||
|
||||
case webrtc.H264:
|
||||
|
||||
// https://gstreamer.freedesktop.org/documentation/openh264/openh264enc.html?gi-language=c#openh264enc
|
||||
// gstreamer1.0-plugins-bad
|
||||
// openh264enc multi-thread=4 complexity=high bitrate=3072000 max-bitrate=4096000
|
||||
|
@ -10,10 +10,10 @@ import (
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"n.eko.moe/neko/internal/config"
|
||||
"n.eko.moe/neko/internal/http/endpoint"
|
||||
"n.eko.moe/neko/internal/http/middleware"
|
||||
"n.eko.moe/neko/internal/websocket"
|
||||
"n.eko.moe/neko/internal/types"
|
||||
"n.eko.moe/neko/internal/types/config"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
@ -23,7 +23,7 @@ type Server struct {
|
||||
conf *config.Server
|
||||
}
|
||||
|
||||
func New(conf *config.Server, webSocketHandler *websocket.WebSocketHandler) *Server {
|
||||
func New(conf *config.Server, webSocketHandler types.WebSocketHandler) *Server {
|
||||
logger := log.With().Str("module", "webrtc").Logger()
|
||||
|
||||
router := chi.NewRouter()
|
||||
|
@ -1,48 +0,0 @@
|
||||
package preflight
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func Config(name string) {
|
||||
config := viper.GetString("config")
|
||||
|
||||
if config != "" {
|
||||
viper.SetConfigFile(config) // Use config file from the flag.
|
||||
} else {
|
||||
if runtime.GOOS == "linux" {
|
||||
viper.AddConfigPath("/etc/neko/")
|
||||
}
|
||||
|
||||
viper.AddConfigPath(".")
|
||||
viper.SetConfigName(name)
|
||||
}
|
||||
|
||||
viper.SetEnvPrefix("NEKO")
|
||||
viper.AutomaticEnv() // read in environment variables that match
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
|
||||
log.Error().Err(err)
|
||||
}
|
||||
if config != "" {
|
||||
log.Error().Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
file := viper.ConfigFileUsed()
|
||||
logger := log.With().
|
||||
Bool("debug", viper.GetBool("debug")).
|
||||
Str("logging", viper.GetString("logs")).
|
||||
Str("config", file).
|
||||
Logger()
|
||||
|
||||
if file == "" {
|
||||
logger.Warn().Msg("preflight complete without config file")
|
||||
} else {
|
||||
logger.Info().Msg("preflight complete")
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package preflight
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/diode"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func Logs(name string) {
|
||||
zerolog.TimeFieldFormat = ""
|
||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||
|
||||
if viper.GetBool("debug") {
|
||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||
}
|
||||
|
||||
console := zerolog.ConsoleWriter{Out: os.Stdout}
|
||||
|
||||
if !viper.GetBool("logs") {
|
||||
log.Logger = log.Output(console)
|
||||
} else {
|
||||
|
||||
logs := filepath.Join(".", "logs")
|
||||
if runtime.GOOS == "linux" {
|
||||
logs = "/var/log/neko"
|
||||
}
|
||||
|
||||
if _, err := os.Stat(logs); os.IsNotExist(err) {
|
||||
os.Mkdir(logs, os.ModePerm)
|
||||
}
|
||||
|
||||
latest := filepath.Join(logs, name+"-latest.log")
|
||||
_, err := os.Stat(latest)
|
||||
if err == nil {
|
||||
err = os.Rename(latest, filepath.Join(logs, "neko."+time.Now().Format("2006-01-02T15-04-05Z07-00")+".log"))
|
||||
if err != nil {
|
||||
log.Panic().Err(err).Msg("failed to rotate log file")
|
||||
}
|
||||
}
|
||||
|
||||
logf, err := os.OpenFile(latest, os.O_RDWR|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
log.Panic().Err(err).Msg("failed to create log file")
|
||||
}
|
||||
|
||||
logger := diode.NewWriter(logf, 1000, 10*time.Millisecond, func(missed int) {
|
||||
fmt.Printf("logger dropped %d messages", missed)
|
||||
})
|
||||
|
||||
log.Logger = log.Output(io.MultiWriter(console, logger))
|
||||
}
|
||||
}
|
@ -1,18 +1,23 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pion/webrtc/v2"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type WebRTC struct {
|
||||
Device string
|
||||
AudioCodec string
|
||||
AudioParams string
|
||||
Display string
|
||||
VideoCodec string
|
||||
VideoParams string
|
||||
Device string
|
||||
AudioCodec string
|
||||
AudioParams string
|
||||
Display string
|
||||
VideoCodec string
|
||||
VideoParams string
|
||||
EphemeralStart uint16
|
||||
EphemeralEnd uint16
|
||||
}
|
||||
|
||||
func (WebRTC) Init(cmd *cobra.Command) error {
|
||||
@ -21,54 +26,59 @@ func (WebRTC) Init(cmd *cobra.Command) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().String("aduio", "", "Audio codec parameters to use for streaming")
|
||||
cmd.PersistentFlags().String("aduio", "", "Audio codec parameters to use for streaming (unused)")
|
||||
if err := viper.BindPFlag("aparams", cmd.PersistentFlags().Lookup("aduio")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().String("display", ":0.0", "XDisplay to capture")
|
||||
cmd.PersistentFlags().String("display", ":99.0", "XDisplay to capture")
|
||||
if err := viper.BindPFlag("display", cmd.PersistentFlags().Lookup("display")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().String("video", "", "Video codec parameters to use for streaming")
|
||||
cmd.PersistentFlags().String("video", "", "Video codec parameters to use for streaming (unused)")
|
||||
if err := viper.BindPFlag("vparams", cmd.PersistentFlags().Lookup("video")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().String("epr", "59000-59100", "Limits the pool of ephemeral ports that ICE UDP connections can allocate from")
|
||||
if err := viper.BindPFlag("epr", cmd.PersistentFlags().Lookup("epr")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// video codecs
|
||||
cmd.PersistentFlags().Bool("vp8", false, "Use VP8 codec")
|
||||
cmd.PersistentFlags().Bool("vp8", false, "Use VP8 video codec")
|
||||
if err := viper.BindPFlag("vp8", cmd.PersistentFlags().Lookup("vp8")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().Bool("vp9", false, "Use VP9 codec")
|
||||
cmd.PersistentFlags().Bool("vp9", false, "Use VP9 video codec")
|
||||
if err := viper.BindPFlag("vp9", cmd.PersistentFlags().Lookup("vp9")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().Bool("h264", false, "Use H264 codec")
|
||||
cmd.PersistentFlags().Bool("h264", false, "Use H264 video codec")
|
||||
if err := viper.BindPFlag("h264", cmd.PersistentFlags().Lookup("h264")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// audio codecs
|
||||
cmd.PersistentFlags().Bool("opus", false, "Use Opus codec")
|
||||
cmd.PersistentFlags().Bool("opus", false, "Use Opus audio codec")
|
||||
if err := viper.BindPFlag("opus", cmd.PersistentFlags().Lookup("opus")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().Bool("g722", false, "Use G722 codec")
|
||||
cmd.PersistentFlags().Bool("g722", false, "Use G722 audio codec")
|
||||
if err := viper.BindPFlag("g722", cmd.PersistentFlags().Lookup("g722")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().Bool("pcmu", false, "Use PCMU codec")
|
||||
cmd.PersistentFlags().Bool("pcmu", false, "Use PCMU audio codec")
|
||||
if err := viper.BindPFlag("pcmu", cmd.PersistentFlags().Lookup("pcmu")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().Bool("pcma", false, "Use PCMA codec")
|
||||
cmd.PersistentFlags().Bool("pcma", false, "Use PCMA audio codec")
|
||||
if err := viper.BindPFlag("pcmu", cmd.PersistentFlags().Lookup("pcmu")); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -103,4 +113,19 @@ func (s *WebRTC) Set() {
|
||||
s.Display = viper.GetString("display")
|
||||
s.VideoCodec = videoCodec
|
||||
s.VideoParams = viper.GetString("vparams")
|
||||
s.EphemeralStart = 59000
|
||||
s.EphemeralEnd = 59100
|
||||
|
||||
epr := viper.GetString("epr")
|
||||
ports := strings.SplitN(epr, "-", -1)
|
||||
if len(ports[0]) > 1 {
|
||||
start, err := strconv.ParseUint(ports[0], 16, 16)
|
||||
if err == nil {
|
||||
s.EphemeralStart = uint16(start)
|
||||
}
|
||||
end, err := strconv.ParseUint(ports[1], 16, 16)
|
||||
if err == nil {
|
||||
s.EphemeralEnd = uint16(end)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,15 @@
|
||||
package types
|
||||
|
||||
import "net/http"
|
||||
|
||||
type WebScoket interface {
|
||||
Address() *string
|
||||
Send(v interface{}) error
|
||||
Destroy() error
|
||||
}
|
||||
|
||||
type WebSocketHandler interface {
|
||||
Start() error
|
||||
Shutdown() error
|
||||
Upgrade(w http.ResponseWriter, r *http.Request) error
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ import (
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"n.eko.moe/neko/internal/config"
|
||||
"n.eko.moe/neko/internal/gst"
|
||||
"n.eko.moe/neko/internal/hid"
|
||||
"n.eko.moe/neko/internal/types"
|
||||
"n.eko.moe/neko/internal/types/config"
|
||||
)
|
||||
|
||||
func New(sessions types.SessionManager, config *config.WebRTC) *WebRTCManager {
|
||||
@ -22,7 +22,7 @@ func New(sessions types.SessionManager, config *config.WebRTC) *WebRTCManager {
|
||||
},
|
||||
}
|
||||
|
||||
setings.SetEphemeralUDPPortRange(59000, 59100)
|
||||
setings.SetEphemeralUDPPortRange(config.EphemeralStart, config.EphemeralEnd)
|
||||
|
||||
return &WebRTCManager{
|
||||
logger: logger,
|
||||
|
@ -9,9 +9,9 @@ import (
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"n.eko.moe/neko/internal/config"
|
||||
"n.eko.moe/neko/internal/hid/clipboard"
|
||||
"n.eko.moe/neko/internal/types"
|
||||
"n.eko.moe/neko/internal/types/config"
|
||||
"n.eko.moe/neko/internal/types/event"
|
||||
"n.eko.moe/neko/internal/types/message"
|
||||
"n.eko.moe/neko/internal/utils"
|
||||
|
@ -6,9 +6,9 @@ import (
|
||||
"os/signal"
|
||||
"runtime"
|
||||
|
||||
"n.eko.moe/neko/internal/config"
|
||||
"n.eko.moe/neko/internal/http"
|
||||
"n.eko.moe/neko/internal/session"
|
||||
"n.eko.moe/neko/internal/types/config"
|
||||
"n.eko.moe/neko/internal/webrtc"
|
||||
"n.eko.moe/neko/internal/websocket"
|
||||
|
||||
|
Reference in New Issue
Block a user