Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MinigetError: input stream: Status code: 404 #939

Closed
N1C0exe opened this issue Jun 22, 2021 · 65 comments · Fixed by #938
Closed

MinigetError: input stream: Status code: 404 #939

N1C0exe opened this issue Jun 22, 2021 · 65 comments · Fixed by #938

Comments

@N1C0exe
Copy link

N1C0exe commented Jun 22, 2021

MinigetError: input stream: Status code: 404
at ClientRequest.
at Object.onceWrapper (events.js:422:26)
at ClientRequest.emit (events.js:315:20)
at HTTPParser.parserOnIncomingClient (_http_client.js:641:27)
at HTTPParser.parserOnHeadersComplete (_http_common.js:126:17)
at TLSSocket.socketOnData (_http_client.js:509:22)
at TLSSocket.emit (events.js:315:20)
at addChunk (internal/streams/readable.js:309:12)
at readableAddChunk (internal/streams/readable.js:284:9)
at TLSSocket.Readable.push (internal/streams/readable.js:223:10) {
statusCode: 404
}
I have this issue evry time i try to play a yt song ( mp3 file work and soundcloud songs work too) . I have this issue today and I havn't touch the code ; only show this error in the console

@parthasarathi-e
Copy link

Yes, Even I am facing same issue

@a26364177
Copy link

this pr can fixed
d1f5357

@N1C0exe
Copy link
Author

N1C0exe commented Jun 22, 2021

Somone on the support discord server say this : " 404 due to youtube updates their site and ytdl-core haven't been updated yet ". I think is correct becouse every single song that I try to play throw this error

@N1C0exe
Copy link
Author

N1C0exe commented Jun 22, 2021

this pr can fixed
d1f5357

this pr can fixed
d1f5357
fixed omg XD

@Exhabition
Copy link

That fix has some side effects, .lengthSeconds is no longer available for me atleast

@404invalid-user
Copy link

ah so its not just me I have been trouble shooting for hours

@nguyenHao5495
Copy link

Yes, Even I am facing same issue

@Samiul30
Copy link

Yes, Even I am facing same issue

I am aslo facing this.

@N1C0exe
Copy link
Author

N1C0exe commented Jun 22, 2021

Yes, Even I am facing same issue

try this d1f5357 ot jus wait new update

@nguyenHao5495
Copy link

Yes, Even I am facing same issue

try this d1f5357 ot jus wait new update
I am using ytdl-core to download youtube videos. I don't know how to handle this error

@404invalid-user
Copy link

Yes, Even I am facing same issue

try this d1f5357 ot jus wait new update
I am using ytdl-core to download youtube videos. I don't know how to handle this error

I have been trying an on error doesn't work you can't even try catch

@JeHwanYoo
Copy link

JeHwanYoo commented Jun 22, 2021

I think I know what's wrong.

2021-06-22-9-20-47

The URL "https://www.youtube.com/get_video_info" must work. But now responding with a 404.

need to check if the policy of the YouTube API has changed.

in ytdl-core/lib/info.js

@Sansekai
Copy link

.lengthSeconds undefined

@javalsai
Copy link

javalsai commented Jun 22, 2021

That fix has some side effects, .lengthSeconds is no longer available for me at least

Also having trouble with .publishDate and .related_videos return an empty array
Likes and dislikes are null and the channel has undefined subs

@N1C0exe
Copy link
Author

N1C0exe commented Jun 22, 2021

That fix has some side effects, .lengthSeconds is no longer available for me at least

Also having trouble with .publishDate and .related_videos return an empty array
Likes and dislikes are null and the channel has undefined subs

wait new update

@zaskker
Copy link

zaskker commented Jun 22, 2021

Tengo el mismo error, esperando nueva actualizacion.

@ghost
Copy link

ghost commented Jun 22, 2021

I have been researching and this error is due to YouTube having changed API. It is time to be patient.

@EPXOL
Copy link

EPXOL commented Jun 22, 2021

All of edits are in node_modules/ytdl-core/lib/info.js

