parent
9d50d205ec
commit
7cb41f8018
|
@ -1,3 +1,6 @@
|
|||
## 1.9.10
|
||||
- Close #139: Implement Channel.subscribersCount.
|
||||
|
||||
## 1.9.9
|
||||
- Fix issue #134 (Error when getting the hls manifest from a livestream)
|
||||
|
||||
|
|
|
@ -16,8 +16,11 @@ class Channel with EquatableMixin {
|
|||
/// URL of the channel's logo image.
|
||||
final String logoUrl;
|
||||
|
||||
/// The (approximate) channel subscriber's count.
|
||||
final int? subscribersCount;
|
||||
|
||||
/// Initializes an instance of [Channel]
|
||||
Channel(this.id, this.title, this.logoUrl);
|
||||
Channel(this.id, this.title, this.logoUrl, this.subscribersCount);
|
||||
|
||||
@override
|
||||
String toString() => 'Channel ($title)';
|
||||
|
|
|
@ -30,7 +30,8 @@ class ChannelClient {
|
|||
id = ChannelId.fromString(id);
|
||||
var channelPage = await ChannelPage.get(_httpClient, id.value);
|
||||
|
||||
return Channel(id, channelPage.channelTitle, channelPage.channelLogoUrl);
|
||||
return Channel(id, channelPage.channelTitle, channelPage.channelLogoUrl,
|
||||
channelPage.subscribersCount);
|
||||
}
|
||||
|
||||
/// Gets the metadata associated with the channel of the specified user.
|
||||
|
@ -42,7 +43,7 @@ class ChannelClient {
|
|||
var channelPage =
|
||||
await ChannelPage.getByUsername(_httpClient, username.value);
|
||||
return Channel(ChannelId(channelPage.channelId), channelPage.channelTitle,
|
||||
channelPage.channelLogoUrl);
|
||||
channelPage.channelLogoUrl, channelPage.subscribersCount);
|
||||
}
|
||||
|
||||
/// Gets the info found on a YouTube Channel About page.
|
||||
|
|
|
@ -31,6 +31,22 @@ class ChannelPage {
|
|||
_root.querySelector('meta[property="og:image"]')?.attributes['content'] ??
|
||||
'';
|
||||
|
||||
int? get subscribersCount => initialData.subscribersCount;
|
||||
|
||||
///
|
||||
late final _InitialData initialData = _getInitialData();
|
||||
|
||||
_InitialData _getInitialData() {
|
||||
final scriptText = _root
|
||||
.querySelectorAll('script')
|
||||
.map((e) => e.text)
|
||||
.toList(growable: false);
|
||||
return scriptText.extractGenericData(
|
||||
(obj) => _InitialData(obj),
|
||||
() => TransientFailureException(
|
||||
'Failed to retrieve initial data from the channel about page, please report this to the project GitHub page.'));
|
||||
}
|
||||
|
||||
///
|
||||
ChannelPage(this._root);
|
||||
|
||||
|
@ -68,3 +84,50 @@ class ChannelPage {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
class _InitialData {
|
||||
static final RegExp _subCountExp = RegExp(r'(\d+(?:\.\d+)?)(K|M|\s)');
|
||||
|
||||
// Json parsed map
|
||||
final Map<String, dynamic> root;
|
||||
|
||||
_InitialData(this.root);
|
||||
|
||||
int? get subscribersCount {
|
||||
final renderer = root.get('header')?.get('c4TabbedHeaderRenderer');
|
||||
if (renderer?['subscriberCountText'] == null) {
|
||||
return null;
|
||||
}
|
||||
final subText =
|
||||
renderer?.get('subscriberCountText')?.getT<String>('simpleText');
|
||||
if (subText == null) {
|
||||
return null;
|
||||
}
|
||||
final match = _subCountExp.firstMatch(subText);
|
||||
if (match == null) {
|
||||
return null;
|
||||
}
|
||||
if (match.groupCount != 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final count = double.tryParse(match.group(1) ?? '');
|
||||
if (count == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final multiplierText = match.group(2);
|
||||
if (multiplierText == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var multiplier = 1;
|
||||
if (multiplierText == 'K') {
|
||||
multiplier = 1000;
|
||||
} else if (multiplierText == 'M') {
|
||||
multiplier = 1000000;
|
||||
}
|
||||
|
||||
return (count * multiplier).toInt();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: youtube_explode_dart
|
||||
description: A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key.
|
||||
version: 1.9.9
|
||||
version: 1.9.10
|
||||
|
||||
homepage: https://github.com/Hexer10/youtube_explode_dart
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ void main() {
|
|||
expect(channel.title, 'Tyrrrz');
|
||||
expect(channel.logoUrl, isNotEmpty);
|
||||
expect(channel.logoUrl, isNot(equalsIgnoringWhitespace('')));
|
||||
expect(channel.subscribersCount, greaterThanOrEqualTo(190));
|
||||
});
|
||||
|
||||
group('Get metadata of any channel', () {
|
||||
|
|
Loading…
Reference in New Issue