firsttris / plugin.video.sendtokodi

:tv: plays various stream sites on kodi using youtube-dl
MIT License
125 stars 28 forks source link

fix crash with multiple entries #67

Closed mlichvar closed 2 years ago

mlichvar commented 2 years ago

After updating to LibreELEC 10 (using Kodi 19 and python3) sendtokodi seems to be crashing on URLs that generate multiple streams.

This commit fixes the issue for me. I have no idea if the fix is correct or complete.

nullket commented 2 years ago

Can you please also provide a URL which was not working for you in the first place and also a log with such a crash would be super helpful. The result should be a list already… we might need to check this in more detail why your changes are actually necessary in the first place.

mlichvar commented 2 years ago

It seems to be triggered by anything with multiple streams or a playlist. Here is an example if you need a URL:

https://www.youtube.com/playlist?list=PLvOlSehNtuHuvHE5GQrQJxWXHdmW2l5IF

The kodi log:

2022-07-09 15:46:02.680 T:1432    ERROR <general>: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
                                                    - NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
                                                   Error Type: <class 'AttributeError'>
                                                   Error Contents: 'tuple' object has no attribute 'pop'
                                                   Traceback (most recent call last):
                                                     File "/storage/.kodi/addons/plugin.video.sendtokodi/service.py", line 186, in <module>
                                                       startingEntry = unresolvedEntries.pop(indexToStartAt)
                                                   AttributeError: 'tuple' object has no attribute 'pop'
                                                   -->End of Python script error report<--                                                   

The issue with missing title seems unrelated and should probably have a separate PR. I'll remove it from the commit.

nullket commented 2 years ago

Thanks for the contribution! While you fix will not hurt anyone, I want to understand why it does not work for you in the first place. @anohren this section was added by you, have you encountered tuples during implementation?

The result['entries'] and thus also the unresolvedEntries should be a list already and not a tuple like in your traceback. At least in my tests it was always a list and within the extractor code it also seems to be a list generated here

Which version of the plugin were you running? Did you use use yt_dlp or youtube_dl to resolve the streams (in python3 installations go to the addon settings in kodi). Please test it with both an report back as I can not reproduce this error.
To be sure, can you also add the following in the not-fixed version at around line 186 to see what type it really is

print(f"The the result['entries'] var is of type {type(result['entries'])} while the unresolvedEntries var is of type {type(unresolvedEntries)}")

It could also be helpful if you create a little new python script within the .../addons/plugin.video.sendtokodi folder and execute it with you system python installation (simply call it with python scriptname.py from the terminal) to make sure your yt_dlp version works correct.

from yt_dlp import YoutubeDL

url="https://www.youtube.com/playlist?list=PLvOlSehNtuHuvHE5GQrQJxWXHdmW2l5IF"
ydl_opts = {'format': 'best', 'extract_flat': 'in_playlist'}
ydl = YoutubeDL(ydl_opts)
ydl.add_default_info_extractors()
result = ydl.extract_info(url, download=False)
unresolvedEntries = list(result['entries'])

print("The unresolvedEntries var is of type {}".format(type(unresolvedEntries)))

print("Lets try to pop an element (only possible with lists)")
print(unresolvedEntries.pop(0))
anohren commented 2 years ago

I want to understand why it does not work for you in the first place. @anohren this section was added by you, have you encountered tuples during implementation?

No, i didn't come across this. Can't recreate it with the link.

Easiest way would be to look at how the YouTube resolver assembles the list when we know whether it's yt-dlp or not, but to me it just looks like python being python (you'll get some type — you're welcome) or someone going "it's a playlist, but there are only a few items so we'll get better performance with a tuple" or something. Maybe some new syntactic sugar, or maybe it's the library that thinks this doesn't matter.

mlichvar commented 2 years ago

The version of the installed addon was 0.9.211. It was resolving with yt-dlp. Changing to youtube-dl didn't help.

The output from the added line was:

The the result['entries'] var is of type <class 'tuple'> while the unresolvedEntries var is of type <class 'tuple'>

and the script (after changing the import to lib.yt_dlp):

[youtube:tab] PLvOlSehNtuHuvHE5GQrQJxWXHdmW2l5IF: Downloading webpage
[youtube:tab] PLvOlSehNtuHuvHE5GQrQJxWXHdmW2l5IF: Downloading API JSON with unavailable videos
[download] Downloading playlist: Calculators
[youtube:tab] Playlist Calculators: Downloading 1 videos of 1
[download] Downloading video 1 of 1
[download] Finished downloading playlist: Calculators
The unresolvedEntries var is of type <class 'list'>
Lets try to pop an element (only possible with lists)
{'_type': 'url', 'ie_key': 'Youtube', 'id': 'S3R4r2xvVYQ', 'url': 'https://www.youtube.com/watch?v=S3R4r2xvVYQ', 'title': 'EEVblog 1479 - Is Your Calculator WRONG?', 'description': None, 'duration': 1066.0, 'view_count': None, 'uploader': 'EEVblog', 'channel_id': 'UC2DjFE7Xf11URZqWBigcVOQ', 'thumbnails': [{'url': 'https://i.ytimg.com/vi/S3R4r2xvVYQ/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC2ZW-UUXJGrtHphT2E53pFafr-1g', 'height': 94, 'width': 168}, {'url': 'https://i.ytimg.com/vi/S3R4r2xvVYQ/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD9QEJUkVb2VdJDpGODupZ3mQZhSQ', 'height': 110, 'width': 196}, {'url': 'https://i.ytimg.com/vi/S3R4r2xvVYQ/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDyeqv2bK5qwnw6FygQ1LwglEE52Q', 'height': 138, 'width': 246}, {'url': 'https://i.ytimg.com/vi/S3R4r2xvVYQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCf2fs2WfyqGD9f_IqVrKti0QBmWQ', 'height': 188, 'width': 336}], 'upload_date': None, 'live_status': None, 'release_timestamp': None, 'availability': None, '__x_forwarded_for_ip': None}

While changing the configuration, I noticed there is an upgrade available. After upgrading to 0.9.215 it no longer crashes. In the git diff I didn't see anything interesting. I downgraded to 0.9.211 and it's crashing again.

So, whatever this was it's fixed now?

mlichvar commented 2 years ago

Hm, no, that would be too easy. After upgrading to 0.9.215 again it's still crashing.

Is it possible there is a delay in the yt-dlp vs youtube-dl configuration change becoming effective?

nullket commented 2 years ago

is it possible there is a delay in the yt-dlp vs youtube-dl configuration change becoming effective?

what do you mean? How did you notice any delay? There shouldn‘t be one.

The output from the added line was:

The the result['entries'] var is of type <class 'tuple'> while the unresolvedEntries var is of type <class 'tuple'>

and the script (after changing the import to lib.yt_dlp):

So it seems like the issue comes from the python version used by openelec (Kodi users a built in minimal python version instead of the system python). Your system python states that it is a list while when executing in Kodi it states as a tuple. Really strange.

Anyway, I will merge your PR, even if we do not know what the problem really is, as your fix will not hurt in any way.