bunny_video_player 0.1.4
bunny_video_player: ^0.1.4 copied to clipboard
Flutter video player for Bunny.net with signed/tokenized HLS/MP4 and full control from Dart. Android and iOS.
bunny_video_player #
A Flutter plugin for Bunny Stream playback with native rendering on Android and iOS.
- Android: Bunny Stream Android player integration
- iOS: AVPlayer-based native implementation
- Robust Native -> Dart and Dart -> Native communication
- PiP, lifecycle handling, playback events, source switching
Supported Platforms #
- Android
- iOS
Features #
- Native platform view rendering (
BunnyVideoView) - Controller API (
BunnyVideoController) - Playback controls: play, pause, seek, speed, volume, looping
- Picture in Picture (Android/iOS)
- Signed URL refresh
- Configurable control colors (track, buffered, background, icon)
- Real-time streams:
- playback state
- position
- buffered position
- errors
- PiP mode state
- Runtime Android control layout tuning from Dart
Requirements #
- Flutter
>=3.22.0 - Dart
>=3.0.0 <4.0.0 - Android
minSdk 26 - iOS
12.0+
Installation #
Add dependency:
dependencies:
bunny_video_player: ^0.1.4
Then run:
flutter pub get
Platform Setup #
Android #
PiP support in your app AndroidManifest.xml activity:
<activity
android:name=".MainActivity"
android:supportsPictureInPicture="true"
android:resizeableActivity="true"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" />
iOS #
For background playback/PiP behavior, enable audio background mode in Info.plist:
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
Example App Secret Handling #
Do not hardcode production Bunny credentials in source control.
Run the example with a runtime define:
flutter run \
--dart-define=BUNNY_LIBRARY_ID=your_library_id \
--dart-define=BUNNY_VIDEO_ID=your_video_id \
--dart-define=BUNNY_ACCESS_KEY=your_access_key
Quick Start #
import 'package:bunny_video_player/bunny_video_player.dart';
final controller = BunnyVideoController(playerId: 0);
await controller.initialize(
libraryId: 'your-library-id',
videoId: 'your-video-id',
accessKey: 'your-access-key',
autoPlay: false,
looping: false,
allowBackgroundPlayback: true,
);
Render native view:
BunnyVideoView(
playerId: 0,
config: const BunnyPlayerViewConfig(),
)
Controller API #
await controller.play();
await controller.pause();
await controller.seekTo(const Duration(seconds: 10));
await controller.setPlaybackSpeed(1.25);
await controller.setVolume(0.8);
await controller.setLooping(true);
await controller.enterPictureInPicture();
await controller.exitPictureInPicture();
await controller.refreshSignedUrl('https://...');
await controller.dispose();
Switch to another video source on same controller:
await controller.switchSource(
libraryId: '596670',
videoId: 'another-video-id',
accessKey: 'your-access-key',
keepPlaybackState: true,
);
Event Streams #
controller.playbackStateStream.listen((state) {});
controller.positionStream.listen((position) {});
controller.bufferedStream.listen((buffered) {});
controller.errorStream.listen((message) {});
controller.pipModeStream.listen((isInPip) {});
BunnyPlaybackState values:
idleloadingreadyplayingpausedbufferingcompletederror
View Configuration #
BunnyPlayerViewConfig supports:
useHybridCompositioneagerGestureHandlingapplyWhiteIconsshowFullscreenButtonshowSettingsButtonkeepScreenOnplayerBackgroundColorArgbcontrolsTintColorArgbcontrolsScrimColorArgbcontrolsTrackColorArgbcontrolsBufferedColorArgbcontrolsBackgroundColorArgbcontrolsIconColorArgbcontrolsIconVerticalPaddingDpcontrolsTextVerticalPaddingDpcontrolsLeadingSpaceDpprogressBarTranslationDpprogressBarBottomMarginDpiosShowsPlaybackControls
Custom Color Config (from code) #
These color fields are ARGB integers (0xAARRGGBB) and are applied on Android/iOS + overlay controls:
playerBackgroundColorArgb: video surface background.controlsScrimColorArgb: overlay gradient/scrim color.controlsTintColorArgb: base fallback color for controls.controlsTrackColorArgb: played/seek track color.controlsBufferedColorArgb: buffered stream color.controlsBackgroundColorArgb: unplayed track/background color.controlsIconColorArgb: icon tint color.
Fallback behavior used in code:
- If
controlsTrackColorArgbis null,controlsTintColorArgbis used. - If
controlsBufferedColorArgbis null, it uses track color at35%alpha. - If
controlsBackgroundColorArgbis null, it uses track color at25%alpha. - If
controlsIconColorArgbis null, it uses track color.
Example:
const BunnyVideoView(
config: BunnyPlayerViewConfig(
playerBackgroundColorArgb: 0xFF000000,
controlsTintColorArgb: 0xFFFFFFFF,
controlsScrimColorArgb: 0xB3000000,
applyWhiteIcons: true,
controlsTrackColorArgb: 0xFFFFFFFF,
controlsBufferedColorArgb: 0x66FFFFFF,
controlsBackgroundColorArgb: 0x33000000,
controlsIconColorArgb: 0xFFFFFFFF,
controlsIconVerticalPaddingDp: 3,
controlsTextVerticalPaddingDp: 3,
controlsLeadingSpaceDp: 1,
progressBarTranslationDp: 8,
progressBarBottomMarginDp: -3,
),
)
Error Notes #
A Bunny API 404 Not Found means the video is not available for the provided:
libraryIdvideoIdaccessKey
Validate all three before playback.
Publishing #
See PUBLISHING.md for release and pub.dev publish steps.
License #
MIT