package playback import ( "net/http" "os" "path/filepath" "strings" ) // MimeFromExtension returns a MIME type based on the file extension. // Falls back to "application/octet-stream" for unknown extensions. func MimeFromExtension(name string) string { ext := strings.ToLower(filepath.Ext(name)) switch ext { case ".mp4", ".m4v": return "video/mp4" case ".mkv": return "video/x-matroska" case ".webm": return "video/webm" case ".avi": return "video/x-msvideo" case ".mov": return "video/quicktime" case ".ts": return "video/mp2t" case ".flv": return "video/x-flv" case ".wmv": return "video/x-ms-wmv" default: return "application/octet-stream" } } // ServeDirectPlay serves a media file with HTTP byte-range support. // Uses http.ServeContent for proper range handling, which supports // Range requests, conditional requests (If-Modified-Since, If-None-Match), // and Content-Type detection. func ServeDirectPlay(w http.ResponseWriter, r *http.Request, filePath string) error { f, err := os.Open(filePath) if err != nil { if os.IsNotExist(err) { http.Error(w, "file not found", http.StatusNotFound) return err } http.Error(w, "internal server error", http.StatusInternalServerError) return err } defer f.Close() stat, err := f.Stat() if err != nil { http.Error(w, "internal server error", http.StatusInternalServerError) return err } // Set Content-Type explicitly so ServeContent does not sniff. w.Header().Set("Content-Type", MimeFromExtension(filePath)) http.ServeContent(w, r, stat.Name(), stat.ModTime(), f) return nil }