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

plugins.joqrag: new plugin #5648

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

Conversation

pzhlkj6612
Copy link
Contributor

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).

Copy link
Member

@bastimeyer bastimeyer left a 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.

Comment on lines 42 to 43
validate.regex(re.compile(r"""var\s+Program_name\s*=\s*["\']([^"\']+)["\']""")),
validate.none_or_all(
Copy link
Member

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:

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.

Copy link
Contributor Author

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 return None ...

You mean re.Pattern.search() ?

validate.regex raises a ValidationError when there's no match:

Yes, I know that.


So... how do I play with validate.regex() ?

Copy link
Contributor Author

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 .

),
)
if self.title == "放送休止":
raise NoStreamsError
Copy link
Member

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.

m3u8_url = self.session.http.get(
self._URL_PLAYER,
schema=validate.Schema(
validate.regex(re.compile(r"""<source\s[^>]*\bsrc="([^"]+)"\s*""")),
Copy link
Member

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.

Comment on lines 3 to 7
$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/
Copy link
Member

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.

Comment on lines 26 to 29
@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)/"))
Copy link
Member

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.

from streamlink.stream.hls import HLSStream


log = logging.getLogger(__name__)
Copy link
Member

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.

@pzhlkj6612
Copy link
Contributor Author

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

  1. Sites which don't provide any video streaming content, eg. radio stations

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.

@bastimeyer
Copy link
Member

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
https://www.uniqueradio.jp/agapps/hls/cdn.m3u8

pzhlkj6612 and others added 3 commits November 2, 2023 22:55
Co-Authored-By: bastimeyer <mail@bastimeyer.de>
Co-Authored-By: bastimeyer <mail@bastimeyer.de>
Co-Authored-By: bastimeyer <mail@bastimeyer.de>
@pzhlkj6612
Copy link
Contributor Author

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.

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.

Apart from that, the stream URL seems to be static, namely https://www.uniqueradio.jp/agapps/hls/cdn.m3u8

I know that, but they seem to have changed the URL multiple times:

https://www.uniqueradio.jp/agplayer5/hls/mbr-0.m3u8
https://www.uniqueradio.jp/agplayer5/hls/mbr-1.m3u8
https://www.uniqueradio.jp/agplayer5/hls/mbr-2.m3u8
https://www.uniqueradio.jp/agplayer5/hls/mbr-3.m3u8
https://www.uniqueradio.jp/agplayer5/hls/mbr-4.m3u8
https://www.uniqueradio.jp/agplayer5/hls/mbr-ff.m3u8
https://www.uniqueradio.jp/agplayer5/hls/mbr-0-cdn.m3u8
https://www.uniqueradio.jp/agplayer5/hls/mbr-1-cdn.m3u8

cdn.m3u8 is the latest version.

@blackdan-team-leader
Copy link

blackdan-team-leader commented Nov 22, 2023

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.

@pzhlkj6612 pzhlkj6612 marked this pull request as draft November 28, 2023 14:57
@pzhlkj6612
Copy link
Contributor Author

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.


[1] 新サイトオープン!旧サイト(agqr.jp) と並行稼働中!!! | 文化放送

@pzhlkj6612 pzhlkj6612 marked this pull request as ready for review December 19, 2023 13:24
@pzhlkj6612
Copy link
Contributor Author

Hi, @bastimeyer. Is there any chance to merge this PR? What should I do for it? Thank you.

@bastimeyer
Copy link
Member

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 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:

$ streamlink -l none --stdout 'https://www.uniqueradio.jp/agapps/hls/cdn.m3u8' best 2>/dev/null \
  | ffprobe -v error -of json -show_streams - \
  | jq '.streams[] | select(.codec_type == "video") | {width: .width, height: .height, fps: .avg_frame_rate}'
{
  "width": 320,
  "height": 180,
  "fps": "10/1"
}

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:
https://github.com/streamlink/streamlink/blob/6.7.2/CONTRIBUTING.md#plugin-requests

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.

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

Successfully merging this pull request may close these issues.

None yet

3 participants