diff --git a/client.go b/client.go index 93d3d1da..5ab9605d 100644 --- a/client.go +++ b/client.go @@ -298,7 +298,7 @@ func (c *Client) GetStreamURL(video *Video, format *Format) (string, error) { // GetStreamURLContext returns the url for a specific format with a context func (c *Client) GetStreamURLContext(ctx context.Context, video *Video, format *Format) (string, error) { if format.URL != "" { - return format.URL, nil + return c.unThrottle(ctx, video.ID, format.URL) } cipher := format.Cipher diff --git a/decipher.go b/decipher.go index 67104d4a..47893913 100644 --- a/decipher.go +++ b/decipher.go @@ -37,19 +37,53 @@ func (c *Client) decipherURL(ctx context.Context, videoID string, cipher string) } query.Add(params.Get("sp"), string(bs)) + query, err = c.decryptNParam(ctx, config, query) + if err != nil { + return "", err + } + + uri.RawQuery = query.Encode() + + return uri.String(), nil +} + +// see https://github.com/kkdai/youtube/pull/244 +func (c *Client) unThrottle(ctx context.Context, videoID string, urlString string) (string, error) { + config, err := c.getPlayerConfig(ctx, videoID) + if err != nil { + return "", err + } + + uri, err := url.Parse(urlString) + if err != nil { + return "", err + } + + query, err := c.decryptNParam(ctx, config, uri.Query()) + if err != nil { + return "", err + } + + uri.RawQuery = query.Encode() + return uri.String(), nil +} + +func (c *Client) decryptNParam(ctx context.Context, config playerConfig, query url.Values) (url.Values, error) { // decrypt n-parameter nSig := query.Get("n") if nSig != "" { nDecoded, err := config.decodeNsig(nSig) if err != nil { - return "", fmt.Errorf("unable to decode nSig: %w", err) + return nil, fmt.Errorf("unable to decode nSig: %w", err) } query.Set("n", nDecoded) } - uri.RawQuery = query.Encode() + if c.Debug { + log.Printf("[nParam] n: %s; nDecoded: %s\nQuery: %v\n", nSig, query.Get("n"), query) + } - return uri.String(), nil + return query, nil } const (