mirror of
https://github.com/m1k1o/neko.git
synced 2025-07-19 09:37:50 +02:00
Add ability to restart broadcast
This commit is contained in:
parent
a5830dc440
commit
acc3c286a1
10 changed files with 60 additions and 27 deletions
|
@ -1,4 +1,4 @@
|
|||
ARG BASE_IMAGE=m1k1o/neko:base
|
||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/nvidia-base:latest
|
||||
FROM $BASE_IMAGE
|
||||
|
||||
ARG SRC_URL="https://download.mozilla.org/?product=firefox-latest&os=linux64&lang=en-US"
|
||||
|
|
|
@ -33,13 +33,6 @@ RUN go mod download
|
|||
COPY server/ .
|
||||
RUN ./build
|
||||
|
||||
FROM ghcr.io/m1k1o/neko/intel-firefox:latest
|
||||
|
||||
RUN set -eux; apt-get update; \
|
||||
apt-get install -y --no-install-recommends intel-media-va-driver-non-free i965-va-driver-shaders; \
|
||||
#
|
||||
# clean up
|
||||
apt-get clean -y; \
|
||||
rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
||||
FROM cave-firefox:latest
|
||||
|
||||
COPY --from=server /src/bin/neko /usr/bin/neko
|
||||
|
|
|
@ -10,10 +10,16 @@ services:
|
|||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
volumes:
|
||||
- ./bin/firefox:/home/neko/.mozilla/firefox
|
||||
- ./bin/home/neko:/home/neko
|
||||
devices:
|
||||
- /dev/dri/renderD128:/dev/dri/renderD128
|
||||
- /dev/dri/card0:/dev/dri/card0
|
||||
- /dev/dri:/dev/dri
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: 1
|
||||
capabilities: [gpu]
|
||||
privileged: true
|
||||
environment:
|
||||
NEKO_SCREEN: 1920x1080@60
|
||||
|
@ -23,4 +29,5 @@ services:
|
|||
NEKO_ICELITE: 1
|
||||
NEKO_BROADCAST_URL: rtmp://ome.thuan.au:1935/app/stream-neko
|
||||
NEKO_NAT1TO1: 192.168.0.34
|
||||
NEKO_HWENC:
|
||||
NEKO_HWENC: NVENC
|
||||
NEKO_VIDEO_CODEC: h264
|
||||
|
|
|
@ -17,6 +17,7 @@ type BroacastManagerCtx struct {
|
|||
pipeline *gst.Pipeline
|
||||
pipelineMu sync.Mutex
|
||||
pipelineFn func(url string) (string, error)
|
||||
pipelineRestart chan bool
|
||||
|
||||
url string
|
||||
started bool
|
||||
|
@ -31,6 +32,7 @@ func broadcastNew(pipelineFn func(url string) (string, error), defaultUrl string
|
|||
return &BroacastManagerCtx{
|
||||
logger: logger,
|
||||
pipelineFn: pipelineFn,
|
||||
pipelineRestart: make(chan bool),
|
||||
url: defaultUrl,
|
||||
started: defaultUrl != "",
|
||||
}
|
||||
|
@ -71,6 +73,10 @@ func (manager *BroacastManagerCtx) Started() bool {
|
|||
return manager.started
|
||||
}
|
||||
|
||||
func (manager *BroacastManagerCtx) GetRestart() chan bool {
|
||||
return manager.pipelineRestart
|
||||
}
|
||||
|
||||
func (manager *BroacastManagerCtx) Url() string {
|
||||
manager.mu.Lock()
|
||||
defer manager.mu.Unlock()
|
||||
|
|
|
@ -53,6 +53,25 @@ func (manager *CaptureManagerCtx) Start() {
|
|||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
_, ok := <-manager.broadcast.GetRestart()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if !manager.broadcast.Started() {
|
||||
return
|
||||
}
|
||||
|
||||
manager.broadcast.destroyPipeline()
|
||||
err := manager.broadcast.createPipeline()
|
||||
if err != nil && !errors.Is(err, types.ErrCapturePipelineAlreadyExists) {
|
||||
manager.logger.Panic().Err(err).Msg("unable to recreate broadcast pipeline")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
before, ok := <-manager.desktop.GetScreenSizeChangeChannel()
|
||||
|
|
|
@ -30,7 +30,7 @@ import (
|
|||
*/
|
||||
|
||||
const (
|
||||
videoSrc = "ximagesrc display-name=%s show-pointer=true use-damage=false ! video/x-raw,framerate=%d/1 ! vaapipostproc ! queue ! "
|
||||
videoSrc = "ximagesrc display-name=%s show-pointer=true use-damage=false ! video/x-raw,framerate=%d/1 ! videoconvert ! queue ! "
|
||||
audioSrc = "pulsesrc device=%s ! audio/x-raw,channels=2 ! audioconvert ! "
|
||||
)
|
||||
|
||||
|
@ -47,7 +47,8 @@ func NewBroadcastPipeline(device string, display string, pipelineSrc string, url
|
|||
// replace display
|
||||
pipelineStr = strings.Replace(pipelineStr, "{display}", display, -1)
|
||||
} else {
|
||||
pipelineStr = fmt.Sprintf("flvmux name=mux ! rtmpsink location='%s live=1' %s audio/x-raw,channels=2 ! audioconvert ! voaacenc ! mux. %s video/x-raw,format=NV12 ! vaapih264enc rate-control=cbr bitrate=%d keyframe-period=180 quality-level=7 ! h264parse ! mux.", url, audio, video, 8000)
|
||||
birate := 8000
|
||||
pipelineStr = fmt.Sprintf("flvmux name=mux ! rtmpsink location='%s live=1 subscribe=stream-neko buffer=1200000' %s audio/x-raw,channels=2 ! audioconvert ! voaacenc ! mux. %s video/x-raw,format=NV12 ! nvh264enc name=encoder rc-lookahead=20 preset=2 gop-size=120 temporal-aq=true bitrate=%d vbv-buffer-size=%d rc-mode=cbr bframes=0 ! h264parse config-interval=-1 ! mux.", url, audio, video, birate, birate)
|
||||
}
|
||||
|
||||
return pipelineStr, nil
|
||||
|
|
|
@ -14,6 +14,7 @@ type BroadcastManager interface {
|
|||
Start(url string) error
|
||||
Stop()
|
||||
Started() bool
|
||||
GetRestart() chan bool
|
||||
Url() string
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ const (
|
|||
OP_KEY_DOWN = 0x03
|
||||
OP_KEY_UP = 0x04
|
||||
OP_KEY_CLK = 0x05
|
||||
OP_RESTART_BROADCAST = 0x06
|
||||
)
|
||||
|
||||
type PayloadHeader struct {
|
||||
|
|
|
@ -121,6 +121,9 @@ func (ws *WebSocketHandler) connectUpstream() {
|
|||
|
||||
ws.logger.Debug().Msgf("key up %d", payload.Key)
|
||||
}
|
||||
case webrtc.OP_RESTART_BROADCAST:
|
||||
ws.logger.Info().Msg("Restarting broadcast")
|
||||
ws.capture.Broadcast().GetRestart() <- true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ func New(sessions types.SessionManager, desktop types.DesktopManager, capture ty
|
|||
conf: conf,
|
||||
sessions: sessions,
|
||||
desktop: desktop,
|
||||
capture: capture,
|
||||
webrtc: webrtc,
|
||||
state: state,
|
||||
upgrader: websocket.Upgrader{
|
||||
|
@ -88,6 +89,7 @@ type WebSocketHandler struct {
|
|||
upgrader websocket.Upgrader
|
||||
sessions types.SessionManager
|
||||
desktop types.DesktopManager
|
||||
capture types.CaptureManager
|
||||
webrtc types.WebRTCManager
|
||||
state *state.State
|
||||
conf *config.WebSocket
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue