hls.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package handlers
  2. import (
  3. "net/http"
  4. "path"
  5. "path/filepath"
  6. "strconv"
  7. "strings"
  8. "github.com/owncast/owncast/config"
  9. "github.com/owncast/owncast/core"
  10. "github.com/owncast/owncast/core/data"
  11. "github.com/owncast/owncast/models"
  12. "github.com/owncast/owncast/utils"
  13. "github.com/owncast/owncast/webserver/router/middleware"
  14. )
  15. // HandleHLSRequest will manage all requests to HLS content.
  16. func HandleHLSRequest(w http.ResponseWriter, r *http.Request) {
  17. // Sanity check to limit requests to HLS file types.
  18. if filepath.Ext(r.URL.Path) != ".m3u8" && filepath.Ext(r.URL.Path) != ".ts" {
  19. w.WriteHeader(http.StatusNotFound)
  20. return
  21. }
  22. requestedPath := r.URL.Path
  23. relativePath := strings.Replace(requestedPath, "/hls/", "", 1)
  24. fullPath := filepath.Join(config.HLSStoragePath, relativePath)
  25. // If using external storage then only allow requests for the
  26. // master playlist at stream.m3u8, no variants or segments.
  27. if data.GetS3Config().Enabled && relativePath != "stream.m3u8" {
  28. w.WriteHeader(http.StatusNotFound)
  29. return
  30. }
  31. // Handle playlists
  32. if path.Ext(r.URL.Path) == ".m3u8" {
  33. // Playlists should never be cached.
  34. middleware.DisableCache(w)
  35. // Force the correct content type
  36. w.Header().Set("Content-Type", "application/x-mpegURL")
  37. // Use this as an opportunity to mark this viewer as active.
  38. viewer := models.GenerateViewerFromRequest(r)
  39. core.SetViewerActive(&viewer)
  40. } else {
  41. cacheTime := utils.GetCacheDurationSecondsForPath(relativePath)
  42. w.Header().Set("Cache-Control", "public, max-age="+strconv.Itoa(cacheTime))
  43. }
  44. middleware.EnableCors(w)
  45. http.ServeFile(w, r, fullPath)
  46. }