Added 'next' endpoint and 'singles' for artist

This commit is contained in:
Shiny Nematoda
2022-04-16 22:42:41 +05:30
parent da290e66ad
commit d7a23bf4d5
5 changed files with 165 additions and 28 deletions
+35 -7
View File
@@ -1,16 +1,16 @@
package main
import (
"bytes"
"encoding/json"
"io"
"log"
"bytes"
"net/http"
"encoding/json"
)
func Fetch(data []byte) (string, int, error) {
func Fetch(path string, data []byte) (string, int, error) {
url := "https://music.youtube.com/youtubei/v1/browse?key=AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30"
url := "https://music.youtube.com/youtubei/v1/" + path + "?key=AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30&prettyPrint=false"
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
@@ -19,7 +19,8 @@ func Fetch(data []byte) (string, int, error) {
req.Header.Set("Content-Type", "application/json; charset=utf-8")
req.Header.Set("Origin", "https://music.youtube.com")
req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)")
req.Header.Set("x-origin", "https://music.youtube.com")
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36")
client := &http.Client{}
@@ -47,7 +48,7 @@ func FetchArtist(id string) (string, int) {
return ErrorMessage(err), 500
}
raw, status, err := Fetch(data)
raw, status, err := Fetch("browse", data)
if err != nil {
return ErrorMessage(err), 500
} else if status > 300 {
@@ -59,5 +60,32 @@ func FetchArtist(id string) (string, int) {
return ErrorMessage(err), 500
}
return res, 200
return res, status
}
func FetchNext(id string) (string, int) {
data, err := json.Marshal(GetTypeNext(id))
if err != nil {
return ErrorMessage(err), 500
}
raw, status, err := Fetch("next", data)
if err != nil {
return ErrorMessage(err), 500
} else if status > 300 {
return raw, status
}
res, err := ParseNext(raw)
return res, status
}
/*func main() {
res, status := FetchNext("KWLGyeg74es")
log.Println(status)
log.Println(res)
}*/
+13 -3
View File
@@ -8,16 +8,25 @@ import (
)
func SetHeaders(c *fiber.Ctx) error {
c.Vary("Origin")
c.Type("json", "utf-8")
c.Set("Access-Control-Allow-Origin", "https://hyperpipe.surge.sh")
c.Set("Access-Control-Allow-Origin", "*")
c.Set("Access-Control-Allow-Headers", "*")
c.Set("Access-Control-Max-Age", "1728000")
return c.Next()
}
func HandleHealth(c *fiber.Ctx) error {
defer calc()()
return c.Status(204).SendString("")
return c.SendStatus(204)
}
func HandleNext(c *fiber.Ctx) error {
defer calc()()
res, status := FetchNext(c.Params("id"))
return c.Status(status).SendString(res)
}
func HandleBrowse(c *fiber.Ctx) error {
@@ -47,6 +56,7 @@ func main() {
app.Use(recover.New())
app.Get("/healthz", HandleHealth)
app.Get("/next/:id", HandleNext)
app.Get("/browse/:id", HandleBrowse)
app.Get("/channel/:id", HandleArtist)
+62 -4
View File
@@ -72,11 +72,11 @@ func GetSongs(s gjson.Result) []Item {
defer wg.Done()
j := v.Get("musicResponsiveListItemRenderer")
f := j.Get("flexColumns.#.musicResponsiveListItemFlexColumnRenderer.text.runs.0")
flex := j.Get("flexColumns.#.musicResponsiveListItemFlexColumnRenderer.text.runs.0")
r = append(r, Item{
Id: j.Get("playlistItemData.videoId").String(),
Title: f.Get("#(navigationEndpoint.watchEndpoint.videoId).text").String(),
Title: flex.Get("#(navigationEndpoint.watchEndpoint.videoId).text").String(),
Thumbnails: GetThumbnails(j.Get("thumbnail.musicThumbnailRenderer.thumbnail.thumbnails")),
})
@@ -97,9 +97,9 @@ func GetTwoRowItem(t string, a gjson.Result) []Item {
var id string
if t == "album" {
if t == "album" || t == "singles" {
id = "menu.menuRenderer.items.#(menuNavigationItemRenderer.text.runs.0.text == Shuffle play).menuNavigationItemRenderer.navigationEndpoint.watchPlaylistEndpoint.playlistId"
} else if t == "artist" {
} else {
id = "navigationEndpoint.browseEndpoint.browseId"
}
@@ -133,6 +133,39 @@ func GetTwoRowItem(t string, a gjson.Result) []Item {
return r
}
func GetNextSongs(n gjson.Result) []Item {
r := []Item{}
wg := sync.WaitGroup{}
n.ForEach(
func(_, v gjson.Result) bool {
wg.Add(1)
go func() {
defer wg.Done()
j := v.Get("playlistPanelVideoRenderer")
r = append(r, Item{
Id: j.Get("navigationEndpoint.watchEndpoint.videoId").String(),
Title: RunsText(j.Get("title")),
Sub: j.Get("longBylineText.runs.2.text").String(),
Thumbnails: GetThumbnails(j.Get("thumbnail.thumbnails")),
})
}()
wg.Wait()
return true
},
)
return r
}
func ParseArtist(raw string) (string, error) {
j := gjson.Parse(raw)
@@ -142,6 +175,7 @@ func ParseArtist(raw string) (string, error) {
s := c.Get("#(musicShelfRenderer.title.runs.0.text == Songs).musicShelfRenderer")
a := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer.title.runs.0.text == Albums).musicCarouselShelfRenderer")
m := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer.title.runs.0.text == Singles).musicCarouselShelfRenderer")
u := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer.title.runs.0.text == Fans might also like).musicCarouselShelfRenderer")
val := Artist{
@@ -154,6 +188,7 @@ func ParseArtist(raw string) (string, error) {
Items: Items{
Songs: GetSongs(s.Get("contents")),
Albums: GetTwoRowItem("album", a.Get("contents")),
Singles: GetTwoRowItem("singles", m.Get("contents")),
Artists: GetTwoRowItem("artist", u.Get("contents")),
},
}
@@ -165,3 +200,26 @@ func ParseArtist(raw string) (string, error) {
return string(res), nil
}
func ParseNext(raw string) (string, error) {
j := gjson.Parse(raw)
m := j.Get("playerOverlays.playerOverlayRenderer.browserMediaSession.browserMediaSessionRenderer")
n := j.Get("contents.singleColumnMusicWatchNextResultsRenderer.tabbedRenderer.watchNextTabbedResultsRenderer.tabs.#(tabRenderer.title == Up next).tabRenderer.content.musicQueueRenderer.content.playlistPanelRenderer")
val := Next{
MediaSession: MediaSession{
Album: RunsText(m.Get("album")),
Thumbnails: GetThumbnails(m.Get("thumbnailDetails.thumbnails")),
},
Songs: GetNextSongs(n.Get("contents")),
}
res, err := json.Marshal(val)
if err != nil {
return "", err
}
return string(res), nil
}
+34 -5
View File
@@ -1,5 +1,7 @@
package main
/* Parsers */
type Thumbnail struct {
Height int64 `json:"height"`
Width int64 `json:"width"`
@@ -16,6 +18,7 @@ type Item struct {
type Items struct {
Songs []Item `json:"songs"`
Albums []Item `json:"albums"`
Singles []Item `json:"singles"`
Artists []Item `json:"recommendedArtists"`
}
@@ -29,6 +32,18 @@ type Artist struct {
Items Items `json:"items"`
}
type MediaSession struct {
Thumbnails []Thumbnail `json:"thumbnails"`
Album string `json:"album"`
}
type Next struct {
Songs []Item `json:"songs"`
MediaSession MediaSession `json:"mediaSession"`
}
/* Structs and Types */
type Client struct {
Name string `json:"clientName"`
Version string `json:"clientVersion"`
@@ -42,12 +57,26 @@ type PageType struct {
PageType string `json:"pageType"`
}
type MusicConfig struct {
type BrowseMusicConfig struct {
MusicConfig PageType `json:"browseEndpointContextMusicConfig"`
}
type BrowseData struct {
Context Context `json:"context"`
MusicConfig MusicConfig `json:"browseEndpointContextMusicConfig"`
BrowseId string `json:"browseId"`
type WatchMusicConfig struct {
Panel bool `json:"hasPersistentPlaylistPanel"`
Type string `json:"musicVideoType"`
}
type BrowseData struct {
Context Context `json:"context"`
MusicConfig BrowseMusicConfig `json:"browseEndpointContextMusicConfig"`
BrowseId string `json:"browseId"`
}
type NextData struct {
Id string `json:"videoId"`
Context Context `json:"context"`
Audio bool `json:"isAudioOnly"`
Tuner string `json:"tunerSettingValue"`
Panel bool `json:"enablePersistentPlaylistPanel"`
MusicConfig WatchMusicConfig `json:"watchEndpointMusicConfig"`
}
+21 -9
View File
@@ -2,19 +2,17 @@ package main
import "strings"
func GetContext() Context {
return Context{
Client: Client{
Name: "WEB_REMIX",
Version: "1.20211213.00.00",
},
}
var BaseContext = Context{
Client: Client{
Name: "WEB_REMIX",
Version: "1.20211213.00.00",
},
}
func GetTypeBrowse(t, id string) BrowseData {
return BrowseData{
Context: GetContext(),
MusicConfig: MusicConfig{
Context: BaseContext,
MusicConfig: BrowseMusicConfig{
MusicConfig: PageType{
PageType: "MUSIC_PAGE_TYPE_" + strings.ToUpper(t),
},
@@ -22,3 +20,17 @@ func GetTypeBrowse(t, id string) BrowseData {
BrowseId: id,
}
}
func GetTypeNext(id string) NextData {
return NextData{
Id: id,
Context: BaseContext,
Panel: true,
Audio: true,
Tuner: "AUTOMIX_SETTING_NORMAL",
MusicConfig: WatchMusicConfig{
Panel: true,
Type: "MUSIC_VIDEO_TYPE_ATV",
},
}
}