From 977e973af201da6534b78550c8d47114f34e5c48 Mon Sep 17 00:00:00 2001
From: Nico <d3sox@protonmail.com>
Date: Sat, 26 Jun 2021 05:26:18 +0200
Subject: [PATCH] fix: Add parameters to `get_video_info` endpoint to fix 404
 errors (#938)

* fix: add parameters to `get_video_info` endpoint

fixes 404 errors

* fix: add fallback for lengthSeconds

* fix: correct lengthSeconds path

* style: fix linter errors

* Update info.js

* refactor: use cver for `x-youtube-client-version` header

cherry-picked from https://github.com/distubejs/node-ytdl-core/commit/e13c2a99c3165e077c948ab0eaac5d028cc8ccca

Co-authored-by: TimeForANinja <TimeForANinja@users.noreply.github.com>
---
 lib/info-extras.js | 5 +++--
 lib/info.js        | 7 ++++++-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/lib/info-extras.js b/lib/info-extras.js
index c806c9f2..e735a4a8 100644
--- a/lib/info-extras.js
+++ b/lib/info-extras.js
@@ -282,8 +282,9 @@ exports.cleanVideoDetails = (videoDetails, info) => {
 
   // Use more reliable `lengthSeconds` from `playerMicroformatRenderer`.
   videoDetails.lengthSeconds =
-    info.player_response.microformat &&
-    info.player_response.microformat.playerMicroformatRenderer.lengthSeconds;
+    (info.player_response.microformat &&
+    info.player_response.microformat.playerMicroformatRenderer.lengthSeconds) ||
+    info.player_response.videoDetails.lengthSeconds;
   return videoDetails;
 };
 
diff --git a/lib/info.js b/lib/info.js
index 7ef917ca..7bd3387c 100644
--- a/lib/info.js
+++ b/lib/info.js
@@ -18,6 +18,8 @@ const BASE_URL = 'https://www.youtube.com/watch?v=';
 exports.cache = new Cache();
 exports.cookieCache = new Cache(1000 * 60 * 60 * 24);
 exports.watchPageCache = new Cache();
+// Cache for cver used in getVideoInfoPage
+let cver = '2.20210622.10.00';
 
 
 // Special error class used to determine if an error is unrecoverable,
@@ -273,7 +275,7 @@ const getWatchJSONPage = async(id, options) => {
   let cookie = reqOptions.headers.Cookie || reqOptions.headers.cookie;
   reqOptions.headers = Object.assign({
     'x-youtube-client-name': '1',
-    'x-youtube-client-version': '2.20201203.06.00',
+    'x-youtube-client-version': cver,
     'x-youtube-identity-token': exports.cookieCache.get(cookie || 'browser') || '',
   }, reqOptions.headers);
 
@@ -307,6 +309,7 @@ const getWatchHTMLPage = async(id, options) => {
   let body = await getWatchHTMLPageBody(id, options);
   let info = { page: 'watch' };
   try {
+    cver = utils.between(body, '{"key":"cver","value":"', '"}');
     info.player_response = findJSON('watch.html', 'player_response',
       body, /\bytInitialPlayerResponse\s*=\s*\{/i, '</script>', '{');
   } catch (err) {
@@ -325,6 +328,8 @@ const VIDEO_EURL = 'https://youtube.googleapis.com/v/';
 const getVideoInfoPage = async(id, options) => {
   const url = new URL(`https://${INFO_HOST}${INFO_PATH}`);
   url.searchParams.set('video_id', id);
+  url.searchParams.set('c', 'TVHTML5');
+  url.searchParams.set('cver', `7${cver.substr(1)}`);
   url.searchParams.set('eurl', VIDEO_EURL + id);
   url.searchParams.set('ps', 'default');
   url.searchParams.set('gl', 'US');