package ytdl import "strings" type playerConfig struct { Assets struct { JS string `json:"js"` } `json:"assets"` Args struct { Status string `json:"status"` Errorcode string `json:"errorcode"` Reason string `json:"reason"` PlayerResponse string `json:"player_response"` URLEncodedFmtStreamMap string `json:"url_encoded_fmt_stream_map"` AdaptiveFmts string `json:"adaptive_fmts"` Dashmpd string `json:"dashmpd"` } `json:"args"` } type formatInfo struct { Itag int `json:"itag"` MimeType string `json:"mimeType"` Bitrate int `json:"bitrate"` Width int `json:"width"` Height int `json:"height"` LastModified string `json:"lastModified"` ContentLength string `json:"contentLength"` Quality string `json:"quality"` QualityLabel string `json:"qualityLabel"` ProjectionType string `json:"projectionType"` AverageBitrate int `json:"averageBitrate"` AudioQuality string `json:"audioQuality"` ApproxDurationMs string `json:"approxDurationMs"` AudioSampleRate string `json:"audioSampleRate"` AudioChannels int `json:"audioChannels"` Cipher *string `json:"cipher"` URL string `json:"url"` } type playerResponse struct { PlayabilityStatus struct { Status string `json:"status"` Reason string `json:"reason"` } `json:"playabilityStatus"` StreamingData struct { ExpiresInSeconds string `json:"expiresInSeconds"` Formats []formatInfo `json:"formats"` AdaptiveFormats []formatInfo `json:"adaptiveFormats"` } `json:"streamingData"` VideoDetails struct { Title string `json:"title"` Author string `json:"author"` LengthSeconds string `json:"lengthSeconds"` Keywords []string `json:"keywords"` ViewCount string `json:"viewCount"` } `json:"videoDetails"` Microformat struct { Renderer struct { ViewCount string `json:"viewCount"` PublishDate string `json:"publishDate"` UploadDate string `json:"uploadDate"` } `json:"playerMicroformatRenderer"` } `json:"microformat"` } type representation struct { Itag int `xml:"id,attr"` Height int `xml:"height,attr"` URL string `xml:"BaseURL"` } type initialData struct { Contents struct { TwoColumnWatchNextResults struct { Results struct { Results struct { Contents []struct { VideoSecondaryInfoRenderer struct { Owner struct { VideoOwnerRenderer struct { Thumbnail struct { Thumbnails []struct { URL string `json:"url"` Width int `json:"width"` Height int `json:"height"` } `json:"thumbnails"` } `json:"thumbnail"` Title Content `json:"title"` SubscriberCountText Content `json:"subscriberCountText"` TrackingParams string `json:"trackingParams"` } `json:"videoOwnerRenderer"` } `json:"owner"` Description Content `json:"description"` MetadataRowContainer struct { MetadataRowContainerRenderer struct { Rows MetadataRows `json:"rows"` } `json:"metadataRowContainerRenderer"` } `json:"metadataRowContainer"` } `json:"videoSecondaryInfoRenderer,omitempty"` } `json:"contents"` } `json:"results"` } `json:"results"` } `json:"twoColumnWatchNextResults"` } `json:"contents"` } type Content struct { SimpleText *string `json:"simpleText,omitempty"` Lines []struct { Text string `json:"text,omitempty"` } `json:"runs"` } func (c *Content) String() string { if c.SimpleText != nil { return *c.SimpleText } var sb strings.Builder for i := range c.Lines { sb.WriteString(c.Lines[i].Text) } return sb.String() } type MetadataRows []struct { MetadataRowRenderer struct { Title Content `json:"title"` Contents []Content `json:"contents"` } `json:"metadataRowRenderer,omitempty"` } func (rows MetadataRows) Get(title string) string { for i := range rows { row := &rows[i] if row.MetadataRowRenderer.Title.String() == title { if contents := row.MetadataRowRenderer.Contents; len(contents) > 0 { return contents[0].String() } } } return "" }