From 9a2271e52207b437a8c3d27cf3270ca4d3321a74 Mon Sep 17 00:00:00 2001 From: Popeye Lau Date: Fri, 17 Feb 2023 23:25:43 +0800 Subject: [PATCH 1/2] =?UTF-8?q?youtube=20600s=20=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Golang/liveurls/youtube.go | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/Golang/liveurls/youtube.go b/Golang/liveurls/youtube.go index 44afd72..9b59321 100644 --- a/Golang/liveurls/youtube.go +++ b/Golang/liveurls/youtube.go @@ -12,12 +12,15 @@ import ( "io" "net/http" "strconv" + "sync" "time" "github.com/dlclark/regexp2" "github.com/etherlabsio/go-m3u8/m3u8" ) +var streamCachedMap sync.Map + type Youtube struct { //https://www.youtube.com/watch?v=cK4LemjoFd0 //Rid: cK4LemjoFd0 @@ -26,6 +29,9 @@ type Youtube struct { } func (y *Youtube) GetLiveUrl() any { + if cached, ok := get(y.Rid); ok { + return cached + } //proxyUrl, err := url.Parse("http://127.0.0.1:8888") client := &http.Client{ Timeout: time.Second * 5, @@ -51,14 +57,14 @@ func (y *Youtube) GetLiveUrl() any { return nil } stream := res.Captures[0].String() - quality := getResolution(stream, y.Quality) + quality := y.getResolution(stream) if quality != nil { return *quality } return stream } -func getResolution(liveurl string, quality string) *string { +func (y *Youtube) getResolution(liveurl 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") @@ -80,8 +86,23 @@ func getResolution(liveurl string, quality string) *string { mapping[strconv.Itoa(item.Resolution.Height)] = item.URI } - if stream, ok := mapping[quality]; ok { + if stream, ok := mapping[y.Quality]; ok { + set(y.Rid, stream, 600) return &stream } - return &playlist.Playlists()[size-1].URI + + stream := &playlist.Playlists()[size-1].URI + set(y.Rid, stream, 600) + return stream +} + +func set(key string, data interface{}, timeout int) { + streamCachedMap.Store(key, data) + time.AfterFunc(time.Second*time.Duration(timeout), func() { + streamCachedMap.Delete(key) + }) +} + +func get(key string) (interface{}, bool) { + return streamCachedMap.Load(key) } From b6051c272783e65bbe420d6c8853669dc1b0f4ac Mon Sep 17 00:00:00 2001 From: Popeye Lau Date: Sun, 19 Feb 2023 07:36:29 +0800 Subject: [PATCH 2/2] bug fixes #19 --- Golang/liveurls/youtube.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Golang/liveurls/youtube.go b/Golang/liveurls/youtube.go index 9b59321..2e1b82b 100644 --- a/Golang/liveurls/youtube.go +++ b/Golang/liveurls/youtube.go @@ -40,9 +40,8 @@ func (y *Youtube) GetLiveUrl() any { }, //Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}, } - r, _ := http.NewRequest("GET", fmt.Sprintf("https://www.youtube.com/watch?v=%v", y.Rid), 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") - r.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") + r, _ := http.NewRequest("GET", fmt.Sprintf("https://m.youtube.com/watch?v=%v", y.Rid), nil) + r.Header.Add("user-agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 16_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Mobile/15E148 Safari/604.1") resp, err := client.Do(r) if err != nil { return err @@ -68,21 +67,24 @@ func (y *Youtube) getResolution(liveurl 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) + resp, err := client.Do(r) + if err != nil { + return nil + } playlist, err := m3u8.Read(resp.Body) defer resp.Body.Close() if err != nil { return nil } - size := playlist.ItemSize() + playlists := playlist.Playlists() - if size < 1 { + if len(playlists) < 1 { return nil } mapping := map[string]string{} - for _, item := range playlist.Playlists() { + for _, item := range playlists { mapping[strconv.Itoa(item.Resolution.Height)] = item.URI } @@ -91,9 +93,9 @@ func (y *Youtube) getResolution(liveurl string) *string { return &stream } - stream := &playlist.Playlists()[size-1].URI + stream := playlists[len(playlists)-1].URI set(y.Rid, stream, 600) - return stream + return &stream } func set(key string, data interface{}, timeout int) {