@@ -605,6 +605,12 @@ func (c *Client) httpPost(ctx context.Context, url string, body interface{}) (*h
605605 req .Header .Set ("Content-Type" , "application/json" )
606606 req .Header .Set ("Accept" , "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" )
607607
608+ if xgoogvisitorid , err := getVisitorId (); err != nil {
609+ return nil , err
610+ } else {
611+ req .Header .Set ("x-goog-visitor-id" , xgoogvisitorid )
612+ }
613+
608614 resp , err := c .httpDo (req )
609615 if err != nil {
610616 return nil , err
@@ -618,6 +624,58 @@ func (c *Client) httpPost(ctx context.Context, url string, body interface{}) (*h
618624 return resp , nil
619625}
620626
627+ var VisitorIdMaxAge = 10 * time .Hour
628+ var VisitorId struct {
629+ Id string
630+ Ctime time.Time
631+ }
632+
633+ func getVisitorId () (string , error ) {
634+ if VisitorId .Id != "" && time .Since (VisitorId .Ctime ) < VisitorIdMaxAge {
635+ return VisitorId .Id , nil
636+ }
637+
638+ const sep = "\n ytcfg.set("
639+
640+ var req http.Request
641+ req .Header = http.Header {}
642+ req .Header .Set ("User-Agent" , "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.4 Safari/605.1.15" )
643+ req .URL = & url.URL {}
644+ req .URL .Host = "www.youtube.com"
645+ req .URL .Scheme = "https"
646+ resp , err := http .DefaultClient .Do (& req )
647+ if err != nil {
648+ return "" , err
649+ }
650+ defer resp .Body .Close ()
651+ data , err := io .ReadAll (resp .Body )
652+ if err != nil {
653+ return "" , err
654+ }
655+ _ , data1 , found := strings .Cut (string (data ), sep )
656+ if ! found {
657+ return "" , err
658+ }
659+ var value struct {
660+ InnertubeContext struct {
661+ Client struct {
662+ VisitorData string
663+ }
664+ } `json:"INNERTUBE_CONTEXT"`
665+ }
666+ if err := json .NewDecoder (strings .NewReader (data1 )).Decode (& value ); err != nil {
667+ return "" , err
668+ }
669+
670+ if VisitorId .Id , err = url .PathUnescape (value .InnertubeContext .Client .VisitorData ); err != nil {
671+ return "" , err
672+ }
673+
674+ VisitorId .Ctime = time .Now ()
675+
676+ return VisitorId .Id , nil
677+ }
678+
621679// httpPostBodyBytes reads the whole HTTP body and returns it
622680func (c * Client ) httpPostBodyBytes (ctx context.Context , url string , body interface {}) ([]byte , error ) {
623681 resp , err := c .httpPost (ctx , url , body )
0 commit comments