You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
srs/proxy/main.go

122 lines
3.3 KiB
Go

// Copyright (c) 2025 Winlin
//
// SPDX-License-Identifier: MIT
package main
import (
"context"
"os"
"srs-proxy/errors"
"srs-proxy/logger"
)
func main() {
ctx := logger.WithContext(context.Background())
logger.Df(ctx, "%v/%v started", Signature(), Version())
// Install signals.
ctx, cancel := context.WithCancel(ctx)
installSignals(ctx, cancel)
// Start the main loop, ignore the user cancel error.
err := doMain(ctx)
if err != nil && ctx.Err() != context.Canceled {
logger.Ef(ctx, "main: %+v", err)
os.Exit(-1)
}
logger.Df(ctx, "%v done", Signature())
}
func doMain(ctx context.Context) error {
// Setup the environment variables.
if err := loadEnvFile(ctx); err != nil {
return errors.Wrapf(err, "load env")
}
buildDefaultEnvironmentVariables(ctx)
// When cancelled, the program is forced to exit due to a timeout. Normally, this doesn't occur
// because the main thread exits after the context is cancelled. However, sometimes the main thread
// may be blocked for some reason, so a forced exit is necessary to ensure the program terminates.
if err := installForceQuit(ctx); err != nil {
return errors.Wrapf(err, "install force quit")
}
// Start the Go pprof if enabled.
handleGoPprof(ctx)
// Initialize SRS load balancers.
switch lbType := envLoadBalancerType(); lbType {
case "memory":
srsLoadBalancer = NewMemoryLoadBalancer()
case "redis":
srsLoadBalancer = NewRedisLoadBalancer()
default:
return errors.Errorf("invalid load balancer %v", lbType)
}
if err := srsLoadBalancer.Initialize(ctx); err != nil {
return errors.Wrapf(err, "initialize srs load balancer")
}
// Parse the gracefully quit timeout.
gracefulQuitTimeout, err := parseGracefullyQuitTimeout()
if err != nil {
return errors.Wrapf(err, "parse gracefully quit timeout")
}
// Start the RTMP server.
srsRTMPServer := NewSRSRTMPServer()
defer srsRTMPServer.Close()
if err := srsRTMPServer.Run(ctx); err != nil {
return errors.Wrapf(err, "rtmp server")
}
// Start the WebRTC server.
srsWebRTCServer := NewSRSWebRTCServer()
defer srsWebRTCServer.Close()
if err := srsWebRTCServer.Run(ctx); err != nil {
return errors.Wrapf(err, "rtc server")
}
// Start the HTTP API server.
srsHTTPAPIServer := NewSRSHTTPAPIServer(func(server *srsHTTPAPIServer) {
server.gracefulQuitTimeout, server.rtc = gracefulQuitTimeout, srsWebRTCServer
})
defer srsHTTPAPIServer.Close()
if err := srsHTTPAPIServer.Run(ctx); err != nil {
return errors.Wrapf(err, "http api server")
}
// Start the SRT server.
srsSRTServer := NewSRSSRTServer()
defer srsSRTServer.Close()
if err := srsSRTServer.Run(ctx); err != nil {
return errors.Wrapf(err, "srt server")
}
// Start the System API server.
systemAPI := NewSystemAPI(func(server *systemAPI) {
server.gracefulQuitTimeout = gracefulQuitTimeout
})
defer systemAPI.Close()
if err := systemAPI.Run(ctx); err != nil {
return errors.Wrapf(err, "system api server")
}
// Start the HTTP web server.
srsHTTPStreamServer := NewSRSHTTPStreamServer(func(server *srsHTTPStreamServer) {
server.gracefulQuitTimeout = gracefulQuitTimeout
})
defer srsHTTPStreamServer.Close()
if err := srsHTTPStreamServer.Run(ctx); err != nil {
return errors.Wrapf(err, "http server")
}
// Wait for the main loop to quit.
<-ctx.Done()
return nil
}