From c228921237edb09bad891c88aae0135fe4a9f4a4 Mon Sep 17 00:00:00 2001 From: Artem Date: Tue, 5 Nov 2024 23:47:00 +0100 Subject: [PATCH] project structure refactoring --- cmd/kvm/main.go | 29 ++++++++++--------- config/config.go | 18 +++++++----- {http/hw/stream => external/ffmpeg}/ffmpeg.go | 7 +++-- .../stream => external/process}/extprocess.go | 3 +- .../process}/pipedprocess.go | 20 ++++++------- {http/hw/hid => hid}/hid.go | 0 {http/hw/hid => hid}/keyboard.go | 0 {http/hw/hid => hid}/mouse.go | 0 {http/hw/hid => hid}/op.go | 0 http/route/api.go | 4 +-- http/route/nanokvm_ui.go | 4 +-- http/{hw => }/rtc/listener.go | 0 http/{hw => }/rtc/webrtc.go | 0 http/ws/ws.go | 2 +- {http/hw/stream => stream}/ustreamer.go | 6 ++-- {http/hw/stream => stream}/video.go | 5 ++-- 16 files changed, 51 insertions(+), 47 deletions(-) rename {http/hw/stream => external/ffmpeg}/ffmpeg.go (95%) rename {http/hw/stream => external/process}/extprocess.go (98%) rename {http/hw/stream => external/process}/pipedprocess.go (94%) rename {http/hw/hid => hid}/hid.go (100%) rename {http/hw/hid => hid}/keyboard.go (100%) rename {http/hw/hid => hid}/mouse.go (100%) rename {http/hw/hid => hid}/op.go (100%) rename http/{hw => }/rtc/listener.go (100%) rename http/{hw => }/rtc/webrtc.go (100%) rename {http/hw/stream => stream}/ustreamer.go (88%) rename {http/hw/stream => stream}/video.go (98%) diff --git a/cmd/kvm/main.go b/cmd/kvm/main.go index 671cd32..a660d1c 100644 --- a/cmd/kvm/main.go +++ b/cmd/kvm/main.go @@ -3,9 +3,10 @@ package main import ( "fmt" "rkkvm/config" - "rkkvm/http/hw/rtc" - "rkkvm/http/hw/stream" + "rkkvm/external/ffmpeg" + "rkkvm/external/process" "rkkvm/http/route" + "rkkvm/http/rtc" "strings" "github.com/gin-gonic/gin" @@ -30,18 +31,7 @@ func main() { log.Println("Failed to parse log level, use default level: info") } - if cfg.Stream.Source == config.StreamSourceMjpeg { - ustreamer := stream.Init(cfg.UStreamer.Path, strings.Split(cfg.UStreamer.Args, " ")) - ustreamer.Start() - //go ustreamer.Watch() - } else if cfg.Stream.Source == config.StreamSourceH264 { - v := stream.InitFFmpeg() - v.Start() - } else { - log.Fatalf("unsupported stream source type: %v", cfg.Stream.Source) - } - - webrtc, err := rtc.InitListener(cfg.WebRtc.Host, cfg.WebRtc.Port, 5006) + webrtc, err := rtc.InitListener(cfg.WebRtc.Host, cfg.WebRtc.VideoPort, 5006) if err != nil { log.Fatal(err) } @@ -49,6 +39,17 @@ func main() { go webrtc.VideoListenerRead() go webrtc.AudioListenerRead() + if cfg.Stream.Source == config.StreamSourceMjpeg { + ustreamer := process.Init(cfg.UStreamer.Path, strings.Split(cfg.UStreamer.Args, " ")) + ustreamer.Start() + //go ustreamer.Watch() + } else if cfg.Stream.Source == config.StreamSourceH264 { + v := ffmpeg.InitFFmpeg() + v.Start() + } else { + log.Fatalf("unsupported stream source type: %v", cfg.Stream.Source) + } + r := gin.Default() r.Use(gin.Recovery()) route.Api(r) diff --git a/config/config.go b/config/config.go index de1ee7d..4f651d0 100644 --- a/config/config.go +++ b/config/config.go @@ -14,7 +14,6 @@ type Config struct { Port int `yaml:"port"` UStreamer UStreamer `yaml:"ustreamer"` Video FFmpeg `yaml:"video"` - Audio []string `yaml:"audio"` WebRtc WebRtc `yaml:"webrtc"` Stream Stream `yaml:"stream"` @@ -23,8 +22,9 @@ type Config struct { } type WebRtc struct { - Host string `yaml:"host"` - Port int `yaml:"port"` + Host string `yaml:"host"` + VideoPort int `yaml:"video_port"` + AudioPort int `yaml:"audio_port"` } type ExtProcess struct { @@ -34,6 +34,7 @@ type ExtProcess struct { type Stream struct { Source string `yaml:"source"` // mjpeg or h264 + } const ( @@ -89,12 +90,12 @@ func Init() { }, 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" + + StreamInputVideoAudio: "/usr/bin/arecord -D hw:0,0 -f dat -r 48000 -c 2 --buffer-size=150 | /app/ffmpeg -re -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" + + StreamInputVideo: "/app/ffmpeg -re -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", }, @@ -102,11 +103,12 @@ func Init() { Bitrate: 6000, Height: 720, GOP: 5, - Codec: "h264", + Codec: StreamSourceH264, }, WebRtc: WebRtc{ - Host: "127.0.0.1", - Port: 5004, + Host: "127.0.0.1", + VideoPort: 5004, + AudioPort: 5006, }, Stream: Stream{ Source: StreamSourceH264, diff --git a/http/hw/stream/ffmpeg.go b/external/ffmpeg/ffmpeg.go similarity index 95% rename from http/hw/stream/ffmpeg.go rename to external/ffmpeg/ffmpeg.go index 954d79c..2b20e37 100644 --- a/http/hw/stream/ffmpeg.go +++ b/external/ffmpeg/ffmpeg.go @@ -1,7 +1,8 @@ -package stream +package ffmpeg import ( "rkkvm/config" + "rkkvm/external/process" ) //h264 @@ -36,7 +37,7 @@ arecord -D hw:0,0 -f dat -r 48000 -c 2 --buffer-size=60 | /app/ffmpeg -re -init_ var ffmpeg *FFmpeg type FFmpeg struct { - *PipedCmd + *process.PipedCmd config.FFmpeg } @@ -85,7 +86,7 @@ func InitFFmpeg() *FFmpeg { cmd := cfg.Commands[config.StreamInputVideoAudio] ffmpeg = &FFmpeg{ - PipedCmd: InitPipedCmd(cfg.FormatCmd(cmd)), + PipedCmd: process.InitPipedCmd(cfg.FormatCmd(cmd)), FFmpeg: cfg, } return ffmpeg diff --git a/http/hw/stream/extprocess.go b/external/process/extprocess.go similarity index 98% rename from http/hw/stream/extprocess.go rename to external/process/extprocess.go index 8d75a04..a307925 100644 --- a/http/hw/stream/extprocess.go +++ b/external/process/extprocess.go @@ -1,4 +1,4 @@ -package stream +package process import ( "io" @@ -17,7 +17,6 @@ type ExtProcess struct { running bool stopChan chan struct{} finished chan struct{} - state State stdin io.WriteCloser } diff --git a/http/hw/stream/pipedprocess.go b/external/process/pipedprocess.go similarity index 94% rename from http/hw/stream/pipedprocess.go rename to external/process/pipedprocess.go index 9ae7b4f..b627309 100644 --- a/http/hw/stream/pipedprocess.go +++ b/external/process/pipedprocess.go @@ -1,4 +1,4 @@ -package stream +package process import ( "os" @@ -10,18 +10,16 @@ import ( log "github.com/sirupsen/logrus" ) -var pipedCmd *PipedCmd -var mu sync.Mutex - // PipedCmd struct manages a sequence of piped commands. type PipedCmd struct { cmds []*exec.Cmd + mu sync.Mutex running bool } // InitPipedCmd initializes a PipedCmd instance with a sequence of commands. func InitPipedCmd(cmd string) *PipedCmd { - pipedCmd = &PipedCmd{} + pipedCmd := &PipedCmd{} pipedCmd.ChangeCmd(cmd) return pipedCmd } @@ -50,8 +48,8 @@ func (p *PipedCmd) ChangeCmd(cmd string) { // Start begins execution of all commands in the piped sequence. func (p *PipedCmd) Start() error { - mu.Lock() - defer mu.Unlock() + p.mu.Lock() + defer p.mu.Unlock() if p.running { log.Debugf("Process is already running.") @@ -106,8 +104,8 @@ func (p *PipedCmd) monitorCommands() { // Wait for all commands to complete or terminate wg.Wait() - mu.Lock() - defer mu.Unlock() + p.mu.Lock() + defer p.mu.Unlock() p.running = false } @@ -125,8 +123,8 @@ func (p *PipedCmd) terminateAll() { // Stop manually stops all commands in the sequence. func (p *PipedCmd) Stop() { - mu.Lock() - defer mu.Unlock() + p.mu.Lock() + defer p.mu.Unlock() if !p.running { log.Debug("Process is not running.") diff --git a/http/hw/hid/hid.go b/hid/hid.go similarity index 100% rename from http/hw/hid/hid.go rename to hid/hid.go diff --git a/http/hw/hid/keyboard.go b/hid/keyboard.go similarity index 100% rename from http/hw/hid/keyboard.go rename to hid/keyboard.go diff --git a/http/hw/hid/mouse.go b/hid/mouse.go similarity index 100% rename from http/hw/hid/mouse.go rename to hid/mouse.go diff --git a/http/hw/hid/op.go b/hid/op.go similarity index 100% rename from http/hw/hid/op.go rename to hid/op.go diff --git a/http/route/api.go b/http/route/api.go index 4bcc11a..867a346 100644 --- a/http/route/api.go +++ b/http/route/api.go @@ -6,11 +6,11 @@ import ( "os/exec" "path/filepath" "rkkvm/config" - "rkkvm/http/hw/hid" - "rkkvm/http/hw/stream" + "rkkvm/hid" "rkkvm/http/middleware" "rkkvm/http/reqrsp" "rkkvm/http/ws" + "rkkvm/stream" "strings" "github.com/gin-gonic/gin" diff --git a/http/route/nanokvm_ui.go b/http/route/nanokvm_ui.go index 2e18269..529b7c6 100644 --- a/http/route/nanokvm_ui.go +++ b/http/route/nanokvm_ui.go @@ -2,7 +2,7 @@ package route import ( "net/http" - "rkkvm/http/hw/stream" + "rkkvm/external/ffmpeg" "rkkvm/http/middleware" "rkkvm/http/reqrsp" "time" @@ -56,7 +56,7 @@ func SetScreen(c *gin.Context) { return } - ffmpeg := stream.GetFFmpeg() + ffmpeg := ffmpeg.GetFFmpeg() switch req.Type { case "fps": ffmpeg.SetFPS(req.Value) diff --git a/http/hw/rtc/listener.go b/http/rtc/listener.go similarity index 100% rename from http/hw/rtc/listener.go rename to http/rtc/listener.go diff --git a/http/hw/rtc/webrtc.go b/http/rtc/webrtc.go similarity index 100% rename from http/hw/rtc/webrtc.go rename to http/rtc/webrtc.go diff --git a/http/ws/ws.go b/http/ws/ws.go index 548624e..68ec8f6 100644 --- a/http/ws/ws.go +++ b/http/ws/ws.go @@ -5,7 +5,7 @@ import ( "net" "net/http" "rkkvm/config" - "rkkvm/http/hw/hid" + "rkkvm/hid" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" diff --git a/http/hw/stream/ustreamer.go b/stream/ustreamer.go similarity index 88% rename from http/hw/stream/ustreamer.go rename to stream/ustreamer.go index 3c2f735..092554e 100644 --- a/http/hw/stream/ustreamer.go +++ b/stream/ustreamer.go @@ -2,6 +2,7 @@ package stream import ( "rkkvm/config" + "rkkvm/external/process" "time" log "github.com/sirupsen/logrus" @@ -10,13 +11,14 @@ import ( var ustreamer *UStreamer type UStreamer struct { - *ExtProcess + *process.ExtProcess config.UStreamer + state State } func InitUStreamer(path string, args []string) *UStreamer { ustreamer = &UStreamer{ - ExtProcess: Init(path, args), + ExtProcess: process.Init(path, args), UStreamer: config.Get().UStreamer, } return ustreamer diff --git a/http/hw/stream/video.go b/stream/video.go similarity index 98% rename from http/hw/stream/video.go rename to stream/video.go index 1494e05..fcf552c 100644 --- a/http/hw/stream/video.go +++ b/stream/video.go @@ -6,8 +6,9 @@ import ( "io" "net/http" "rkkvm/config" - "rkkvm/http/hw/rtc" + "rkkvm/external/ffmpeg" "rkkvm/http/reqrsp" + "rkkvm/http/rtc" "strconv" "github.com/gin-gonic/gin" @@ -172,7 +173,7 @@ func WebRTCSettings(c *gin.Context) { return } - ffmpeg := GetFFmpeg() + ffmpeg := ffmpeg.GetFFmpeg() if len(bitrateStr) > 0 { bitrate, err := strconv.Atoi(bitrateStr)