▶️ youtube_shorts: A package for displaying youtube shorts.
A vertical youtube shorts player. You can choose what shorts will be displayed by passing a list of shorts url's or by passing a channel name. Under the hood the package is using youtube_explode_dart to get youtube video info and media_kit as the player for videos.
🗂️ Summary
- ⦿ Configurations and native permissions
- ⦿ Basic how to use
- ⦿ Video manipulation
- ⦿ Player manipulation
Configurations and native permissions
Since the package uses media_kit as it's video player engine, the native configurations of this package are the same configurations of media_kit package. Click here to access the media_kit package native configuration. Please do the configurations for the platforms you pretend to use.
That configurations also includes calling MediaKit.ensureInitialized();
in the main function. Please check documentation.
After macking the configuration, use package:permission_handler
to request access at runtime:
if (/* Android 13 or higher. */) {
// Video permissions.
if (await Permission.videos.isDenied || await Permission.videos.isPermanentlyDenied) {
final state = await Permission.videos.request();
if (!state.isGranted) {
await SystemNavigator.pop();
}
}
// Audio permissions.
if (await Permission.audio.isDenied || await Permission.audio.isPermanentlyDenied) {
final state = await Permission.audio.request();
if (!state.isGranted) {
await SystemNavigator.pop();
}
}
} else {
if (await Permission.storage.isDenied || await Permission.storage.isPermanentlyDenied) {
final state = await Permission.storage.request();
if (!state.isGranted) {
await SystemNavigator.pop();
}
}
}
Basic how to use
First, you will need to create a VideosSourceController
that will controll all the video source. There are two constructor of the source controller. From a list of url or from the channel name. Examples are bellow:
- By list of youtube url's (example):
You can check a complete implementation of this constructor by clicking here. But bellow is a more short right to the point example:
late final ShortsController controller;
@override
void initState() {
super.initState();
controller = ShortsController(
youtubeVideoInfoService: VideosSourceController.fromUrlList(
videoIds: [
'https://www.youtube.com/shorts/PiWJWfzVwjU',
'https://www.youtube.com/shorts/AeZ3dmC676c',
'https://www.youtube.com/shorts/L1lg_lxUxfw',
'https://www.youtube.com/shorts/OWPsdhLHK7c',
...
],
),
);
}
- By channel name (example):
You can check a complete implementation of this constructor by clicking here. But bellow is a more short right to the point example:
late final ShortsController controller;
@override
void initState() {
super.initState();
controller = ShortsController(
youtubeVideoInfoService: VideosSourceController.fromYoutubeChannel(
channelName: 'fcbarcelona',
),
);
}
Shorts page use (minimal example):
Now, we need too add the widget that shows the shorts and will use the controller we just created.
@override
Widget build(BuildContext context) {
return ShortsPage(
controller: controller,
);
}
Don't forget to dispose the controller after closing the page.
@override
void dispose() {
controller.dispose();
super.dispose();
}
Don't forget to check out the examples of "by url list" and "by channel name" implementations.
Video manipulation
Controll the current/focussed player
You can manipulate the player of the current video that is focused (in screen). Bellow are the methods of manipulation
final ShortsController controller = ShortsController(...);
controller.playCurrentVideo(); // Will play if paused
controller.pauseCurrentVideo(); // Will pause if playing
controller.muteCurrentVideo(); // Will mute (set volume to 0)
controller.setVolume(50); // 50% of the volume (0 - 100)
Set autoplay
final ShortsController controller = ShortsController(
startWithAutoplay: false, // Default is true
...
);
Set if videos will be played in loop
final ShortsController controller = ShortsController(
videosWillBeInLoop: false, // Default is true
...
);
Player manipulation
Disable/enable default controllers
Some default controllers are in the player (time control, pause/play etc). Those are the media_kit default player controllers. If you wan't to desable/enable them you can controll that by boolean the variable willHaveDefaultShortsControllers
. This is usefull if you wan't to implement your own controllers.
@override
Widget build(BuildContext context) {
willHaveDefaultShortsControllers: false, // No more default controllers on video.
return ShortsPage(
controller: controller,
);
}
Create a overlay above the player
This is usefull if you want to display something like controllers or more.
@override
Widget build(BuildContext context) {
return ShortsPage(
controller: controller,
overlayWidgetBuilder: (
int index,
PageController pageController,
VideoController videoController,
Video videoData,
MuxedStreamInfo info,
) {
// Example of something you may want to return (this widget bellow does not exist)
return MyCustomDoubleTapToPauseOverlayWidget(
...
);
}
);
}
Set loading widget
You can display a widget that will be shown while the video is loading.
@override
Widget build(BuildContext context) {
return ShortsPage(
controller: controller,
loadingWidget: Center(
child: MyCustomCoolLoadingIndicator(),
)
);
}
Set error widget
You can display a widget that will be shown when a error occours while fetching a video. You will have a error and probably a stacktrace also (can be null).
@override
Widget build(BuildContext context) {
return ShortsPage(
controller: controller,
errorWidget: (error, stackTrace) {
return Center(
child: MyCustomCoolError(error, stackTrace),
);
},
);
}
Video builder
videoBuilder
parameter is for macking a wrapper in the player. Of if you can't to have a specific controll of the videoController of each player and wan't to make a controll of it here. child
parameter is the default video widget that is displayed when you don't pass a videoBuilder
. You can use it or not; for example, if you wan't to build your player from scratch, you won't use the child parameter. But if you just want to make a "wrapper" above the player, use this.
@override
Widget build(BuildContext context) {
return ShortsPage(
controller: controller,
videoBuilder: (
int index,
PageController pageController,
VideoController videoController,
Video videoData,
MuxedStreamInfo hostedVideoInfo,
Widget child,
) {
return Container(
padding: EdgeInsets.all(30),
child: child,
);
},
);
}
Made with ❤ by Igor Miranda
If you like the package, give a 👍
Libraries
- youtube_explode_fork/src/channels/channel
- youtube_explode_fork/src/channels/channel_about
- youtube_explode_fork/src/channels/channel_client
- youtube_explode_fork/src/channels/channel_handle
- youtube_explode_fork/src/channels/channel_id
- youtube_explode_fork/src/channels/channel_link
- youtube_explode_fork/src/channels/channel_uploads_list
- youtube_explode_fork/src/channels/channel_video
- youtube_explode_fork/src/channels/username
- youtube_explode_fork/src/channels/video_sorting
- youtube_explode_fork/src/channels/video_type
- youtube_explode_fork/src/common/base_paged_list
- youtube_explode_fork/src/common/common
- youtube_explode_fork/src/common/engagement
- youtube_explode_fork/src/common/thumbnail
- youtube_explode_fork/src/common/thumbnail_set
- youtube_explode_fork/src/exceptions/exceptions
- youtube_explode_fork/src/exceptions/fatal_failure_exception
- youtube_explode_fork/src/exceptions/http_client_closed
- youtube_explode_fork/src/exceptions/request_limit_exceeded_exception
- youtube_explode_fork/src/exceptions/search_item_section_exception
- youtube_explode_fork/src/exceptions/transient_failure_exception
- youtube_explode_fork/src/exceptions/video_requires_purchase_exception
- youtube_explode_fork/src/exceptions/video_unplayable_exception
- youtube_explode_fork/src/exceptions/youtube_explode_exception
- youtube_explode_fork/src/extensions/helpers_extension
- youtube_explode_fork/src/playlists/playlist
- youtube_explode_fork/src/playlists/playlist_client
- youtube_explode_fork/src/playlists/playlist_id
- youtube_explode_fork/src/retry
- youtube_explode_fork/src/reverse_engineering/cipher/cipher_manifest
- youtube_explode_fork/src/reverse_engineering/cipher/cipher_operations
- youtube_explode_fork/src/reverse_engineering/clients/closed_caption_client
- youtube_explode_fork/src/reverse_engineering/clients/comments_client
- youtube_explode_fork/src/reverse_engineering/dash_manifest
- youtube_explode_fork/src/reverse_engineering/heuristics
- youtube_explode_fork/src/reverse_engineering/models/fragment
- youtube_explode_fork/src/reverse_engineering/models/initial_data
- youtube_explode_fork/src/reverse_engineering/models/stream_info_provider
- youtube_explode_fork/src/reverse_engineering/models/youtube_page
- youtube_explode_fork/src/reverse_engineering/pages/channel_about_page
- youtube_explode_fork/src/reverse_engineering/pages/channel_page
- youtube_explode_fork/src/reverse_engineering/pages/channel_upload_page
- youtube_explode_fork/src/reverse_engineering/pages/player_config_base
- youtube_explode_fork/src/reverse_engineering/pages/playlist_page
- youtube_explode_fork/src/reverse_engineering/pages/search_page
- youtube_explode_fork/src/reverse_engineering/pages/watch_page
- youtube_explode_fork/src/reverse_engineering/player/player_response
- youtube_explode_fork/src/reverse_engineering/player/player_source
- youtube_explode_fork/src/reverse_engineering/youtube_http_client
- youtube_explode_fork/src/search/search_client
- youtube_explode_fork/src/search/search_filter
- youtube_explode_fork/src/search/search_list
- youtube_explode_fork/src/search/search_query
- youtube_explode_fork/src/search/search_result
- youtube_explode_fork/src/videos/closed_captions/closed_caption
- youtube_explode_fork/src/videos/closed_captions/closed_caption_client
- youtube_explode_fork/src/videos/closed_captions/closed_caption_format
- youtube_explode_fork/src/videos/closed_captions/closed_caption_manifest
- youtube_explode_fork/src/videos/closed_captions/closed_caption_part
- youtube_explode_fork/src/videos/closed_captions/closed_caption_track
- youtube_explode_fork/src/videos/closed_captions/closed_caption_track_info
- youtube_explode_fork/src/videos/closed_captions/closed_captions
- youtube_explode_fork/src/videos/closed_captions/language
- youtube_explode_fork/src/videos/comments/comment
- youtube_explode_fork/src/videos/comments/comments
- youtube_explode_fork/src/videos/comments/comments_client
- youtube_explode_fork/src/videos/comments/comments_list
- youtube_explode_fork/src/videos/streams/audio_only_stream_info
- youtube_explode_fork/src/videos/streams/audio_stream_info
- youtube_explode_fork/src/videos/streams/bitrate
- youtube_explode_fork/src/videos/streams/filesize
- youtube_explode_fork/src/videos/streams/framerate
- youtube_explode_fork/src/videos/streams/muxed_stream_info
- youtube_explode_fork/src/videos/streams/stream_client
- youtube_explode_fork/src/videos/streams/stream_container
- youtube_explode_fork/src/videos/streams/stream_context
- youtube_explode_fork/src/videos/streams/stream_controller
- youtube_explode_fork/src/videos/streams/stream_info
- youtube_explode_fork/src/videos/streams/stream_manifest
- youtube_explode_fork/src/videos/streams/streams
- youtube_explode_fork/src/videos/streams/video_only_stream_info
- youtube_explode_fork/src/videos/streams/video_quality
- youtube_explode_fork/src/videos/streams/video_resolution
- youtube_explode_fork/src/videos/streams/video_stream_info
- youtube_explode_fork/src/videos/video
- youtube_explode_fork/src/videos/video_client
- youtube_explode_fork/src/videos/video_controller
- youtube_explode_fork/src/videos/video_id
- youtube_explode_fork/src/youtube_explode_base
- youtube_explode_fork/youtube_explode_dart
- Provides all the APIs implemented by this library.
- youtube_shorts
- youtube_explode_fork/src/channels/channels Channels
- APIs related to YouTube channels.
- youtube_explode_fork/src/playlists/playlists Playlists
- APIs related to YouTube playlists.
- youtube_explode_fork/src/search/search Search
- APIs related to YouTube search queries.
- youtube_explode_fork/src/videos/videos Videos
- APIs related to YouTube videos.