dndmusicbot/youtube.go

83 lines
1.8 KiB
Go

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)
}