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

On Linux, use the system yt-dlp if available instead of embedded #103

Open
ilikenwf opened this issue Feb 24, 2024 · 7 comments
Open

On Linux, use the system yt-dlp if available instead of embedded #103

ilikenwf opened this issue Feb 24, 2024 · 7 comments

Comments

@ilikenwf
Copy link

I use Arch and use the -git builds of yt-dlp. As such, it's more up to date with fixes for cloudflare streams and the like. I suggest that you determine if yt-dlp exists within the system python, and if it does, use that instead of the one embedded with the plugin.

@ilikenwf
Copy link
Author

ilikenwf commented Feb 24, 2024

...that or pull in the current yt-dlp master and test to see if you can get cloudflarestream URIs to playback?

It works in yt-dlp itself but not sendtokodi.

https://watch.cloudflarestream.com/2463f6d3e06fa29710a337f5f5389fd8/iframe/?autoplay\=true\&letterboxColor\=transparent

https://customer-aw5py76sw8wyqzmh.cloudflarestream.com/2463f6d3e06fa29710a337f5f5389fd8/iframe

@nullket
Copy link
Collaborator

nullket commented Feb 25, 2024

The plugin is updated once day with the upstream yt_dlp master branch. If there were changes a new plugin version is released and should be automatically updated in your Kodi instance. So we might be even faster than arch ;)?

https://github.com/firsttris/plugin.video.sendtokodi/commits?author=github-actions%5Bbot%5D

I have no experience in that but I assume that it is not possible to import a system wide installed python module in an embedded python environment (I simply don’t know!)?

@anohren
Copy link
Collaborator

anohren commented Aug 10, 2024

@nullket I have a working prototype of using external yt-dlp, which enables use of yt-dlp even on Kodi versions constrained to Python 2. I wanted to ask whether you think it's a good idea to expose a setting for users to specify the path manually?

This is not done by importing Python modules (which wouldn't work on Python 2 anyway), but by parsing command output from a working executable. Nevertheless, it was implemented in about three lines of code, so it's very easy on the eyes.

Just wanted a second opinion before adding the boring bits (e.g. addon settings).

@iBenMoore
Copy link

@nullket I have a working prototype of using external yt-dlp, which enables use of yt-dlp even on Kodi versions constrained to Python 2. I wanted to ask whether you think it's a good idea to expose a setting for users to specify the path manually?

This is not done by importing Python modules (which wouldn't work on Python 2 anyway), but by parsing command output from a working executable. Nevertheless, it was implemented in about three lines of code, so it's very easy on the eyes.

Just wanted a second opinion before adding the boring bits (e.g. addon settings).

I'd be interested in seeing how this works @anohren . This addon won't work with Kodi Windows builds as yt-dlp bumped it's minver of python to 3.9 and Kodi doesn't plan on upping from 3.8 any time soon, so being able to point to an external yt-dlp executable would be useful.

@anohren
Copy link
Collaborator

anohren commented Feb 6, 2025

Sure, if I can find it then I can post a simple search/replace snippet here in a comment. That'd be the quickest way to get you up and running again without waiting for this addon to incorporate this (questionable) change.

After that you only have to make sure the addon isn't accidentally updated, either from within Kodi (maybe just disable the repo?) or in the OS.

@anohren
Copy link
Collaborator

anohren commented Feb 6, 2025

Found it.

Near the end of the addon's service.py replace everything between with and except:

with ydl:
    progress = xbmcgui.DialogProgressBG()
    progress.create("Resolving " + url)
    try:
        ytDlpPath = "/absolute/path/to/yt-dlp"
        if ytDlpPath != None:
            import subprocess
            jsonString = subprocess.check_output([ytDlpPath, "-J", "--format=" + ydl_opts['format'], "--flat-playlist", url])
            result = json.loads(jsonString)
        else:
            result = ydl.extract_info(url, download=False)
    except:

Note that I don't know if the command line options look identical for yt-dlp on Windows, so customize as needed.

Haven't used this lately but at least troubleshooting should be easier when you can call the same yt-dlp command externally and see what it spits out.

@iBenMoore
Copy link

Thanks @anohren , I was able to get this working with your example. A few more lines of code needed to be updated/commented out to make sure no attempts are made to access the yt-dlp included python code, and I threw in something to hide the yt-dlp.exe console window from popping up in front of Kodi as well. Seems to work pretty well now. Here's my version of the section that needs commenting/updating:

# Use the chosen resolver while forcing to use youtube_dl on legacy python 2 systems (dlp is python 3.6+)
#if xbmcplugin.getSetting(int(sys.argv[1]),"resolver") == "0" or sys.version_info[0] == 2:
#    from lib.youtube_dl import YoutubeDL
#else:
#    from lib.yt_dlp import YoutubeDL
    
# patch broken strptime (see above)
patch_strptime()

# extract_flat:  Do not resolve URLs, return the immediate result.
#                Pass in 'in_playlist' to only show this behavior for
#                playlist items.
ydl_opts = {
    'format': 'best',
    'extract_flat': 'in_playlist'
}

params = getParams()
url = str(params['url'])
ydl_opts.update(params['ydlOpts'])
if xbmcplugin.getSetting(int(sys.argv[1]),"usemanifest") == 'true':
    ydl_opts['format'] = 'bestvideo*+bestaudio/best'
#ydl = YoutubeDL(ydl_opts)
#ydl.add_default_info_extractors()

#with ydl:
    #progress = xbmcgui.DialogProgressBG()
    #progress.create("Resolving " + url)
    #try:
    #    result = ydl.extract_info(url, download=False)
progress = xbmcgui.DialogProgressBG()
progress.create("Resolving " + url)
try:
    ytDlpPath = "D:\your\path\to\yt-dlp.exe"
    if ytDlpPath != None:
        import subprocess
        jsonString = subprocess.check_output([ytDlpPath, "-J", "--format=" + ydl_opts['format'], "--flat-playlist", url], creationflags = subprocess.CREATE_NO_WINDOW)
        result = json.loads(jsonString)
    #else:
    #    result = ydl.extract_info(url, download=False)
except:

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

No branches or pull requests

4 participants