83 lines
1.8 KiB
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)
|
|
}
|