This error can be fixed by not using getVideoInfoPage (set line 64 to //) (This will disable requests for https://www.youtube.com/get_video_info)
Then you can bypass too many requests error by disabling getWatchJSONPage (set line 63 to //) (This will disable requests that uses token that is reason why too many requests error exists in ytdl-core)
Then only site that can be data downloaded from is WatchHTMLPage but it's corupted so we need to fix it go to line 254 and replace it with (Cutting out HTML and get only JSON)

let jsonStr = body.split("ytInitialPlayerResponse = {")[1].split("}}};")[0] += "}}}";
Whole code here :
const querystring = require('querystring');
const sax = require('sax');
const miniget = require('miniget');
const utils = require('./utils');
// Forces Node JS version of setTimeout for Electron based applications
const { setTimeout } = require('timers');
const formatUtils = require('./format-utils');
const urlUtils = require('./url-utils');
const extras = require('./info-extras');
const sig = require('./sig');
const Cache = require('./cache');


const BASE_URL = 'https://www.youtube.com/watch?v=';


// Cached for storing basic/full info.
exports.cache = new Cache();
exports.cookieCache = new Cache(1000 * 60 * 60 * 24);
exports.watchPageCache = new Cache();


// Special error class used to determine if an error is unrecoverable,
// as in, ytdl-core should not try again to fetch the video metadata.
// In this case, the video is usually unavailable in some way.
class UnrecoverableError extends Error {}


// List of URLs that show up in `notice_url` for age restricted videos.
const AGE_RESTRICTED_URLS = [
  'support.google.com/youtube/?p=age_restrictions',
  'youtube.com/t/community_guidelines',
];


/**
 * Gets info from a video without getting additional formats.
 *
 * @param {string} id
 * @param {Object} options
 * @returns {Promise<Object>}
*/
exports.getBasicInfo = async(id, options) => {
  const retryOptions = Object.assign({}, miniget.defaultOptions, options.requestOptions);
  options.requestOptions = Object.assign({}, options.requestOptions, {});
  options.requestOptions.headers = Object.assign({},
    {
      // eslint-disable-next-line max-len
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.101 Safari/537.36',
    }, options.requestOptions.headers);
  const validate = info => {
    let playErr = utils.playError(info.player_response, ['ERROR'], UnrecoverableError);
    let privateErr = privateVideoError(info.player_response);
    if (playErr || privateErr) {
      throw playErr || privateErr;
    }
    return info && info.player_response && (
      info.player_response.streamingData || isRental(info.player_response) || isNotYetBroadcasted(info.player_response)
    );
  };
  let info = await pipeline([id, options], validate, retryOptions, [
    getWatchHTMLPage,
    //getWatchJSONPage,
    //getVideoInfoPage,
  ]);

  Object.assign(info, {
    formats: parseFormats(info.player_response),
    related_videos: extras.getRelatedVideos(info),
  });

  // Add additional properties to info.
  const media = extras.getMedia(info);
  const additional = {
    author: extras.getAuthor(info),
    media,
    likes: extras.getLikes(info),
    dislikes: extras.getDislikes(info),
    age_restricted: !!(media && media.notice_url && AGE_RESTRICTED_URLS.some(url => media.notice_url.includes(url))),

    // Give the standard link to the video.
    video_url: BASE_URL + id,
    storyboards: extras.getStoryboards(info),
    chapters: extras.getChapters(info),
  };

  info.videoDetails = extras.cleanVideoDetails(Object.assign({},
    info.player_response && info.player_response.microformat &&
    info.player_response.microformat.playerMicroformatRenderer,
    info.player_response && info.player_response.videoDetails, additional), info);

  return info;
};

const privateVideoError = player_response => {
  let playability = player_response && player_response.playabilityStatus;
  if (playability && playability.status === 'LOGIN_REQUIRED' && playability.messages &&
    playability.messages.filter(m => /This is a private video/.test(m)).length) {
    return new UnrecoverableError(playability.reason || (playability.messages && playability.messages[0]));
  } else {
    return null;
  }
};


const isRental = player_response => {
  let playability = player_response.playabilityStatus;
  return playability && playability.status === 'UNPLAYABLE' &&
    playability.errorScreen && playability.errorScreen.playerLegacyDesktopYpcOfferRenderer;
};


const isNotYetBroadcasted = player_response => {
  let playability = player_response.playabilityStatus;
  return playability && playability.status === 'LIVE_STREAM_OFFLINE';
};


const getWatchHTMLURL = (id, options) => `${BASE_URL + id}&hl=${options.lang || 'en'}`;
const getWatchHTMLPageBody = (id, options) => {
  const url = getWatchHTMLURL(id, options);
  return exports.watchPageCache.getOrSet(url, () => utils.exposedMiniget(url, options).text());
};


const EMBED_URL = 'https://www.youtube.com/embed/';
const getEmbedPageBody = (id, options) => {
  const embedUrl = `${EMBED_URL + id}?hl=${options.lang || 'en'}`;
  return utils.exposedMiniget(embedUrl, options).text();
};


const getHTML5player = body => {
  let html5playerRes =
    /<script\s+src="([^"]+)"(?:\s+type="text\/javascript")?\s+name="player_ias\/base"\s*>|"jsUrl":"([^"]+)"/
      .exec(body);
  return html5playerRes ? html5playerRes[1] || html5playerRes[2] : null;
};


const getIdentityToken = (id, options, key, throwIfNotFound) =>
  exports.cookieCache.getOrSet(key, async() => {
    let page = await getWatchHTMLPageBody(id, options);
    let match = page.match(/(["'])ID_TOKEN\1[:,]\s?"([^"]+)"/);
    if (!match && throwIfNotFound) {
      throw new UnrecoverableError('Cookie header used in request, but unable to find YouTube identity token');
    }
    return match && match[2];
  });


/**
 * Goes through each endpoint in the pipeline, retrying on failure if the error is recoverable.
 * If unable to succeed with one endpoint, moves onto the next one.
 *
 * @param {Array.<Object>} args
 * @param {Function} validate
 * @param {Object} retryOptions
 * @param {Array.<Function>} endpoints
 * @returns {[Object, Object, Object]}
 */
const pipeline = async(args, validate, retryOptions, endpoints) => {
  let info;
  for (let func of endpoints) {
    try {
      const newInfo = await retryFunc(func, args.concat([info]), retryOptions);
      if (newInfo.player_response) {
        newInfo.player_response.videoDetails = assign(
          info && info.player_response && info.player_response.videoDetails,
          newInfo.player_response.videoDetails);
        newInfo.player_response = assign(info && info.player_response, newInfo.player_response);
      }
      info = assign(info, newInfo);
      if (validate(info, false)) {
        break;
      }
    } catch (err) {
      if (err instanceof UnrecoverableError || func === endpoints[endpoints.length - 1]) {
        throw err;
      }
      // Unable to find video metadata... so try next endpoint.
    }
  }
  return info;
};


/**
 * Like Object.assign(), but ignores `null` and `undefined` from `source`.
 *
 * @param {Object} target
 * @param {Object} source
 * @returns {Object}
 */
const assign = (target, source) => {
  if (!target || !source) { return target || source; }
  for (let [key, value] of Object.entries(source)) {
    if (value !== null && value !== undefined) {
      target[key] = value;
    }
  }
  return target;
};


/**
 * Given a function, calls it with `args` until it's successful,
 * or until it encounters an unrecoverable error.
 * Currently, any error from miniget is considered unrecoverable. Errors such as
 * too many redirects, invalid URL, status code 404, status code 502.
 *
 * @param {Function} func
 * @param {Array.<Object>} args
 * @param {Object} options
 * @param {number} options.maxRetries
 * @param {Object} options.backoff
 * @param {number} options.backoff.inc
 */
const retryFunc = async(func, args, options) => {
  let currentTry = 0, result;
  while (currentTry <= options.maxRetries) {
    try {
      result = await func(...args);
      break;
    } catch (err) {
      if (err instanceof UnrecoverableError ||
        (err instanceof miniget.MinigetError && err.statusCode < 500) || currentTry >= options.maxRetries) {
        throw err;
      }
      let wait = Math.min(++currentTry * options.backoff.inc, options.backoff.max);
      await new Promise(resolve => setTimeout(resolve, wait));
    }
  }
  return result;
};


const jsonClosingChars = /^[)\]}'\s]+/;
const parseJSON = (source, varName, json) => {
  if (!json || typeof json === 'object') {
    return json;
  } else {
    try {
      json = json.replace(jsonClosingChars, '');
      return JSON.parse(json);
    } catch (err) {
      throw Error(`Error parsing ${varName} in ${source}: ${err.message}`);
    }
  }
};


const findJSON = (source, varName, body, left, right, prependJSON) => {
  let jsonStr = body.split("ytInitialPlayerResponse = {")[1].split("}}};")[0] += "}}}";
  if (!jsonStr) {
    throw Error(`Could not find ${varName} in ${source}`);
  }
  return parseJSON(source, varName, utils.cutAfterJSON(`${prependJSON}${jsonStr}`));
};


const findPlayerResponse = (source, info) => {
  const player_response = info && (
    (info.args && info.args.player_response) ||
    info.player_response || info.playerResponse || info.embedded_player_response);
  return parseJSON(source, 'player_response', player_response);
};


const getWatchJSONURL = (id, options) => `${getWatchHTMLURL(id, options)}&pbj=1`;
const getWatchJSONPage = async(id, options) => {
  const reqOptions = Object.assign({ headers: {} }, options.requestOptions);
  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-identity-token': exports.cookieCache.get(cookie || 'browser') || '',
  }, reqOptions.headers);

  const setIdentityToken = async(key, throwIfNotFound) => {
    if (reqOptions.headers['x-youtube-identity-token']) { return; }
    reqOptions.headers['x-youtube-identity-token'] = await getIdentityToken(id, options, key, throwIfNotFound);
  };

  if (cookie) {
    await setIdentityToken(cookie, true);
  }

  const jsonUrl = getWatchJSONURL(id, options);
  const body = await utils.exposedMiniget(jsonUrl, options, reqOptions).text();
  let parsedBody = parseJSON('watch.json', 'body', body);
  if (parsedBody.reload === 'now') {
    await setIdentityToken('browser', false);
  }
  if (parsedBody.reload === 'now' || !Array.isArray(parsedBody)) {
    throw Error('Unable to retrieve video metadata in watch.json');
  }
  let info = parsedBody.reduce((part, curr) => Object.assign(curr, part), {});
  info.player_response = findPlayerResponse('watch.json', info);
  info.html5player = info.player && info.player.assets && info.player.assets.js;

  return info;
};


const getWatchHTMLPage = async(id, options) => {
  let body = await getWatchHTMLPageBody(id, options);
  let info = { page: 'watch' };
  try {
    info.player_response = findJSON('watch.html', 'player_response',
      body, /\bytInitialPlayerResponse\s*=\s*\{/i, '\n', '{');
  } catch (err) {
    let args = findJSON('watch.html', 'player_response', body, /\bytplayer\.config\s*=\s*{/, '</script>', '{');
    info.player_response = findPlayerResponse('watch.html', args);
  }
  info.response = findJSON('watch.html', 'response', body, /\bytInitialData("\])?\s*=\s*\{/i, '\n', '{');
  info.html5player = getHTML5player(body);
  return info;
};


const INFO_HOST = 'www.youtube.com';
const INFO_PATH = '/get_video_info';
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('eurl', VIDEO_EURL + id);
  url.searchParams.set('ps', 'default');
  url.searchParams.set('gl', 'US');
  url.searchParams.set('hl', options.lang || 'en');
  url.searchParams.set('html5', '1');
  const body = await utils.exposedMiniget(url.toString(), options).text();
  let info = querystring.parse(body);
  info.player_response = findPlayerResponse('get_video_info', info);
  return info;
};


/**
 * @param {Object} player_response
 * @returns {Array.<Object>}
 */
const parseFormats = player_response => {
  let formats = [];
  if (player_response && player_response.streamingData) {
    formats = formats
      .concat(player_response.streamingData.formats || [])
      .concat(player_response.streamingData.adaptiveFormats || []);
  }
  return formats;
};


/**
 * Gets info from a video additional formats and deciphered URLs.
 *
 * @param {string} id
 * @param {Object} options
 * @returns {Promise<Object>}
 */
exports.getInfo = async(id, options) => {
  let info = await exports.getBasicInfo(id, options);
  const hasManifest =
    info.player_response && info.player_response.streamingData && (
      info.player_response.streamingData.dashManifestUrl ||
      info.player_response.streamingData.hlsManifestUrl
    );
  let funcs = [];
  if (info.formats.length) {
    info.html5player = info.html5player ||
      getHTML5player(await getWatchHTMLPageBody(id, options)) || getHTML5player(await getEmbedPageBody(id, options));
    if (!info.html5player) {
      throw Error('Unable to find html5player file');
    }
    const html5player = new URL(info.html5player, BASE_URL).toString();
    funcs.push(sig.decipherFormats(info.formats, html5player, options));
  }
  if (hasManifest && info.player_response.streamingData.dashManifestUrl) {
    let url = info.player_response.streamingData.dashManifestUrl;
    funcs.push(getDashManifest(url, options));
  }
  if (hasManifest && info.player_response.streamingData.hlsManifestUrl) {
    let url = info.player_response.streamingData.hlsManifestUrl;
    funcs.push(getM3U8(url, options));
  }

  let results = await Promise.all(funcs);
  info.formats = Object.values(Object.assign({}, ...results));
  info.formats = info.formats.map(formatUtils.addFormatMeta);
  info.formats.sort(formatUtils.sortFormats);
  info.full = true;
  return info;
};


/**
 * Gets additional DASH formats.
 *
 * @param {string} url
 * @param {Object} options
 * @returns {Promise<Array.<Object>>}
 */
const getDashManifest = (url, options) => new Promise((resolve, reject) => {
  let formats = {};
  const parser = sax.parser(false);
  parser.onerror = reject;
  let adaptationSet;
  parser.onopentag = node => {
    if (node.name === 'ADAPTATIONSET') {
      adaptationSet = node.attributes;
    } else if (node.name === 'REPRESENTATION') {
      const itag = parseInt(node.attributes.ID);
      if (!isNaN(itag)) {
        formats[url] = Object.assign({
          itag, url,
          bitrate: parseInt(node.attributes.BANDWIDTH),
          mimeType: `${adaptationSet.MIMETYPE}; codecs="${node.attributes.CODECS}"`,
        }, node.attributes.HEIGHT ? {
          width: parseInt(node.attributes.WIDTH),
          height: parseInt(node.attributes.HEIGHT),
          fps: parseInt(node.attributes.FRAMERATE),
        } : {
          audioSampleRate: node.attributes.AUDIOSAMPLINGRATE,
        });
      }
    }
  };
  parser.onend = () => { resolve(formats); };
  const req = utils.exposedMiniget(new URL(url, BASE_URL).toString(), options);
  req.setEncoding('utf8');
  req.on('error', reject);
  req.on('data', chunk => { parser.write(chunk); });
  req.on('end', parser.close.bind(parser));
});


/**
 * Gets additional formats.
 *
 * @param {string} url
 * @param {Object} options
 * @returns {Promise<Array.<Object>>}
 */
const getM3U8 = async(url, options) => {
  url = new URL(url, BASE_URL);
  const body = await utils.exposedMiniget(url.toString(), options).text();
  let formats = {};
  body
    .split('\n')
    .filter(line => /^https?:\/\//.test(line))
    .forEach(line => {
      const itag = parseInt(line.match(/\/itag\/(\d+)\//)[1]);
      formats[line] = { itag, url: line };
    });
  return formats;
};


// Cache get info functions.
// In case a user wants to get a video's info before downloading.
for (let funcName of ['getBasicInfo', 'getInfo']) {
  /**
   * @param {string} link
   * @param {Object} options
   * @returns {Promise<Object>}
   */
  const func = exports[funcName];
  exports[funcName] = async(link, options = {}) => {
    utils.checkForUpdates();
    let id = await urlUtils.getVideoID(link);
    const key = [funcName, id, options.lang].join('-');
    return exports.cache.getOrSet(key, () => func(id, options));
  };
}


// Export a few helpers.
exports.validateID = urlUtils.validateID;
exports.validateURL = urlUtils.validateURL;
exports.getURLVideoID = urlUtils.getURLVideoID;
exports.getVideoID = urlUtils.getVideoID;

@TheJerryFox
Copy link

Tried the fix, now I dont have any sound

@EPXOL
Copy link

EPXOL commented Jun 22, 2021

This has nothing to do with video or audio downloading it fixes data (info) downloading and that was the problem. And I am using it in my bot and it works.

@CrypticMrDark
Copy link

well, he's right. follow Epxol

@EdgarNunezTrejo
Copy link

I fixed it adding this two lines:
url.searchParams.set('c', 'TVHTML5'); url.searchParams.set('cver', '7.20190319');

As @a26364177 refered, then I put:

try{ var info = await ytdl.getInfo(url) }catch(e){ console.log('error catch',e) }

And it worked again.

@Lazy-C0der
Copy link

This has nothing to do with video or audio downloading it fixes data (info) downloading and that was the problem. And I am using it in my bot and it works.

he's right

@Lazy-C0der
Copy link

why i a getting this error ? MinigetError: Status code: 404

epxol has already given code above
but if you still have doubt then try this

https://youtu.be/TYMsAYAx5Z0

@CrypticMrDark
Copy link

CrypticMrDark commented Jun 23, 2021 via email

@deereyeskart
Copy link

Song and videos not downloading,, something went error occur.. Please fix the error.. Please new update suddenly.. Thank you

@RaghuMudem
Copy link

RaghuMudem commented Jun 24, 2021

When is the official release for version 4.8.3 with the fix for this issue #939 ??

@ryzyx
Copy link

ryzyx commented Jun 24, 2021

Has this issue been fixed yet?

@jbelford
Copy link

jbelford commented Jun 24, 2021

I believe the root of the issue for the fix that @EPXOL posted is that the use of regex to get a substring seems to be very flaky - particularly since we have a regex that tries to find the end of the object definition which regex is not well suited for. And the object representation changing will break it each time.

If we just get the point where this variable is created we could probably just do something like below to get to the beginning of the object definition.

let jsonStr = body.split(/(var|let|const)\s+ytInitialPlayerResponse\s*=\s*\/i)[1];

Then what we want to do is iterate through the object definition like is done in cutAfterJSON (we may be able to straight up call this as is without any changes). We don't need to know when the end of this object definition is in the string before calling cutAfterJSON - if we reach the end of the string we error out.

TLDR; we can likely fix bug by not using utils.between(body, left, right) instead just get substring of whole string after left

@D3SOX
Copy link
Contributor

D3SOX commented Jun 24, 2021

@jbelford #946 already fixes this part of the problem in a better way

@Eris-js
Copy link

Eris-js commented Jun 25, 2021

good, it works great

@github-actions
Copy link

🎉 This issue has been resolved in version 4.8.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

@TimeForANinja
Copy link
Collaborator

as noted in #938 i hope the 404s are fixed
various videoDetails are broken, but i wanna keep the discussion for that in #958
thanks for everyone that helped

@QuazArxx
Copy link

I'm still getting 404 errors. I just started attempting to use ytdl-core. I tried the fix above by EPXOL and while the error went away, there is still no sound coming from links having that issue.

@N1C0exe
Copy link
Author

N1C0exe commented Jul 23, 2021

I'm still getting 404 errors. I just started attempting to use ytdl-core. I tried the fix above by EPXOL and while the error went away, there is still no sound coming from links having that issue.

Hi Its come again for me too becouse I try to play restricted video age

@QuazArxx
Copy link

I'm still getting 404 errors. I just started attempting to use ytdl-core. I tried the fix above by EPXOL and while the error went away, there is still no sound coming from links having that issue.

Hi Its come again for me too becouse I try to play restricted video age

I didn't notice until you said that but yeah the issues seem to be with restricted videos now. All the other videos work fine.

@N1C0exe
Copy link
Author

N1C0exe commented Jul 23, 2021

I'm still getting 404 errors. I just started attempting to use ytdl-core. I tried the fix above by EPXOL and while the error went away, there is still no sound coming from links having that issue.

Hi Its come again for me too becouse I try to play restricted video age

I didn't notice until you said that but yeah the issues seem to be with restricted videos now. All the other videos work fine.

Yes same situation

@nukeop
Copy link

nukeop commented Jul 23, 2021

A pox upon youtube, their executives, and theirs for these shenaningans

@TimeForANinja
Copy link
Collaborator

might be related but i'd still prefer a new, own issue for that then 😉

@sanikava
Copy link

@Nico-ITA Hi now we are getting new error 401
lol

@N1C0exe
Copy link
Author

N1C0exe commented Jul 31, 2021

@Nico-ITA Hi now we are getting new error 401
lol

Hey bro ! Im only getting 403 error xD never 401

@nokisenpai
Copy link

nokisenpai commented Dec 9, 2021

Here I get 410 error with this video : https://www.youtube.com/watch?v=K3GkSo3ujSY

`D:\Perso\prog\Kinoa\node_modules\miniget\dist\index.js:210
let err = new Miniget.MinigetError(Status code: ${res.statusCode}, res.statusCode);
^

MinigetError: Status code: 410
at ClientRequest. (D:\Perso\prog\Kinoa\node_modules\miniget\dist\index.js:210:27)
at Object.onceWrapper (node:events:510:26)
at ClientRequest.emit (node:events:390:28)
at HTTPParser.parserOnIncomingClient (node:_http_client:623:27)
at HTTPParser.parserOnHeadersComplete (node:_http_common:128:17)
at TLSSocket.socketOnData (node:_http_client:487:22)
at TLSSocket.emit (node:events:390:28)
at addChunk (node:internal/streams/readable:324:12)
at readableAddChunk (node:internal/streams/readable:297:9)
at TLSSocket.Readable.push (node:internal/streams/readable:234:10)
Emitted 'error' event on PassThrough instance at:
at runMicrotasks ()
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
statusCode: 410
}`

@sanikava
Copy link

sanikava commented Dec 12, 2021

If you getting 403 then it means your access forbidden because of high api use 😓 just stop using heroku if you using otherwise wait for a long time 🤣

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.