main.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright (c) 2024 Winlin
  2. //
  3. // SPDX-License-Identifier: MIT
  4. package main
  5. import (
  6. "context"
  7. "os"
  8. "srs-proxy/errors"
  9. "srs-proxy/logger"
  10. )
  11. func main() {
  12. ctx := logger.WithContext(context.Background())
  13. logger.Df(ctx, "%v/%v started", Signature(), Version())
  14. // Install signals.
  15. ctx, cancel := context.WithCancel(ctx)
  16. installSignals(ctx, cancel)
  17. // Start the main loop, ignore the user cancel error.
  18. err := doMain(ctx)
  19. if err != nil && ctx.Err() != context.Canceled {
  20. logger.Ef(ctx, "main: %+v", err)
  21. os.Exit(-1)
  22. }
  23. logger.Df(ctx, "%v done", Signature())
  24. }
  25. func doMain(ctx context.Context) error {
  26. // Setup the environment variables.
  27. if err := loadEnvFile(ctx); err != nil {
  28. return errors.Wrapf(err, "load env")
  29. }
  30. buildDefaultEnvironmentVariables(ctx)
  31. // When cancelled, the program is forced to exit due to a timeout. Normally, this doesn't occur
  32. // because the main thread exits after the context is cancelled. However, sometimes the main thread
  33. // may be blocked for some reason, so a forced exit is necessary to ensure the program terminates.
  34. if err := installForceQuit(ctx); err != nil {
  35. return errors.Wrapf(err, "install force quit")
  36. }
  37. // Start the Go pprof if enabled.
  38. handleGoPprof(ctx)
  39. // Initialize SRS load balancers.
  40. switch lbType := envLoadBalancerType(); lbType {
  41. case "memory":
  42. srsLoadBalancer = NewMemoryLoadBalancer()
  43. case "redis":
  44. srsLoadBalancer = NewRedisLoadBalancer()
  45. default:
  46. return errors.Errorf("invalid load balancer %v", lbType)
  47. }
  48. if err := srsLoadBalancer.Initialize(ctx); err != nil {
  49. return errors.Wrapf(err, "initialize srs load balancer")
  50. }
  51. // Parse the gracefully quit timeout.
  52. gracefulQuitTimeout, err := parseGracefullyQuitTimeout()
  53. if err != nil {
  54. return errors.Wrapf(err, "parse gracefully quit timeout")
  55. }
  56. // Start the RTMP server.
  57. srsRTMPServer := NewSRSRTMPServer()
  58. defer srsRTMPServer.Close()
  59. if err := srsRTMPServer.Run(ctx); err != nil {
  60. return errors.Wrapf(err, "rtmp server")
  61. }
  62. // Start the WebRTC server.
  63. srsWebRTCServer := NewSRSWebRTCServer()
  64. defer srsWebRTCServer.Close()
  65. if err := srsWebRTCServer.Run(ctx); err != nil {
  66. return errors.Wrapf(err, "rtc server")
  67. }
  68. // Start the HTTP API server.
  69. srsHTTPAPIServer := NewSRSHTTPAPIServer(func(server *srsHTTPAPIServer) {
  70. server.gracefulQuitTimeout, server.rtc = gracefulQuitTimeout, srsWebRTCServer
  71. })
  72. defer srsHTTPAPIServer.Close()
  73. if err := srsHTTPAPIServer.Run(ctx); err != nil {
  74. return errors.Wrapf(err, "http api server")
  75. }
  76. // Start the SRT server.
  77. srsSRTServer := NewSRSSRTServer()
  78. defer srsSRTServer.Close()
  79. if err := srsSRTServer.Run(ctx); err != nil {
  80. return errors.Wrapf(err, "srt server")
  81. }
  82. // Start the System API server.
  83. systemAPI := NewSystemAPI(func(server *systemAPI) {
  84. server.gracefulQuitTimeout = gracefulQuitTimeout
  85. })
  86. defer systemAPI.Close()
  87. if err := systemAPI.Run(ctx); err != nil {
  88. return errors.Wrapf(err, "system api server")
  89. }
  90. // Start the HTTP web server.
  91. srsHTTPStreamServer := NewSRSHTTPStreamServer(func(server *srsHTTPStreamServer) {
  92. server.gracefulQuitTimeout = gracefulQuitTimeout
  93. })
  94. defer srsHTTPStreamServer.Close()
  95. if err := srsHTTPStreamServer.Run(ctx); err != nil {
  96. return errors.Wrapf(err, "http server")
  97. }
  98. // Wait for the main loop to quit.
  99. <-ctx.Done()
  100. return nil
  101. }