firsttris / plugin.video.sendtokodi

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

Remove advertisement prefixes from URL string #54

Open mrXoo opened 2 years ago

mrXoo commented 2 years ago

I posted this before but can't find my post.

Ive just started using your addon on ios. It works well, however one of the apps im using (GSE iptv) has a share iptv link. When I send the IPTV channel link to your app to send to Kodi it sends it but does not play the stream because the link I get from GSE is "Shared with GSE USA Entertainment http://xyz.com/etc If I go in and edit the link manully to http://xyz.com/etc it plays fine. Wondering if there is a way to ignore all the stuff before the http://

nullket commented 2 years ago

If I understand correctly the sharing action in your app just prefixes this "shared with ..." string to the URL?.

We could fix this with a regex in the paramstring parsing. Something like ^.*?(http). In the next days I might not have time to actually do this as I would need build up a test environment to make sure it does not break any other links.

mrXoo commented 2 years ago

Awesome thanks. Sorry I didn’t get back to you. I just seen this. Will test it and report back.

mrXoo commented 2 years ago

Yes did test but maybe that was not included in the update. mid tou like post the line(S) of code and I can test.

nullket commented 2 years ago

You can try the following

Pleas report back how/if it works.

mrXoo commented 2 years ago

Well that nearly works.

If i take out all the spaces in for example below it works

gse iptv canada hbo http:// now reads

gseiptvcanadahbohttp:// then it works.

if you need a log then i can get you one

nullket commented 2 years ago

Yes you are correct. The issue is that the plugin gets a single string as an argument when it is called (by kodi due to the app sending something). The python argv[2] object looks something like

shared with abc http://url.com/ {"ydlOpts":{}}

Our getParam() function simply takes that string and assumes that the first element must be the URL and the second element the youtube-dl options. Obviously in the example above the url value would be set to "shared" while the youtube-dl options would be set to "with". Both parameters are wrong and will crash the plugin.

On one side we could create a new getParam() which guesses the parameters from the string (like getting the url by finding http or finding the youtube-dl Options by looking for that "ydlOpts" substring enclosed in curly brackets.

On the other side it would be much cleaner to encode the arguments properly (if we want to keep with positional arguments) like suggested here https://github.com/firsttris/plugin.video.sendtokodi/issues/29. This would actually require changes to the app (percent encode the parameters). I know other apps/extensions are using this plugin as a backend as well so we should find a solution which would not break them. I am not sure but it seems like trying to decode a not percent-encoded string (like we would get from other apps) should not break anything:

import urllib.parse
# This would need to happen within the app:
orig_string= "shared with whitespace prefix https://www.youtube.com/watch?v=BaW_jenozKc"
encoded_string = urllib.parse.quote(orig_string.encode('utf8')) # send that to the plugin 

# This would need to happen within the plugin:
# lets assume we got the encoded string from a new version of the ios app 
print(urllib.parse.unquote(encoded_string))
# prints: shared with whitespace prefix https://www.youtube.com/watch?v=BaW_jenozKc

# lets assume another app was sending in the current way (would not be encoded) 
print(urllib.parse.unquote(orig_string))
# prints: shared with whitespace prefix https://www.youtube.com/watch?v=BaW_jenozKc

Of course the url and the ydlOpts should not be encoded together (to still have the white-space between them to identify the position of each argument). This will eliminate the additional advantage of the percent encoding for transportation (like mentioned in https://github.com/firsttris/plugin.video.sendtokodi/issues/29).

A third option would be to use keyword arguments (and still encode the url in the app).

@firsttris this would require changes in the app, whats your opinion on this?

anohren commented 2 years ago

Ive just started using your addon on ios. It works well, however one of the apps im using (GSE iptv) has a share iptv link.

To me it sounds like the iOS app you're using should expose an additional data item specifically for a URL type in addition to the plain text type that it appears to use. Haven't looked into it lately but I'd guess the types of the activityItems passed to https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622019-init controls the possible actions for the shared item.

Or, alternatively, the SendToKodi iOS app's share extension is erroneously accepting plain text as input, when it should only accept URLs. But this is a tricky point since technically you don't need an URL to play a video, just a video identifier, which could be any arbitrary string (e.g. the last part of a Youtube URL is enough for youtube-dl to play Youtube videos). Though it shouldn't hurt to restrict it to URLs anyway.

This will eliminate the additional advantage of the percent encoding for transportation (like mentioned in #29).

I found this a bit hard to follow. What does "eliminate an advantage" mean here? Is it good or bad?

I still say that it'd be an advantage to use proper percent encoding for all additional parameters. The "complications before the parameters reach the plugin" doesn't refer to encoding/escaping characters, but rather with that I have a horrible suspicion that Kodi attempts to helpfully convert all \ into / depending on platform... regardless of where they appear in the argument (think e.g. the youtube-dl option format=best[height<=720]/best which currently wasn't possible to send as part of the request without workarounds, last time I tried).

But, when do we even use backslashes? When / gets JSON encoded into \/, which is valid JSON. Here's my comment in the iOS app:

optionsString = optionsString.replacingOccurrences(of: #"\/"#, with: "/") // necessary hack because SendToKodi plugin does not receive (i.e. url decode) additional data ("ydlOpts" json) in a safe way, whereby Kodi promptly "helps" us by flipping all '\' into '/' on linux/unix systems, since they most likely consider the json object part of the url path component. That also prevents us from letting users add arbitrary youtube-dl options.
anohren commented 2 years ago

On the other side it would be much cleaner to encode the arguments properly (if we want to keep with positional arguments) like suggested here #29.

Oh and by the way, I don't recommend keeping positional arguments. I've always imagined fixing that issue by using properly escaped and named query parameters. I think it's pretty clear that Kodi basically expects the argument to be a single URL (why else does it touch the backslashes?), and who knows what Kodi will do with unescaped spaces in the future...

I say we either accept the breakage, or alternatively treat all arguments with an unescaped space in them the old way, and otherwise expect all additional options to be query parameters.