99 lines
1.8 KiB
Go
99 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"dndmusicbot/youtube"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
|
|
"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(config.GetString("cache.path"), 0755)
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
_, data, err := app.cache.Get("youtube." + p.ByName("id"))
|
|
if err != nil {
|
|
log.Println(err)
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// cache hit
|
|
if data != nil {
|
|
io.Copy(w, data)
|
|
return
|
|
//w.WriteHeader(200)
|
|
}
|
|
|
|
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)
|
|
writer := io.MultiWriter(w, buf)
|
|
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
for _, segment := range mediapl.GetAllSegments() {
|
|
segresp, err = http.Get(segment.URI)
|
|
if err != nil {
|
|
segresp.Body.Close()
|
|
log.Println(err)
|
|
return
|
|
}
|
|
_, err = io.Copy(writer, segresp.Body)
|
|
if err != nil {
|
|
segresp.Body.Close()
|
|
log.Println(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
go func() {
|
|
_, cw, err := app.cache.WriteCloser("youtube." + p.ByName("id"))
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
cw.Write(buf.Bytes())
|
|
cw.Close()
|
|
}()
|
|
//w.WriteHeader(200)
|
|
}
|