0 purchases
dart holodex api
A thin unofficial Dart client for Holodex API v2.
Table of Contents #
Getting started
Usage
Get a video by its ID
Get a list of videos
Get a list of live videos
Get a channel by its ID
Get a list of channels
Quickly Access Live / Upcoming for a set of Channels
Get Videos Related To Channel
Get Clips of a VTuber
Get Collabs that mention a VTuber
Get Videos From Channel
Get a single Video's metadata
Search For Videos
Search For Videos With a Comment
Testing with Coverage
Additional information
Getting started #
Get an API key at holodex.net, instructions here
Add this package your pubspec.yaml file
Run dart pub get or flutter pub get.
Usage #
Full example.
Get an instance of HolodexClient with your API key
final holodexClient = HolodexClient(apiKey: apiKey);
copied to clipboard
Remember to close the client when you are done with it, this closes the internal http client.
Failing to close it can cause the Dart process to hang.
holodexClient.close();
copied to clipboard
Get a video by its ID #
Get a video by its video ID, alias of getVideos
Arguments:
videoId The video ID as a string
includes Request extra data be included in the results. They are not guarenteed to be returned.
// Get one video and print it
final VideoFull video = await holodexClient.getVideoById(
'Gx_GPwpyLxw',
includes: [
Includes.channelStats,
Includes.clips,
// Includes.description,
Includes.liveInfo,
Includes.mentions,
Includes.refers,
Includes.simulcasts,
Includes.songs,
Includes.sources,
],
);
print('Requested Video: ${video.toString()}');
copied to clipboard
Get a list of videos #
Arguments:
filter Filter the results returns by the Holodex API /videos endpoint
// Get a bunch of videos and print them
final videoFilter = VideoFilter(
// channelId: 'UCsYcCwDqv6Sg8KMIIMF54SA', // Kiriku Translation
includes: <Includes>[
Includes.channelStats,
Includes.clips,
// Includes.description,
Includes.liveInfo,
Includes.mentions,
Includes.refers,
Includes.simulcasts,
Includes.songs,
Includes.sources,
],
languages: <Language>[Language.all],
limit: 50,
maxUpcomingHours: 1000,
// mentionedChannelId: 'UCDqI2jOz0weumE8s7paEk6g', // Roboco
offset: 50,
order: Order.descending,
// organization: Organization.Hololive,
paginated: true,
sort: <VideoSort>[VideoSort.availableAt],
status: <VideoStatus>[VideoStatus.past],
// Videos of type VideoType.clip cannot not have topic. Streams may or may not have topic.
// topicId: 'singing',
// type: VideoType.stream,
);
final PaginatedVideos videoList = await holodexClient.getVideos(videoFilter);
print('Videos: ${videoList.items.length}');
print('Total Videos: ${videoList.total}');
copied to clipboard
Get a list of live videos #
This is somewhat similar to calling getVideos, except this endpoint imposes default values on the query parameters. You can choose to override them by providing your own values.
final liveVideoFilter = VideoFilter(includes: [Includes.channelStats]);
final PaginatedVideos liveVideos = await holodexClient.getLiveVideos(liveVideoFilter);
print('Live videos: ${liveVideos.items.length}\n');
copied to clipboard
Get a channel by its ID #
Returns Channel
Arguments:
filter Filter the results returns by the API
final Channel ceresFauna = await holodexClient.getChannelById('UCO_aKKYxn4tvrqPjcTzZ6EQ');
print('Requested Channel Name: ${ceresFauna.name}\n');
copied to clipboard
Get a list of channels #
Arguments:
filter Filter the results returns by the API
final channelFilter = const ChannelFilter(
limit: 25,
offset: 0,
order: Order.ascending,
organization: Organization.AtelierLive,
sort: [ChannelSort.organization],
);
final List<Channel> channels = await holodexClient.getChannels(channelFilter);
print('Atelier Live Channels: ${channels.length}\n');
copied to clipboard
Quickly Access Live / Upcoming for a set of Channels #
This endpoint is similar to the getLiveVideos method and usually replies much faster. It is more friendly in general. The cost to execute a lookup is significantly cheaper. It's unfortunately less customizable as a result.
Holodex recommends using this if you have a fixed set of channel IDs to look up status for.
Arguments:
channelIds List of channel IDs to get the live videos from.
final List<Video> quickLiveVideos = await holodexClient.getLiveVideosFromChannelsQuickly([
'UCQ0UDLQCjY0rmuxCDE38FGg', // Matsuri
'UCZlDXzGoo7d44bwdNObFacg', // Kanata
'UCqm3BQLlJfvkTsX_hvm0UmA' // Watame
]);
print('Requested Live Videos From Channels: ${quickLiveVideos.length}\n');
copied to clipboard
Get Videos Related To Channel #
A simplified method for access channel specific data. If you want more customization, the same result can be obtained by calling the [getVideos] method.
Arguments
channelId ID of the Youtube Channel that is being queried
type The type of video resource to fetch. Clips finds clip videos of a vtuber channel, Video finds the channelId channel's uploads, and collabs finds videos uploaded by other channels that mention the channelId
filter Filter the results returns by the API
final PaginatedResult<VideoFull> matsuriClips = await holodexClient.getVideosRelatedToChannel(
'UCQ0UDLQCjY0rmuxCDE38FGg', // Matsuri
type: VideoSearchType.clips
);
print('Clips including Matsuri: ${matsuriClips.total}');
print('Returned clips including Matsuri: ${matsuriClips.videos.length}');
copied to clipboard
Get Clips of a VTuber #
Alias of getChannelRelatedVideos
Arguments:
channelId ID of the Youtube Channel that is being queried
filter Filter the results returns by the API
final PaginatedVideos matsuriClips2 = await holodexClient.getVTuberClips(
'UCQ0UDLQCjY0rmuxCDE38FGg', // Matsuri
);
print('Clips including Matsuri: ${matsuriClips2.total}');
print('Returned clips including Matsuri: ${matsuriClips2.items.length}\n');
copied to clipboard
Get Collabs that mention a VTuber #
Alias of getChannelRelatedVideos
Arguments:
channelId ID of the Youtube Channel that is being queried
filter Filter the results returns by the API
final PaginatedVideos matsuriCollabs = await holodexClient.getVTuberCollabs('UCQ0UDLQCjY0rmuxCDE38FGg');
print('Collabs including Matsuri: ${matsuriCollabs.total}');
print('Returned collabs including Matsuri: ${matsuriCollabs.items.length}\n');
copied to clipboard
Get Videos From Channel #
Alias of getChannelRelatedVideos
Arguments:
channelId ID of the Youtube Channel that is being queried
filter Filter the results returns by the API
final PaginatedVideos matsuriUploads = await holodexClient.getChannelVideos('UCQ0UDLQCjY0rmuxCDE38FGg');
print('Total Matsuri uploads: ${matsuriUploads.total}');
print('Returned uploads: ${matsuriUploads.items.length}\n');
copied to clipboard
Get a single Video's metadata #
Retrieves a video, optionally with comments and recommended videos.
Arguments:
videoId ID of the video
includeTimestampComments If set to true, comments with timestamps will be returned
filterRecommendationLanguages Retrieves recommended videos if not empty. This is a list of language codes to filter channels/clips, official streams do not follow this parameter.
final VideoFull shionSingingStream = await holodexClient.getVideoMetadata(
'eJJuy5rY57w', // Shion's singing stream
includeTimestampComments: true,
filterRecommendationLanguages: [Language.all],
);
final List<Comment> timestampComments = shionSingingStream.comments;
final List<Video> recommendations = shionSingingStream.recommendations;
print('Songs: ${shionSingingStream.songcount}');
print('Video Comments With Timestamps: ${timestampComments.length}');
print('Video Recommendations: ${recommendations.length}\n');
copied to clipboard
Search For Videos #
Flexible endpoint to search for videos fulfilling multiple conditions.
Descriptions with "any" implies an OR condition, and "all" implies an AND condition. Note that searching for topics and clips is not supported, because clips do not contain topics.
Arguments:
conditions Match all of the items. -> For each item: look for the text in video title or description
filter Filter video results from the API
final singingSearchFilter = SearchFilter(
sort: SearchSort.newest,
languages: [Language.all],
targets: [SearchTarget.clip, SearchTarget.stream],
topics: ['singing'],
videoChannels: <String>[],
organizations: [
Organization.Hololive,
Organization.Nijisanji,
],
paginated: true,
offset: 0,
limit: 25,
);
final PaginatedVideos searchVideos = await holodexClient.searchVideos(
conditions: ['karaoke'],
filter: singingSearchFilter,
);
print('Videos Found: ${searchVideos.items.length}\n');
copied to clipboard
Search For Videos With a Comment #
Flexible endpoint to search for comments in videos fulfilling multiple conditions. Descriptions with "any" implies an OR condition, and "all" implies an AND condition. Note that searching for topics and clips is not supported, because clips do not contain topics.
Arguments:
comment Find videos with comments containing specified string (case insensitive)
filter Filter video results from the API
final singingSearchFilter = SearchFilter(
sort: SearchSort.newest,
languages: [Language.all],
targets: [SearchTarget.clip, SearchTarget.stream],
topics: ['singing'],
videoChannels: <String>[],
organizations: [
Organization.Hololive,
Organization.Nijisanji,
],
paginated: true,
offset: 0,
limit: 25,
);
final PaginatedVideos searchComments = await holodexClient.searchComments(
comment: 'shion',
filter: singingSearchFilter,
);
print('Videos with Comment: ${searchComments.items.length}\n');
copied to clipboard
Testing with Coverage #
Generating code coverage:
Activate the coverage package
dart pub global activate coverage
copied to clipboard
Run the tests with coverage
dart pub global run coverage:test_with_coverage --branch-coverage --function-coverage
copied to clipboard
Visualize the coverage with an extension such as
Coverage Gutters
Additional information #
Read the official API documentation here
Visit Holodex.net
Some parts of this package was inspired by the C#
and Rust implementations of the API.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.