package main import ( "bytes" "dndmusicbot/youtube" "io" "log" "net/http" "os" "time" "github.com/grafov/m3u8" "github.com/julienschmidt/httprouter" ) func init() { log.Println("youtube.go loading..") app.youtube = youtube.New() log.Println("youtube.go done.") } func ProxyTube(w http.ResponseWriter, r *http.Request, p httprouter.Params) { os.MkdirAll("cache", 0755) _, data, err := app.cache.GetOrCreateBytes("youtube."+p.ByName("id"), func() (out []byte, err error) { vinfo, err := app.youtube.GetVideoFromID(p.ByName("id")) if err != nil { log.Println(err) http.Error(w, err.Error(), http.StatusInternalServerError) return } uri := vinfo.GetHLSPlaylist("234") resp, err := http.Get(uri) if err != nil { log.Println(err) http.Error(w, err.Error(), http.StatusInternalServerError) return } defer resp.Body.Close() pl, _, err := m3u8.DecodeFrom(resp.Body, true) if err != nil { log.Println(err) http.Error(w, err.Error(), http.StatusInternalServerError) return } var segresp *http.Response mediapl := pl.(*m3u8.MediaPlaylist) buf := new(bytes.Buffer) for _, segment := range mediapl.GetAllSegments() { segresp, err = http.Get(segment.URI) if err != nil { segresp.Body.Close() log.Println(err) http.Error(w, err.Error(), http.StatusInternalServerError) return } _, err = io.Copy(buf, segresp.Body) if err != nil { segresp.Body.Close() log.Println(err) http.Error(w, err.Error(), http.StatusInternalServerError) return } } return buf.Bytes(), nil }) if err != nil { log.Println(err) http.Error(w, err.Error(), http.StatusInternalServerError) return } seeker := bytes.NewReader(data) w.Header().Add("Content-Type", "audio/mp4") http.ServeContent(w, r, "youtube."+p.ByName("id"), time.Now(), seeker) }