core.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package core
  2. import (
  3. "os"
  4. "path"
  5. "path/filepath"
  6. log "github.com/sirupsen/logrus"
  7. "github.com/owncast/owncast/auth"
  8. "github.com/owncast/owncast/config"
  9. "github.com/owncast/owncast/core/chat"
  10. "github.com/owncast/owncast/core/data"
  11. "github.com/owncast/owncast/core/rtmp"
  12. "github.com/owncast/owncast/core/transcoder"
  13. "github.com/owncast/owncast/core/user"
  14. "github.com/owncast/owncast/core/webhooks"
  15. "github.com/owncast/owncast/models"
  16. "github.com/owncast/owncast/notifications"
  17. "github.com/owncast/owncast/utils"
  18. "github.com/owncast/owncast/yp"
  19. )
  20. var (
  21. _stats *models.Stats
  22. _storage models.StorageProvider
  23. _transcoder *transcoder.Transcoder
  24. _yp *yp.YP
  25. _broadcaster *models.Broadcaster
  26. handler transcoder.HLSHandler
  27. fileWriter = transcoder.FileWriterReceiverService{}
  28. )
  29. // Start starts up the core processing.
  30. func Start() error {
  31. resetDirectories()
  32. data.PopulateDefaults()
  33. if err := data.VerifySettings(); err != nil {
  34. log.Error(err)
  35. return err
  36. }
  37. if err := setupStats(); err != nil {
  38. log.Error("failed to setup the stats")
  39. return err
  40. }
  41. // The HLS handler takes the written HLS playlists and segments
  42. // and makes storage decisions. It's rather simple right now
  43. // but will play more useful when recordings come into play.
  44. handler = transcoder.HLSHandler{}
  45. if err := setupStorage(); err != nil {
  46. log.Errorln("storage error", err)
  47. }
  48. user.SetupUsers()
  49. auth.Setup(data.GetDatastore())
  50. fileWriter.SetupFileWriterReceiverService(&handler)
  51. if err := createInitialOfflineState(); err != nil {
  52. log.Error("failed to create the initial offline state")
  53. return err
  54. }
  55. _yp = yp.NewYP(GetStatus)
  56. if err := chat.Start(GetStatus); err != nil {
  57. log.Errorln(err)
  58. }
  59. // start the rtmp server
  60. go rtmp.Start(setStreamAsConnected, setBroadcaster)
  61. rtmpPort := data.GetRTMPPortNumber()
  62. if rtmpPort != 1935 {
  63. log.Infof("RTMP is accepting inbound streams on port %d.", rtmpPort)
  64. }
  65. webhooks.SetupWebhooks(GetStatus)
  66. notifications.Setup(data.GetStore())
  67. return nil
  68. }
  69. func createInitialOfflineState() error {
  70. transitionToOfflineVideoStreamContent()
  71. return nil
  72. }
  73. // transitionToOfflineVideoStreamContent will overwrite the current stream with the
  74. // offline video stream state only. No live stream HLS segments will continue to be
  75. // referenced.
  76. func transitionToOfflineVideoStreamContent() {
  77. log.Traceln("Firing transcoder with offline stream state")
  78. _transcoder := transcoder.NewTranscoder()
  79. _transcoder.SetIdentifier("offline")
  80. _transcoder.SetLatencyLevel(models.GetLatencyLevel(4))
  81. _transcoder.SetIsEvent(true)
  82. offlineFilePath, err := saveOfflineClipToDisk("offline-v2.ts")
  83. if err != nil {
  84. log.Fatalln("unable to save offline clip:", err)
  85. }
  86. _transcoder.SetInput(offlineFilePath)
  87. go _transcoder.Start(false)
  88. // Copy the logo to be the thumbnail
  89. logo := data.GetLogoPath()
  90. dst := filepath.Join(config.TempDir, "thumbnail.jpg")
  91. if err = utils.Copy(filepath.Join("data", logo), dst); err != nil {
  92. log.Warnln(err)
  93. }
  94. // Delete the preview Gif
  95. _ = os.Remove(path.Join(config.DataDirectory, "preview.gif"))
  96. }
  97. func resetDirectories() {
  98. log.Trace("Resetting file directories to a clean slate.")
  99. // Wipe hls data directory
  100. utils.CleanupDirectory(config.HLSStoragePath)
  101. // Remove the previous thumbnail
  102. logo := data.GetLogoPath()
  103. if utils.DoesFileExists(logo) {
  104. err := utils.Copy(path.Join("data", logo), filepath.Join(config.DataDirectory, "thumbnail.jpg"))
  105. if err != nil {
  106. log.Warnln(err)
  107. }
  108. }
  109. }