Skip to content

Instantly share code, notes, and snippets.

@pukkandan
Last active January 2, 2023 16:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pukkandan/24f13ff1ed385c5a390c1d7bd130d8f7 to your computer and use it in GitHub Desktop.
Save pukkandan/24f13ff1ed385c5a390c1d7bd130d8f7 to your computer and use it in GitHub Desktop.
yt-dlp plugin extractor to decrypt youtube nsig online
Moved to https://github.com/pukkandan/YT_NSigProxy
"""
SPDX-License-Identifier: MIT https://opensource.org/licenses/MIT
Copyright © 2022 pukkandan.ytdlp@gmail.com
yt-dlp plugin extractor to decrypt youtube nsig online
Needs yt-dlp 2022.09.17 or above
Usage: Import this file in ytdlp_plugins/extractor/__init__.py
See https://github.com/yt-dlp/yt-dlp#plugins for details
Solver Source:
https://github.com/pukkandan/yt-dlp-online-utils/blob/master/api/youtube/nparams/decrypt.js
Credits: @Lesmiscore for the implementation
Note: The solver has limited resources. Please do not abuse
"""
from yt_dlp.utils import ExtractorError, traverse_obj
from yt_dlp.extractor.youtube import YoutubeIE
SOLVER_URL = 'https://yt-dlp-online-utils.vercel.app/youtube/nparams/decrypt'
PREFER_SOLVER = False # Whether to prefer online solver over local solver
class Youtube_NsigProxyIE(YoutubeIE, plugin_name='NSIG'):
def __nsig_error(self, current, next, s, video_id, player_url, e):
self.report_warning(
f'{current} nsig extraction failed: Trying with {next}\n'
f' n = {s} ; player = {player_url}', video_id)
self.write_debug(e)
def _decrypt_nsig(self, s, video_id, player_url):
fallback = True
try:
if not player_url or not PREFER_SOLVER:
return super()._decrypt_nsig(s, video_id, player_url)
except Exception as e:
if not player_url:
raise
self.__nsig_error('Local', 'online solver', s, video_id, player_url, e)
fallback = False
try:
response_data = self._download_json(
SOLVER_URL, video_id, query={'player': player_url, 'n': s},
note='Requesting nsig decryption from online solver')
if response_data['status'] != 'ok':
raise ExtractorError(f'Failed at step "{response_data["step"]}":\n '
f'{traverse_obj(response_data, ("data", "message"))}')
self.write_debug(f'Decrypted nsig {s} => {response_data["data"]}')
return response_data['data']
except Exception as e:
if not fallback:
raise
self.__nsig_error('Online', 'local solver', s, video_id, player_url, e)
return super()._decrypt_nsig(s, video_id, player_url)
Copy link

ghost commented Sep 16, 2022

Everything good with latest commit, except two small things

  • small typo "Needs yt-dlp 2021.09.17 or above" => "Needs yt-dlp 2022.09.17 or above"
  • nsig always use online solver, even if PREFER_SOLVER = False

@pukkandan
Copy link
Author

@0xcc07c9 Thanks, fixed

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