JuanBindez / pytubefix

Python3 library for downloading YouTube Videos.
https://pytubefix.readthedocs.io
MIT License
722 stars 100 forks source link

pytubefix.exceptions.VideoUnavailable: ←[91mE0MrUUs7PfA is unavailable←[0m #242

Closed robochopbg closed 2 weeks ago

robochopbg commented 2 months ago

:exclamation: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE :exclamation:

lack of information will lead to closure of the issue


Describe the bug

This error is back. I have update today to the latest version of pytubefix

File "C:\Python310\lib\site-packages\pytubefix__main__.py", line 600, in streams self.check_availability() File "C:\Python310\lib\site-packages\pytubefix__main__.py", line 334, in check_availability raise exceptions.VideoUnavailable(video_id=self.video_id) pytubefix.exceptions.VideoUnavailable: ←[91mE0MrUUs7PfA is unavailable←[0m


code that was used that resulted in the bug

from pytubefix import Search, YouTube, Stream

def get_youtube_stream(self, id: str, title: str):
KThread(
name=self.get_youtube_stream.name,
target=self.get_stream, args=(id, title)
).start()

def get_stream(self, id: str, title: str):
try:
stream: Stream = self.get_url(id)
except Exception:
print("error", "".join(traceback.format_exc().rstrip("\n")))
else:
if stream is not None:
self.send_disp_event(
Inst.VLCMgr, {EType.Network: [stream.url, title]}
)

def get_url(self, video_id: str) -> str:
video_url = f"[https://www.youtube.com/watch?v={video_id}](https://www.youtube.com/watch?v=%7Bvideo_id%7D)"
yt = YouTube(video_url)
return yt.streams.get_highest_resolution()

Expected behavior This error came up before. Youguys gave out a temp fix that i manually added to pytubefix in cipher.py module

Current method def get_throttling_function_name(js: str, js_url: str) -> str: """Extract the name of the function that computes the throttling parameter.

:param str js:
    The contents of the base.js asset file.
:param str js_url:
    Full base.js url
:rtype: str
:returns:
    The name of the function used to compute the throttling parameter.
"""
function_patterns = [
    # https://github.com/ytdl-org/youtube-dl/issues/29326#issuecomment-865985377
    # https://github.com/yt-dlp/yt-dlp/commit/48416bc4a8f1d5ff07d5977659cb8ece7640dcd8
    # var Bpa = [iha];
    # ...
    # a.C && (b = a.get("n")) && (b = Bpa[0](b), a.set("n", b),
    # Bpa.length || iha("")) }};
    # In the above case, `iha` is the relevant function name
    # r'a\.[a-zA-Z]\s*&&\s*\([a-z]\s*=\s*a\.get\("n"\)\)\s*&&\s*'
    # r'\([a-z]\s*=\s*([a-zA-Z0-9$]+)(\[\d+\])?\([a-z]\)',

    # New pattern added on July 9, 2024
    # https://github.com/yt-dlp/yt-dlp/pull/10390/files
    # In this example we can find the name of the function at index "0" of "IRa"
    # a.D && (b = String.fromCharCode(110), c = a.get(b)) && (c = IRa[0](c), a.set(b,c), IRa.length || Ima(""))
    # r'(?:\.get\(\"n\"\)\)&&\(b=|b=String\.fromCharCode\(\d+\),c=a\.get\(b\)\)&&\(c=)([a-zA-Z0-9$]+)(?:\[('r'\d+)\])?\([a-zA-Z0-9]\)'

    # New pattern added on July 23, 2024
    # https://github.com/yt-dlp/yt-dlp/pull/10542
    # a.D && (b = "nn"[+a.D], c = a.get(b)) && (c = rDa[0](c), a.set(b,c), rDa.length || rma(""))
    # r'(?:\.get\("n"\)\)&&\(b=|(?:b=String\.fromCharCode\(110\)|([a-zA-Z0-9$.]+)&&\(b="nn"\[\+\1\]),c=a\.get\(b\)\)&&\(c=)(?P<nfunc>[a-zA-Z0-9$]+)(?:\[(?P<idx>\d+)\])?\([a-zA-Z0-9]\)'

    # New pattern used in player "20dfca59" on July 29, 2024
    # a.D && (PL(a), b = a.j.n || null) && (b = oDa[0](b), a.set("n", b), oDa.length || rma(""))
    # Regex logic changed based on old players, n_func can easily be found after ".length ||",
    # in this case n_func is "rma"
    # Before this regex, we got the function inside the idx 0 of "oDa"
    r'[abc]=(?P<func>[a-zA-Z0-9$]+)\[(?P<idx>\d+)\]\([abc]\),a\.set\([a-zA-Z0-9$\",]+\),'
    r'[a-zA-Z0-9$]+\.length\|\|(?P<n_func>[a-zA-Z0-9$]+)\(\"\"\)'

Update code that fixes the above error

r'a.[a-zA-Z]\s&&\s([a-z]\s=\sa.get("n"))\s&&.?||\s([a-z]+)', r'([a-z]\s=\s([a-zA-Z0-9$]+)([\d+])?([a-z])', r'([a-z]\s=\s*([a-zA-Z0-9$]+)([\d+])([a-z])',


Screenshots Capture


Desktop (please complete the following information): Windows 10 Pro - 22H2 Python 3.10.7 final Pytubefix - 6.16.3


Additional context Add any other context about the problem here.

robochopbg commented 2 months ago

The updated code i gave didnt fix it either.

jhanley-com commented 2 months ago

The Video ID appears to have ANSI color codes embedded in it. What is the actual Video ID? Are you trying to "copy and paste" something. If yes, you have done so incorrectly (copied the colors with the value).

As described, it appears your problem is with your application or usage of your application and not with PyTubeFix. Provide more details to be sure.

JuanBindez commented 2 months ago

it is not trying to use the colors, they are from pytubefix and do not influence the program's behavior, it appears like this because it must be in a cloud environment

JuanBindez commented 2 months ago

What is probably causing the problem is the environment in which it is running.

jhanley-com commented 2 months ago

UPDATE 2024-09-24

This evening I am seeing this error for all videos. I changed the code to specify the client and that seems to fix the problem today.

YouTube(url, client='WEB_CREATOR')

ORIGINAL COMMENT

Deducing the actual Video ID from the error string: https://www.youtube.com/watch?v=E0MrUUs7PfA

I am able to download that video using PyTubeFix:

16:54:49 downloading audio: 73.35 MB 128kbps 80s Number Ones Monsterjam (Mixed By Ray Rungay)

Note: I often see error messages similar to "Error: E0MrUUs7PfA is unavailable". Wait 5 seconds and try again usually fixes the problem. Sometimes additional retires are required. In my test, that is exactly what happened. The first download attempt returned the error and the second attempt succeeded.

The error is pytubefix.exceptions.VideoUnavailable.

That most likely means the error is in the application design and not with PyTubeFix. However, I have not deep dived into the source code to see exactly how that exception is generated.

Maybe related or not to this error. I have Cloud, and home Gigabit and DSL connected systems. On the system connected to the Internet using DSL (1.5 Mbit max speed), I often see this error but not with my other systems. The code I wrote has lots of error detection and retry logic because of testing on low quality connections. Most of the world does not have the high quality connections we have in the more developed countries.

robochopbg commented 2 months ago

The code i use does not run from a cloud environment. I'm coding a windows application using pyside6.

When i do get this error type - pytubefix.exceptions.VideoUnavailable: ←[91mE0MrUUs7PfA is unavailable←[0m, if i try the same video again it then works fine the 2nd time around.

felipeucelli commented 2 months ago

YouTube appears to be blocking some requests made by the ANDROID_TESTSUITE client.

Try another client, for example IOS, WEB_EMBED , MWEB or WEB_CREATOR, and tell us the result:

yt = YouTube(video_url, 'WEB_CREATOR')

Note:

The IOS client does not have any progressive stream, that is, the audio and video files are separate.

WEB-based clients require signature cipher decryption, so they may take a little longer to generate the streams.

So far cipher.py is working correctly, don't change it or you may cause a decryption error and generate a 403 error.

celarain commented 2 months ago

I am getting same error pytubefix.exceptions.VideoUnavailable: ←[91mE0MrUUs7PfA is unavailable, in cloud and local and being authenticated.

Tryed this way and worked:

    yt = YouTube(
        url,
        'MWEB', //Added
        use_oauth=True,
        allow_oauth_cache=True,
    )
ArtisanByteCrafter commented 1 month ago

Seeing the same thing in my application I have written. I am adding my feedback here as the issue seems a lot more prevalent when I am on a public guest wifi (Starbucks). Turning on my VPN to my home IP does not help, but having shitty Starbucks wifi does seem to influence how often I see this error. When I am coding at home on gig fiber, it's less frequently.

YouTube appears to be blocking some requests made by the ANDROID_TESTSUITE client.

Try another client, for example IOS, WEB_EMBED , MWEB or WEB_CREATOR, and tell us the result:

I tried a variety of clients and they all returned similar error frequency and randomness. The bigger variable seems to be the quality of the network the requests are being made from.

EDIT: Even at home now, I am getting this on essentially every query. Something seems up on the YouTube side, it does this on both pytubefix 6.16.3 and 6.16.2

grumpyp commented 1 month ago
'WEB_CREATOR'

Changing it to WEB_CREATOR e.g. self.video = YouTube(self.url, 'WEB_CREATOR') worked for me.

xcgfgfcfqgqxhsjhgfjgkdfd commented 1 month ago

hello, in which module it must be done? I mean the 'WEB_CREATOR' ?

grumpyp commented 1 month ago

hello, in which module it must be done? I mean the 'WEB_CREATOR' ?

this is how I use it

class YoutubeVideo:
    def __init__(self, url: str):
        self.url = url
        self.video = None
        self.audio_path = None

    def download_video(self):
        self.video = YouTube(self.url, 'WEB_CREATOR')
...

so in the Youtube class

sopuruAI commented 1 month ago

I've tried all the combinations but I still get this error... "Error downloading video: get_throttling_function_name: could not find match for multiple"

dw-audio commented 1 month ago

same here, attempted to download with multiple clients, but no luck. Currently looking at hijacking a request like this (I'm only ever trying to download my own video - this link is in YouTube Studio).

https://www.youtube.com/download_my_video?v=&t=

ChildishhAlbino commented 1 month ago

yeah I'm using pytubefix==7.1.3 and have tried:

boulbi777 commented 1 month ago

After several hours spent on this bug, I can't still figure it out ! In my case, when I use pytubefix on my personal laptop with all the default parameter, there is no problem. But, when I push my code to github-actions, the Youtube class fails on reading the video and returns None in the GitHub runner. Most of the time it's about VideoUnavailable exception ! I'm trying to download an audio from a YouTube link.

I've tried all the client on the docs : ["WEB", ..., "MEDIA_CONNECT"], the clients that seems to successfully find the video in my case were ANDROID_MUSIC and WEB_MUSIC but they fails on downloading the audio.

Has anyone tried to make a download from github-actions ?

Thanks..

ChildishhAlbino commented 1 month ago

I think I had an issue with my pip install because a fresh install and using ANDROID_VR seemed to fix the issue for some videos.

felipeucelli commented 1 month ago

yeah I'm using pytubefix==7.1.3 and have tried:

  • the client on WEB_CREATOR which fails with a generic bad request.
  • the client on TV_EMBED, WEB, and a few others, which all fail with Details: get_throttling_function_name: could not find match for multiple

The error get_throttling_function_name: could not find match for multiple, is from old versions of pytubefix, in the most recent versions it has been updated. Make sure you are using the latest stable version and that you are importing pytubefix correctly.

After several hours spent on this bug, I can't still figure it out ! In my case, when I use pytubefix on my personal laptop with all the default parameter, there is no problem. But, when I push my code to github-actions, the Youtube class fails on reading the video and returns None in the GitHub runner. Most of the time it's about VideoUnavailable exception ! I'm trying to download an audio from a YouTube link.

I've tried all the client on the docs : ["WEB", ..., "MEDIA_CONNECT"], the clients that seems to successfully find the video in my case were ANDROID_MUSIC and WEB_MUSIC but they fails on downloading the audio.

Has anyone tried to make a download from github-actions ?

Thanks..

YouTube may require PoToken for all cloud clients

ChildishhAlbino commented 1 month ago

The error get_throttling_function_name: could not find match for multiple, is from old versions of pytubefix, in the most recent versions it has been updated. Make sure you are using the latest stable version and that you are importing pytubefix correctly.

yeah I updated and that fixed that error. Have found the MWEB client works best with Authorization - couldn't get WEB_CREATOR to work.

Tektronox commented 1 month ago

WEB_CREATOR client also doesn't work anymore for me, had success with yt_video = YouTube(url, client="WEB_EMBED")

xcgfgfcfqgqxhsjhgfjgkdfd commented 1 month ago

yt_video = YouTube(url, client="WEB_EMBED") for me doesn't show an error, but doesn't work

rowericzi commented 1 month ago

WEB_EMBED works for me, but for certain videos it consistently fails. ANDROID_MUSIC seems to work for most videos for me, but not always on the first try - I needed to add some retry mechanism.

felipeucelli commented 1 month ago

This issue has now been fixed, no need to change the client, just update to the latest version of pytubefix which implements the ANDROID_VR client as default.

The WEB_CREATOR client is undergoing changes that require login, embed clients fail for videos that cannot be embedded and music clients fail for videos that are not labeled as music.

n8creator commented 1 month ago

Well, there is no exact client value that will work - I tested them all. Here is what I did - just wrote a loop to try to download audio or video with any of the clients:

CLIENTS = {
    1: "WEB",
    2: "WEB_EMBED",
    3: "WEB_MUSIC",
    4: "WEB_CREATOR",
    5: "WEB_SAFARI",
    6: "ANDROID",
    7: "ANDROID_MUSIC",
    8: "ANDROID_CREATOR",
    9: "ANDROID_VR",
    10: "ANDROID_PRODUCER",
    11: "ANDROID_TESTSUITE",
    12: "IOS",
    13: "IOS_MUSIC",
    14: "IOS_CREATOR",
    15: "MWEB",
    16: "TV_EMBED",
    17: "MEDIA_CONNECT",
}

def download(url: str, settings: dict, filetype: str):
    """Download filetype (video or audio) with one of the clients from the CLIENTS list."""
    for _, client in CLIENTS.items():
        try:
            # Try to reach filetype and create YouTube object
            print(colored(f'Trying to reach {filetype} with "{client}" client', "yellow"))
            yt = (
                YouTube(url=url, client=client, on_progress_callback=on_progress)
                .streams.filter(**settings["params"])
                .order_by(settings["order_by"])
                .desc()
                .first()
            )

            # Download filetype (video or audio)
            print(colored(f'Downloading "{shorten_name(yt.title)}" ' f'{settings["intro_message"]}'))
            yt.download(filename=f"{filetype}.mp4", skip_existing=False, timeout=10, max_retries=5)
            print(colored(f'\n{settings["out_message"]}', "blue"))

            # Return from function if success
            return
        except Exception as e:
            print(colored(f'Error occured while downloading via "{client}" client: {e}\n', "red"))

    raise Exception("Failed to download asset with all available clients")

And here is an output (as an example):

$ youtube -s https://www.youtube.com/watch?v=_cX6lSVL1fM --hq

Trying to reach video with "WEB" client
Downloading "HP OmniBook Intel Core Ultra 256V Review and Benchmark" .mp4 video file in highest available resolution...
Error occured while downloading via "WEB" client: HTTP Error 403: Forbidden

Trying to reach video with "WEB_EMBED" client
Downloading "HP OmniBook Intel Core Ultra 256V Review and Benchmark" .mp4 video file in highest available resolution...
 ↳ |████████████████████████████████████████████████████████████████████████████████████████| 100.0%
.mp4 video file was successfully downloaded!

Trying to reach audio with "WEB" client
Downloading "HP OmniBook Intel Core Ultra 256V Review and Benchmark" audio file in highest available bitrate...
Error occured while downloading via "WEB" client: HTTP Error 403: Forbidden

Trying to reach audio with "WEB_EMBED" client
Downloading "HP OmniBook Intel Core Ultra 256V Review and Benchmark" audio file in highest available bitrate...
 ↳ |████████████████████████████████████████████████████████████████████████████████████████| 100.0%
Audio track successfully downloaded...

Audio and video files were merged...
Video was saved as "2024-10-02 - [consumer tech warehouse] - HP OmniBook Intel Core***.mp4"!

and another example:

$ youtube -s https://www.youtube.com/watch?v=uR5r9Dr0Z4I --hq

Trying to reach video with "WEB" client
Downloading "ЛИПСИЦ ЛЕКЦИЯ В АКАДЕМИИ НАУК ЛИТВЫ О БУДУЩЕМ МИРОВОЙ ЭКОНОМИКИ***" .mp4 video file in highest available resolution...
Error occured while downloading via "WEB" client: HTTP Error 403: Forbidden

Trying to reach video with "WEB_EMBED" client
Error occured while downloading via "WEB_EMBED" client: uR5r9Dr0Z4I is streaming live and cannot be loaded

Trying to reach video with "WEB_MUSIC" client
Error occured while downloading via "WEB_MUSIC" client: uR5r9Dr0Z4I is unavailable

Trying to reach video with "WEB_CREATOR" client
Error occured while downloading via "WEB_CREATOR" client: uR5r9Dr0Z4I requires login to view, reason: Please sign in

Trying to reach video with "WEB_SAFARI" client
Downloading "ЛИПСИЦ ЛЕКЦИЯ В АКАДЕМИИ НАУК ЛИТВЫ О БУДУЩЕМ МИРОВОЙ ЭКОНОМИКИ***" .mp4 video file in highest available resolution...
Error occured while downloading via "WEB_SAFARI" client: HTTP Error 403: Forbidden

Trying to reach video with "ANDROID" client
Downloading "ЛИПСИЦ ЛЕКЦИЯ В АКАДЕМИИ НАУК ЛИТВЫ О БУДУЩЕМ МИРОВОЙ ЭКОНОМИКИ***" .mp4 video file in highest available resolution...
Error occured while downloading via "ANDROID" client: HTTP Error 403: Forbidden             | 36.5%

Trying to reach video with "ANDROID_MUSIC" client
Error occured while downloading via "ANDROID_MUSIC" client: uR5r9Dr0Z4I is unavailable

Trying to reach video with "ANDROID_CREATOR" client
Error occured while downloading via "ANDROID_CREATOR" client: uR5r9Dr0Z4I requires login to view, reason: Please sign in

Trying to reach video with "ANDROID_VR" client
Error occured while downloading via "ANDROID_VR" client: uR5r9Dr0Z4I is streaming live and cannot be loaded

Trying to reach video with "ANDROID_PRODUCER" client
Error occured while downloading via "ANDROID_PRODUCER" client: HTTP Error 403: Forbidden

Trying to reach video with "ANDROID_TESTSUITE" client
Error occured while downloading via "ANDROID_TESTSUITE" client: uR5r9Dr0Z4I is unavailable

Trying to reach video with "IOS" client
Downloading "ЛИПСИЦ ЛЕКЦИЯ В АКАДЕМИИ НАУК ЛИТВЫ О БУДУЩЕМ МИРОВОЙ ЭКОНОМИКИ***" .mp4 video file in highest available resolution...
 ↳ |███████████████████████████████████████████████████████████████████████████████████████████| 100.0%
.mp4 video file was successfully downloaded!
...
mimo2202 commented 1 week ago

uninstall and install pytubefix-8.3.2 solve the issue!

mimo2202 commented 1 week ago

pip uninstall pytubefix -> pip install pytubefix

JuanBindez commented 1 week ago

or pip install pytubefix --upgrade