mhogomchungu / media-downloader

Media Downloader is a Qt/C++ front end to yt-dlp, youtube-dl, gallery-dl, lux, you-get, svtplay-dl, aria2c, wget and safari books..
GNU General Public License v2.0
1.34k stars 102 forks source link

Media Downloader Does Not Work After Latest OpenSUSE Tumbleweed Update #331

Closed richardstevenhack closed 8 months ago

richardstevenhack commented 8 months ago

This one is very complex. Last night - 2023-10-24 - openSUSE Tumbleweed did an update which included installing a new version of yt-dlp.

Yesterday before the update, I downloaded Youtube videos both from the command line and from Media-Downloader with no issues using version 2023-07-06 of yt-dlp. I was running media-downloader-3.3.0-4.3.x86_64.

The Tumbleweed update installed yt-dlp version 2023-10-13. When I tried to run yt-dlp from my usual script or from the command line, I got this error:

rhack@localhost:/Data2/Work> /usr/bin/python3 /usr/bin/yt-dlp -R 0 -vU  --no-config --no-progress --fragment-retries 0 --skip-unavailable-fragments --abort-on-unavailable-fragment -o "%(title)s.%(ext)s" https://www.youtube.com/watch?v=x-nqRcDRTVs
Traceback (most recent call last):
  File "/usr/lib64/python3.11/importlib/metadata/__init__.py", line 563, in from_name
    return next(cls.discover(name=name))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/yt-dlp", line 33, in <module>
    sys.exit(load_entry_point('yt-dlp==2023.10.13', 'console_scripts', 'yt-dlp')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/bin/yt-dlp", line 22, in importlib_load_entry_point
    for entry_point in distribution(dist_name).entry_points
                       ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/importlib/metadata/__init__.py", line 981, in distribution
    return Distribution.from_name(distribution_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/importlib/metadata/__init__.py", line 565, in from_name
    raise PackageNotFoundError(name)
importlib.metadata.PackageNotFoundError: No package metadata was found for yt-dlp

I put in a bug report to yt-dlp, then found a previous bug report which was similar which included this suggested fix:

> python3 -m pip install --upgrade pip setuptools wheel
> 
> then
> 
> python3 -m pip install --force-reinstall https://github.com/yt-dlp/yt-dlp/archive/master.zip
> 
> and then run yt-dlp

I had problems trying to get that to work because openSUSE has a controlled pythin environment and will not directly install packages out of system control. The error message suggested to use "pipx", so I did this:

pipx install "yt-dlp>2023"
⚠  Note: yt-dlp was already on your PATH at /usr/bin/yt-dlp
  installed package yt-dlp 2023.10.13, installed using Python 3.11.5
  These apps are now globally available
    - yt-dlp
done! ✨ 🌟 ✨

Now I am able to run yt-dlp again from the command line and from my batch files. However, I am unable to run it from Media-Downloader. So I installed the latest media-downloader-3.4.0-8.4.x86_64 from the Tumbleweed repo to see if that made a difference.

What was installed in /usr/bin/ by pipx is not an executable. It is a python script that looks like this:

`#!/usr/bin/python3.11
# EASY-INSTALL-ENTRY-SCRIPT: 'yt-dlp==2023.10.13','console_scripts','yt-dlp'
import re
import sys

# for compatibility with easy_install; see #2198
__requires__ = 'yt-dlp==2023.10.13'

try:
    from importlib.metadata import distribution
except ImportError:
    try:
        from importlib_metadata import distribution
    except ImportError:
        from pkg_resources import load_entry_point

def importlib_load_entry_point(spec, group, name):
    dist_name, _, _ = spec.partition('==')
    matches = (
        entry_point
        for entry_point in distribution(dist_name).entry_points
        if entry_point.group == group and entry_point.name == name
    )
    return next(matches).load()

globals().setdefault('load_entry_point', importlib_load_entry_point)

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(load_entry_point('yt-dlp==2023.10.13', 'console_scripts', 'yt-dlp')())`

When I run media-downloader --debug, I get this output:

[media-downloader] *************************************************************
[media-downloader] To Disable These Checks, Do The Following:-
[media-downloader] 1. Go To "Configure" Tab.
[media-downloader] 2. Go To "General Options" Sub Tab.
[media-downloader] 3. Uncheck "Show Version Info When Starting".
[media-downloader] *************************************************************
[media-downloader] Download Path: /Data2/Work
[media-downloader] App Data Path: /home/rhack/.local/share/media-downloader
[media-downloader] *************************************************************
[media-downloader] Checking installed version of yt-dlp
[media-downloader] cmd: "/usr/bin/python3" "/home/rhack/.local/share/media-downloader/bin/yt-dlp" "--version"
[media-downloader] Found version: 2023.07.06
[media-downloader] Checking installed version of ffmpeg
[media-downloader] cmd: "/usr/bin/ffmpeg" "-version"
[media-downloader] Found version: 6.0
[media-downloader] Checking installed version of aria2c
[media-downloader] cmd: "/usr/bin/aria2c" "--version"
[media-downloader] Found version: 1.36.0
[media-downloader] Checking installed version of python3
[media-downloader] cmd: "/usr/bin/python3" "--version"
[media-downloader] Found version: 3.11.5

It's looking in /home/rhack/.local/share/media-downloader/bin for yt-dlp, but that is the old version script for version 2023-07-06. If I replace that script with the script in /usr/local/bin, which is the new script installed yesterday by the Tumbleweed update, and then run Media-Downloader --debug, I get this output:

[media-downloader] 3. Uncheck "Show Version Info When Starting".
[media-downloader] *************************************************************
[media-downloader] Download Path: /Data2/Work
[media-downloader] App Data Path: /home/rhack/.local/share/media-downloader
[media-downloader] *************************************************************
[media-downloader] Checking installed version of yt-dlp
[media-downloader] cmd: "/usr/bin/python3" "/home/rhack/.local/share/media-downloader/bin/yt-dlp" "--version"
[media-downloader] Failed to find version information, make sure "yt-dlp" is installed and works properly
[media-downloader] Checking installed version of ffmpeg
[media-downloader] cmd: "/usr/bin/ffmpeg" "-version"
[media-downloader] Found version: 6.0
[media-downloader] Checking installed version of aria2c
[media-downloader] cmd: "/usr/bin/aria2c" "--version"
[media-downloader] Found version: 1.36.0
[media-downloader] Checking installed version of python3
[media-downloader] cmd: "/usr/bin/python3" "--version"
[media-downloader] Found version: 3.11.5

Apparently Media-Downloader can not read the new script version which does not contain the yt-dlp version information in it or at least in a manner readable by what Media-Downloader is looking for.

What do I need to do to get Media-Downloader to run the yt-dlp Python script which has been installed in Tumbleweed?

mhogomchungu commented 8 months ago

What do you get when you run the following command from the terminal

"/usr/bin/python3" "/home/rhack/.local/share/media-downloader/bin/yt-dlp" "--version"
richardstevenhack commented 8 months ago

I get the earlier version - which is the version installed in /home/rhack/.local/share/media-downloader/bin.

rhack@localhost:/Data2/Work> "/usr/bin/python3" "/home/rhack/.local/share/media-downloader/bin/yt-dlp" "--version" 2023.07.06

That's actually fortunate, since the old version still works. But I can't run the new yt-dlp from there because Media-Downloader can't for some reason understand that python script. And I can't run the current official yt-dlp executable from there, as that won't run under the current Tumbleweed snapshot.

So I'm stuck running the old 2023.07.06 version.

mhogomchungu commented 8 months ago

[media-downloader] Checking installed version of yt-dlp [media-downloader] cmd: "/usr/bin/python3" "/home/rhack/.local/share/media-downloader/bin/yt-dlp" "--version" [media-downloader] Failed to find version information, make sure "yt-dlp" is installed and works properly

If it works when you run it outside of Media Downloader then it should work when you run it inside Media Downloader and the difference maybe with "/usr/bin/python3" option in the above output, remove it and try again.

richardstevenhack commented 8 months ago

I already did that. I altered the JSON file to remove the call to python3. I can run yt-dlp from the command line with no problem but Media-Downloader still can't detect the version and won't run the new script.

The version that runs from "/home/rhack/.local/share/media-downloader/bin/yt-dlp is the OLD version of yt-dlp. Media-Downloader can't run the NEW version. If I move the new version from /usr/bin to /home/rhack/.local/share/media-downloader/bin/, Media Downloader gives me the "can't detect" message.

Here's the current Engines file from /usr/local/share (I ignored the X86 part, just changed the amd64 part):

`{
    "BackendPath": "${default}",
    "BatchFileArgument": "-a",
    "CanDownloadPlaylist": true,
    "Cmd": {
        "Generic": {
            "amd64": {
                "Args": [
                      "yt-dlp"
                ],
                "Name": "yt-dlp"
            },
            "x86": {
                "Args": [
                     "python3","yt-dlp"
                ],
                "Name": "yt-dlp"
            }
        },
        "Windows": {
            "amd64": {
                "Args": [
                    "yt-dlp.exe"
                ],
                "Name": "yt-dlp.exe"
            },
            "x86": {
                "Args": [
                    "yt-dlp_x86.exe"
                ],
                "Name": "yt-dlp_x86.exe"
            }
        }
    },
    "ControlJsonStructure": {
        "Connector": "&&",
        "lhs": {
            "startsWith": "[download]"
        },
        "rhs": {
            "contains": "ETA"
        }
    },
    "CookieArgument": "--cookies",
    "DefaultCommentsCmdOptions": [
        "--get-comments",
        "--no-download",
        "--print",
        "{\"title\":%(title)j,\"comments\":%(comments)j}"
    ],
    "DefaultDownLoadCmdOptions": [
        "--newline",
        "--ignore-config",
        "--no-playlist",
        "-o",
        "%(title)s.%(ext)s"
    ],
    "DefaultListCmdOptions": [
        "--print",
        "%(formats)j"
    ],
    "DefaultSubstitlesCmdOptions": [
        "--no-download",
        "--print",
        "{\"title\":%(title)j,\"automatic_captions\":%(automatic_captions)j,\"subtitles\":%(subtitles)j}"
    ],
    "DefaultSubtitleDownloadOptions": [
        "--embed-subs"
    ],
    "DownloadUrl": "https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest",
    "LikeYoutubeDl": true,
    "Name": "yt-dlp",
    "OptionsArgument": "-f",
    "PlaylistItemsArgument": "--playlist-items",
    "RemoveText": [
    ],
    "ReplaceOutputWithProgressReport": false,
    "RequiredMinimumVersionOfMediaDownloader": "2.2.0",
    "SkipLineWithText": [
        "(pass -k to keep)"
    ],
    "SplitLinesBy": [
        "\n"
    ],
    "VersionArgument": "--version",
    "VersionStringLine": 0,
    "VersionStringPosition": 0
}

When I run Media-Downloader with that setup, it only runs the old yt-dlp script from /home/rhack/.local/share/media-downloader/bin/. It doesn't run the new system-wide yt-dlp script from /usr/bin. Replacing the old version with the new version of the yt-dlp script gives me the "can't detect version" message.

The old script from /home/rhack/.local/share/media-downloader/bin/ is a binary when I open it in a text editor. The new script from /usr/bin is a text file:

#!/usr/bin/python3.11
# EASY-INSTALL-ENTRY-SCRIPT: 'yt-dlp==2023.10.13','console_scripts','yt-dlp'
import re
import sys

# for compatibility with easy_install; see #2198
__requires__ = 'yt-dlp==2023.10.13'

try:
    from importlib.metadata import distribution
except ImportError:
    try:
        from importlib_metadata import distribution
    except ImportError:
        from pkg_resources import load_entry_point

def importlib_load_entry_point(spec, group, name):
    dist_name, _, _ = spec.partition('==')
    matches = (
        entry_point
        for entry_point in distribution(dist_name).entry_points
        if entry_point.group == group and entry_point.name == name
    )
    return next(matches).load()

globals().setdefault('load_entry_point', importlib_load_entry_point)

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(load_entry_point('yt-dlp==2023.10.13', 'console_scripts', 'yt-dlp')())

This is what runs when I run yt-dlp from the command line. It points to yt-dlp which was installed by pipx as shown here:

rhack@localhost:/Data2/Work> pipx list venvs are in /home/rhack/.local/pipx/venvs apps are exposed on your $PATH at /home/rhack/.local/bin package yt-dlp 2023.10.13, installed using Python 3.11.5

/home/rhack/.local/bin has a text script file called yt-dlp in it which looks like this:

!/home/rhack/.local/pipx/venvs/yt-dlp/bin/python

-- coding: utf-8 --

import re import sys from yt_dlp import main if name == 'main': sys.argv[0] = re.sub(r'(-script.pyw|.exe)?$', '', sys.argv[0]) sys.exit(main())

Which is presumably calling the main yt-dlp python script.

It also has a 5.5mb file in it called "g" - which is an executable (presumably the yt-dlp executable.)

HOLD ON! I JUST FIXED IT!

It occurred to me after reading the above that the the yt-dlp script and the file "g" in /home/rhack/.local/bin are the actual yt-dlp executable broken out into two pieces for some unknown reason. So I got the bright idea of backing up and removing the old yt-dlp script from /home/rhack/.local/share/media-downloader/bin/ and then copying those two files into the /home/rhack/.local/share/media-downloader/bin/ folder.

So now one set of those two files is in /home/rhack/local/bin for global use by the system command line and my own scripts elsewhere, and one copy of those two files is in /home/rhack/.local/share/media-downloader/bin/ for use by Media-Downloader.

THAT WORKED! Now when I run Media-Downloader, it identifies the version of yt-dlp as 2023-10-13! And I can download videos again!

You know what I think you should do? You should create a flatpak or an AppImage which would isolate Media-Downloader's version of yt-dlp from the system version. You'd have to update it every time yt-dlp changes, but you probably have to do that anyway.

More and more I'm discovering that on a rolling distro like openSUSE Tumbleweed, the only to protect externally installed packages not directly supported by openSUSE is to use either AppImages or Flatpaks. I've had several programs busted in the last two weeks by Tumbleweed updates. It's a royal PITA.

So I think we can close this out. That was one complicated mess to sort out! I'll be keeping this bug report saved in my Media-Downloader folder to remember it in case something similar happens again.

mhogomchungu commented 8 months ago

I am glad you found the solution to the problem.

Recent versions of Media Downloader do not use system installed executables for executables it can auto download and it install them at "/home/rhack/.local/share/media-downloader/bin/ in your case.

There is an open issue that tracks creating AppImages or Flatpaks and i will revisit the issue at some point in the future.

https://github.com/mhogomchungu/media-downloader/issues/81