1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| func TestVideo(t *testing.T) { http.HandleFunc("/api/video", func(w http.ResponseWriter, r *http.Request) { videoFile, err := os.Open("videos/video3.ts") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer videoFile.Close()
fileInfo, err := videoFile.Stat() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return }
w.Header().Set("Content-Type", "video/mp4")
w.Header().Set("Content-Length", strconv.FormatInt(fileInfo.Size(), 10))
rangeHeader := r.Header.Get("Range") if rangeHeader != "" { start, _, err := parseRange(rangeHeader, fileInfo.Size()) if err != nil { http.Error(w, "Invalid range request", http.StatusRequestedRangeNotSatisfiable) return }
videoFile.Seek(start, 0)
http.ServeContent(w, r, "", fileInfo.ModTime(), videoFile) } else { http.ServeContent(w, r, "", fileInfo.ModTime(), videoFile) } }) http.ListenAndServe(":9999", nil) }
func parseRange(rangeHeader string, fileSize int64) (int64, int64, error) { rangeParts := strings.SplitN(rangeHeader, "=", 2) byteRange := strings.SplitN(rangeParts[1], "-", 2)
start, err := strconv.ParseInt(byteRange[0], 10, 64) if err != nil { return 0, 0, err }
var end int64 if byteRange[1] != "" { end, err = strconv.ParseInt(byteRange[1], 10, 64) if err != nil { return 0, 0, err } } else { end = fileSize - 1 }
return start, end, nil }
|