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
plugins.joqrag: new plugin #5648
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR.
I can't find any content on this site at all right now. According to Google translate, the next broadcast starts at 4pm local time, in about 8 hours from now.
Japanese Internet radio
Sorry, but if this is audio content only, then we're not going to merge this plugin into master. Please see the plugin request guidelines in the contributing docs before opening pull requests:
https://github.com/streamlink/streamlink/blob/6.3.1/CONTRIBUTING.md#plugin-requests
7. Sites which don't provide any video streaming content, eg. radio stations
Let me still give you a quick review for your plugin implementation.
src/streamlink/plugins/joqrag.py
Outdated
validate.regex(re.compile(r"""var\s+Program_name\s*=\s*["\']([^"\']+)["\']""")), | ||
validate.none_or_all( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validate.regex
raises a ValidationError
when there's no match:
- https://github.com/streamlink/streamlink/blob/6.3.1/src/streamlink/plugin/api/validate/_schemas.py#L66-L69
- https://github.com/streamlink/streamlink/blob/6.3.1/src/streamlink/plugin/api/validate/_validate.py#L215-L238
A re.Pattern
object on its own however can return None
, hence the validate.none_or_all(all_schema)
in the validation schema patterns you can find in other plugins.
I'll have a look at adding some documentation for the validation package at some point in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't follow.
A
re.Pattern
object on its own however can returnNone
...
You mean re.Pattern.search()
?
validate.regex
raises aValidationError
when there's no match:
Yes, I know that.
So... how do I play with validate.regex()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I got it! Fixed in 78ac49a .
src/streamlink/plugins/joqrag.py
Outdated
), | ||
) | ||
if self.title == "放送休止": | ||
raise NoStreamsError |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just return None
here. NoStreamsError
is only useful in nested function calls where there can't be a None
return value.
src/streamlink/plugins/joqrag.py
Outdated
m3u8_url = self.session.http.get( | ||
self._URL_PLAYER, | ||
schema=validate.Schema( | ||
validate.regex(re.compile(r"""<source\s[^>]*\bsrc="([^"]+)"\s*""")), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HTML should never get parsed using a regex. That's what validate.parse_html()
and validate.xml_xpath...()
are for.
Since you're using validate.regex()
, the validation schema can't return None
, but that's an unintended side-effect of the misuse of validate.regex()
. So if you were to change that, you'd have to add a check for m3u8_url is None
.
src/streamlink/plugins/joqrag.py
Outdated
$url www.uniqueradio.jp/agplayer5/player.php | ||
$url www.uniqueradio.jp/agplayer5/inc-player-hls.php | ||
$url www.joqr.co.jp/ag/ | ||
$url www.joqr.co.jp/qr/agdailyprogram/ | ||
$url www.joqr.co.jp/qr/agregularprogram/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Full URLs with paths are not meant to be included in the plugin metadata. Only in cases where it explicitly makes sense. Check the plugins list in the docs.
src/streamlink/plugins/joqrag.py
Outdated
@pluginmatcher(re.compile(r"https?://www\.uniqueradio\.jp/agplayer5/player\.php")) | ||
@pluginmatcher(re.compile(r"https?://www\.uniqueradio\.jp/agplayer5/inc-player-hls\.php")) | ||
@pluginmatcher(re.compile(r"https?://(?:www\.)?joqr\.co\.jp/ag/")) | ||
@pluginmatcher(re.compile(r"https?://(?:www\.)?joqr\.co\.jp/qr/(?:agdailyprogram|agregularprogram)/")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The matchers for each hostname could/should be merged if there are only minor diffs in the path. Otherwise a new re.Pattern.match()
call needs to be made for each matcher by the session's plugin resolver.
src/streamlink/plugins/joqrag.py
Outdated
from streamlink.stream.hls import HLSStream | ||
|
||
|
||
log = logging.getLogger(__name__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The plugin is not logging anything, so creating a new logger object is unnecessary.
My bad, I didn't mention that this site provides video during the broadcast (a type of visual radio). Please translate its Japanese Wikipedia page into English and search the "video" word: 超!A&G+ - Wikipedia And I'll make changes based on your review later, thank you in advance. |
I've checked a couple of times now, and it's just a 320x180@10fps "video" with a bitrate of 160 kbit/s that either shows a static image or a spinning logo animation. That doesn't count as a video stream in my books and merging this would very much bend the plugin inclusion rules. Apart from that, the stream URL seems to be static, namely |
Co-Authored-By: bastimeyer <mail@bastimeyer.de>
Co-Authored-By: bastimeyer <mail@bastimeyer.de>
Co-Authored-By: bastimeyer <mail@bastimeyer.de>
Well, it's indeed a low-quality video stream, but I don't think that it should be considered as a radio. I'd like to show you two videos which were recorded by someone (Japanese):
The above two videos are from the program "鷲崎健のヨルナイト×ヨルナイト | 文化放送" on "Super! A&G+". There is really a real-time video stream. Audiences are able to see the host and guests. That is, not all programs on this site provide videos.
I know that, but they seem to have changed the URL multiple times:
|
Hello. This plugin is named "joqrag", how about changing it to "agqr"? There are some users who have been watching "Super! A&G+ (超!A&G+)" since the URL of the old portal site was "agqr.jp" (archived data before the site renewal around 2021) and also use "#agqr" when they post reactions on X (Twitter). I think "joqrag" is a little confusing when people report problems with plugin. |
Hi, @blackdan-team-leader ! Thanks for your suggestion. I know "agqr" is the old name of "Super! A&G+". However, the new site is over 2.5 years old [1] and the old domain https://agqr.jp/ redirects to the new site, so I think we should use the new name in the new code. Sorry. I've added "AGQR" to the description in 88c3f7f , so we can find it easier on the internet. |
Hi, @bastimeyer. Is there any chance to merge this PR? What should I do for it? Thank you. |
That hasn't changed apart from the fact that it's currently two people sitting in front of their microphones, with the same 90s era video quality:
The videos you had linked earlier were hosted on a different site, which is irrelevant. Radio station streams are still prohibited via the plugin request rules: However, with the recent implementation of lazy-plugin-loading, some of the rules could be changed now IMO. Apart from maintenance concerns, there's no reason to limit the number of plugins anymore. The fear I have though when changing the plugin rules is that if we lift some of the restrictions that we'd get tons of requests for all kinds of content that's currently not allowed. These rules were added because some people started requesting plugin after plugin without even the slightest intention of contributing plugin code. They weren't even using the sites themselves and probably just requested something they found on Google after searching for similar sites. This flooded the issue tracker with lots of nonsense requests. On the other hand, if someone actually submits a new plugin for a new "niche" site, then there's the chance that those plugins will never be touched again by any maintainer here and the person who's submitted the plugin won't fix any issues that will come up in the future either. Figuring out which plugin is broken and which is not is practically impossible, which means we'd include lots of (more) dead code in Streamlink's plugins. So with this being said, I'm going to open a new issue later today, so we can discuss plugin rule changes first. |
Hi!
This is an extractor for Japanese Internet radio "Super! A&G+ (超!A&G+)" operated by Nippon Cultural Broadcasting (JOQR).
The program list is at 今日の番組表(A&G+) | 文化放送 (in JST timezone).
Please do not to be confused with Radiko (radiko.py).