dudeldu.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * DudelDu
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. /*
  11. DudelDu main entry point for the standalone server.
  12. Features:
  13. - Supports various streaming clients: VLC, ServeStream, ... and most Icecast clients.
  14. - Supports sending of meta data (sending artist and title to the streaming client).
  15. - Playlists are simple json files and data files are normal media (e.g. .mp3) files on disk.
  16. - Supports basic authentication.
  17. */
  18. package main
  19. import (
  20. "flag"
  21. "fmt"
  22. "log"
  23. "os"
  24. "devt.de/krotik/dudeldu"
  25. "devt.de/krotik/dudeldu/playlist"
  26. )
  27. // Global variables
  28. // ================
  29. /*
  30. ConfigFile is the config file which will be used to configure DudelDu
  31. */
  32. var ConfigFile = "dudeldu.config.json"
  33. /*
  34. Known configuration options for DudelDu
  35. */
  36. const (
  37. ThreadPoolSize = "ThreadPoolSize"
  38. FrameQueueSize = "FrameQueueSize"
  39. ServerPort = "ServerPort"
  40. ServerHost = "ServerHost"
  41. )
  42. /*
  43. DefaultConfig is the defaut configuration
  44. */
  45. var DefaultConfig = map[string]interface{}{
  46. ThreadPoolSize: 10,
  47. FrameQueueSize: 10000,
  48. ServerPort: "9091",
  49. ServerHost: "127.0.0.1",
  50. }
  51. type consolelogger func(v ...interface{})
  52. /*
  53. Fatal/print logger methods. Using a custom type so we can test calls with unit
  54. tests.
  55. */
  56. var fatal = consolelogger(log.Fatal)
  57. var print = consolelogger(func(a ...interface{}) {
  58. fmt.Fprint(os.Stderr, a...)
  59. fmt.Fprint(os.Stderr, "\n")
  60. })
  61. /*
  62. DudelDu server instance (used by unit tests)
  63. */
  64. var dds *dudeldu.Server
  65. /*
  66. Main entry point for DudelDu.
  67. */
  68. func main() {
  69. var err error
  70. var plf dudeldu.PlaylistFactory
  71. print(fmt.Sprintf("DudelDu %v", dudeldu.ProductVersion))
  72. auth := flag.String("auth", "", "Authentication as <user>:<pass>")
  73. serverHost := flag.String("host", DefaultConfig[ServerHost].(string), "Server hostname to listen on")
  74. serverPort := flag.String("port", DefaultConfig[ServerPort].(string), "Server port to listen on")
  75. threadPoolSize := flag.Int("tps", DefaultConfig[ThreadPoolSize].(int), "Thread pool size")
  76. frameQueueSize := flag.Int("fqs", DefaultConfig[FrameQueueSize].(int), "Frame queue size")
  77. enableDebug := flag.Bool("debug", false, "Enable extra debugging output")
  78. loopPlaylist := flag.Bool("loop", false, "Loop playlists")
  79. shufflePlaylist := flag.Bool("shuffle", false, "Shuffle playlists")
  80. showHelp := flag.Bool("?", false, "Show this help message")
  81. flag.Usage = func() {
  82. print(fmt.Sprintf("Usage of %s [options] <playlist>", os.Args[0]))
  83. flag.PrintDefaults()
  84. }
  85. flag.Parse()
  86. if len(flag.Args()) != 1 || *showHelp {
  87. flag.Usage()
  88. return
  89. }
  90. dudeldu.DebugOutput = *enableDebug
  91. laddr := fmt.Sprintf("%v:%v", *serverHost, *serverPort)
  92. print(fmt.Sprintf("Serving playlist %v on %v", flag.Arg(0), laddr))
  93. print(fmt.Sprintf("Thread pool size: %v", *threadPoolSize))
  94. print(fmt.Sprintf("Frame queue size: %v", *frameQueueSize))
  95. print(fmt.Sprintf("Loop playlist: %v", *loopPlaylist))
  96. print(fmt.Sprintf("Shuffle playlist: %v", *shufflePlaylist))
  97. if *auth != "" {
  98. print(fmt.Sprintf("Required authentication: %v", *auth))
  99. }
  100. // Create server and listen
  101. plf, err = playlist.NewFilePlaylistFactory(flag.Arg(0))
  102. if err == nil {
  103. rh := dudeldu.NewDefaultRequestHandler(plf, *loopPlaylist, *shufflePlaylist, *auth)
  104. dds = dudeldu.NewServer(rh.HandleRequest)
  105. defer print("Shutting down")
  106. err = dds.Run(laddr, nil)
  107. }
  108. if err != nil {
  109. fatal(err)
  110. }
  111. }