113 lines
3.0 KiB
Go
113 lines
3.0 KiB
Go
package webrtc
|
|
|
|
import (
|
|
"math/rand"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
"github.com/pion/webrtc/v2"
|
|
"github.com/rs/zerolog"
|
|
"github.com/rs/zerolog/log"
|
|
|
|
"n.eko.moe/neko/internal/gst"
|
|
)
|
|
|
|
func NewManager(password string) (*WebRTCManager, error) {
|
|
engine := webrtc.MediaEngine{}
|
|
|
|
videoCodec := webrtc.NewRTPVP8Codec(webrtc.DefaultPayloadTypeVP8, 90000)
|
|
video, err := webrtc.NewTrack(webrtc.DefaultPayloadTypeVP8, rand.Uint32(), "stream", "stream", videoCodec)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
engine.RegisterCodec(videoCodec)
|
|
|
|
audioCodec := webrtc.NewRTPOpusCodec(webrtc.DefaultPayloadTypeOpus, 48000)
|
|
audio, err := webrtc.NewTrack(webrtc.DefaultPayloadTypeOpus, rand.Uint32(), "stream", "stream", audioCodec)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
engine.RegisterCodec(audioCodec)
|
|
|
|
videoPipeline := gst.CreatePipeline(webrtc.VP8, []*webrtc.Track{video}, "ximagesrc show-pointer=true use-damage=false ! video/x-raw,framerate=30/1 ! videoconvert")
|
|
// ximagesrc xid=0 show-pointer=true ! videoconvert ! queue | videotestsrc
|
|
|
|
audioPipeline := gst.CreatePipeline(webrtc.Opus, []*webrtc.Track{audio}, "pulsesrc device=auto_null.monitor ! audioconvert")
|
|
// pulsesrc device=auto_null.monitor ! audioconvert | audiotestsrc
|
|
// gst-launch-1.0 -v pulsesrc device=auto_null.monitor ! audioconvert ! vorbisenc ! oggmux ! filesink location=alsasrc.ogg
|
|
|
|
return &WebRTCManager{
|
|
logger: log.With().Str("service", "webrtc").Logger(),
|
|
engine: engine,
|
|
api: webrtc.NewAPI(webrtc.WithMediaEngine(engine)),
|
|
video: video,
|
|
videoPipeline: videoPipeline,
|
|
audio: audio,
|
|
audioPipeline: audioPipeline,
|
|
controller: "",
|
|
password: password,
|
|
sessions: make(map[string]*session),
|
|
debounce: make(map[int]time.Time),
|
|
cleanup: time.NewTicker(500 * time.Second),
|
|
shutdown: make(chan bool),
|
|
upgrader: websocket.Upgrader{
|
|
CheckOrigin: func(r *http.Request) bool {
|
|
return true
|
|
},
|
|
},
|
|
config: webrtc.Configuration{
|
|
ICEServers: []webrtc.ICEServer{
|
|
{
|
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
|
},
|
|
},
|
|
SDPSemantics: webrtc.SDPSemanticsUnifiedPlanWithFallback,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
type WebRTCManager struct {
|
|
logger zerolog.Logger
|
|
upgrader websocket.Upgrader
|
|
engine webrtc.MediaEngine
|
|
api *webrtc.API
|
|
config webrtc.Configuration
|
|
password string
|
|
controller string
|
|
sessions map[string]*session
|
|
debounce map[int]time.Time
|
|
shutdown chan bool
|
|
cleanup *time.Ticker
|
|
video *webrtc.Track
|
|
audio *webrtc.Track
|
|
videoPipeline *gst.Pipeline
|
|
audioPipeline *gst.Pipeline
|
|
}
|
|
|
|
func (manager *WebRTCManager) Start() error {
|
|
manager.videoPipeline.Start()
|
|
manager.audioPipeline.Start()
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-manager.shutdown:
|
|
return
|
|
case <-manager.cleanup.C:
|
|
manager.checkKeys()
|
|
}
|
|
}
|
|
}()
|
|
|
|
return nil
|
|
}
|
|
|
|
func (manager *WebRTCManager) Shutdown() error {
|
|
manager.cleanup.Stop()
|
|
manager.shutdown <- true
|
|
manager.videoPipeline.Stop()
|
|
manager.audioPipeline.Stop()
|
|
return nil
|
|
}
|