diff --git a/Golang/go.mod b/Golang/go.mod index a09ec03..7c4db90 100644 --- a/Golang/go.mod +++ b/Golang/go.mod @@ -3,6 +3,7 @@ module Golang go 1.19 require ( + github.com/dlclark/regexp2 v1.7.0 github.com/dop251/goja v0.0.0-20230203172422-5460598cfa32 github.com/forgoer/openssl v1.5.0 github.com/gin-gonic/gin v1.8.2 @@ -10,7 +11,7 @@ require ( ) require ( - github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/etherlabsio/go-m3u8 v1.0.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect diff --git a/Golang/go.sum b/Golang/go.sum index 348e54d..979bcfc 100644 --- a/Golang/go.sum +++ b/Golang/go.sum @@ -1,3 +1,4 @@ +github.com/AlekSi/pointer v1.0.0/go.mod h1:1kjywbfcPFCmncIxtk6fIEub6LKrfMz3gc5QKVOSOA8= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -10,6 +11,8 @@ github.com/dop251/goja v0.0.0-20230203172422-5460598cfa32 h1:audXtK7nV3y4W9ckAxR github.com/dop251/goja v0.0.0-20230203172422-5460598cfa32/go.mod h1:yRkwfj0CBpOGre+TwBsqPV0IH0Pk73e4PXJOeNDboGs= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= +github.com/etherlabsio/go-m3u8 v1.0.0 h1:d3HJVr8wlbvJO20ksKEyvDYf4bcM7v8YV3W83fHswL0= +github.com/etherlabsio/go-m3u8 v1.0.0/go.mod h1:RzDiaXgaYnIEzZUmVUD/xMRFR7bY7U5JaCnp8XYLmXU= github.com/forgoer/openssl v1.5.0 h1:zu1AvfECl6VatFfkfryvI/C8Cru+xLEvZ6Q80DmAPRc= github.com/forgoer/openssl v1.5.0/go.mod h1:NMVFOzYeLVR7UiGTxsa+A21nrERTZ3Rv2JHDPcJpDyI= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= diff --git a/Golang/liveurls/youtube.go b/Golang/liveurls/youtube.go index a31bbfa..44afd72 100644 --- a/Golang/liveurls/youtube.go +++ b/Golang/liveurls/youtube.go @@ -9,20 +9,26 @@ package liveurls import ( "fmt" - "github.com/dlclark/regexp2" "io" "net/http" + "strconv" + "time" + + "github.com/dlclark/regexp2" + "github.com/etherlabsio/go-m3u8/m3u8" ) type Youtube struct { //https://www.youtube.com/watch?v=cK4LemjoFd0 //Rid: cK4LemjoFd0 - Rid string + Rid string + Quality string } func (y *Youtube) GetLiveUrl() any { //proxyUrl, err := url.Parse("http://127.0.0.1:8888") client := &http.Client{ + Timeout: time.Second * 5, CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, @@ -44,5 +50,38 @@ func (y *Youtube) GetLiveUrl() any { if res == nil { return nil } - return res.Captures[0].String() + stream := res.Captures[0].String() + quality := getResolution(stream, y.Quality) + if quality != nil { + return *quality + } + return stream +} + +func getResolution(liveurl string, quality string) *string { + client := &http.Client{Timeout: time.Second * 5} + r, _ := http.NewRequest("GET", liveurl, nil) + r.Header.Add("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36") + resp, _ := client.Do(r) + playlist, err := m3u8.Read(resp.Body) + defer resp.Body.Close() + if err != nil { + return nil + } + + size := playlist.ItemSize() + + if size < 1 { + return nil + } + + mapping := map[string]string{} + for _, item := range playlist.Playlists() { + mapping[strconv.Itoa(item.Resolution.Height)] = item.URI + } + + if stream, ok := mapping[quality]; ok { + return &stream + } + return &playlist.Playlists()[size-1].URI } diff --git a/Golang/main.go b/Golang/main.go index 88507e1..9dc7a61 100644 --- a/Golang/main.go +++ b/Golang/main.go @@ -66,6 +66,7 @@ func setupRouter(adurl string) *gin.Engine { case "youtube": ytbObj := &liveurls.Youtube{} ytbObj.Rid = rid + ytbObj.Quality = c.DefaultQuery("quality", "1080") c.Redirect(http.StatusMovedPermanently, duanyan(adurl, ytbObj.GetLiveUrl())) } })