zhabby_shorts 0.0.2 copy "zhabby_shorts: ^0.0.2" to clipboard
zhabby_shorts: ^0.0.2 copied to clipboard

Shorts for Flutter.

Zhabby Shorts #

A high-performance Flutter plugin for TikTok-style short video feeds with HLS streaming support, adaptive video fitting, and thumbnail preview capabilities.

Features #

  • 🎥 HLS Streaming: Full support for HTTP Live Streaming (HLS) with adaptive bitrate
  • 📱 TikTok-style Feed: Vertical scrolling video feed optimized for mobile
  • 🖼️ Thumbnail Support: Show custom thumbnails with fade animations while videos load
  • 📐 Adaptive Video Fitting: Multiple fitting modes (contain, cover, fill) that adapt to video dimensions
  • Performance Optimized: Video preloading, texture pooling, and smooth transitions
  • 🔄 Auto-loop: Seamless video looping capabilities
  • 📊 Rich Callbacks: Detailed playback state tracking and debugging information
  • 🎮 Gesture Support: Built-in tap handling and custom gesture support
  • 🚀 Memory Efficient: Intelligent resource management and cleanup

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  zhabby_shorts: ^1.0.0

Then run:

flutter pub get

Quick Start #

1. Basic Setup #

import 'package:zhabby_shorts/zhabby_shorts.dart';

class VideoFeedScreen extends StatefulWidget {
  @override
  State<VideoFeedScreen> createState() => _VideoFeedScreenState();
}

class _VideoFeedScreenState extends State<VideoFeedScreen> {
  late final ShortsPlayerController _player;
  
  final List<String> _videoUrls = [
    'https://example.com/video1.m3u8',
    'https://example.com/video2.m3u8',
    'https://example.com/video3.m3u8',
  ];

  @override
  void initState() {
    super.initState();
    _player = ShortsPlayerController();
    _initializePlayer();
  }

  Future<void> _initializePlayer() async {
    await _player.init();
    await _player.appendUrls(0, _videoUrls);
    await _player.setLooping(true);
    
    // Prime first few videos for smooth playback
    for (int i = 0; i < 3 && i < _videoUrls.length; i++) {
      await _player.attach(i);
      await _player.prime(i);
    }
    
    // Start playing first video
    if (_videoUrls.isNotEmpty) {
      await _player.switchTo(0);
    }
  }

  @override
  void dispose() {
    _player.release();
    super.dispose();
  }
}

2. Using AdaptiveVideoFeedPlayer #

PageView.builder(
  scrollDirection: Axis.vertical,
  onPageChanged: (index) async {
    await _player.switchTo(index);
  },
  itemCount: _videoUrls.length,
  itemBuilder: (context, index) {
    return AdaptiveVideoFeedPlayer(
      index: index,
      controller: _player,
      isActive: _currentIndex == index,
      fit: VideoFit.cover, // or VideoFit.contain, VideoFit.fill
      showDebugInfo: false,
      onTap: () {
        // Handle tap events
      },
    );
  },
)

3. Adding Thumbnails #

// Set video URLs with thumbnails
for (int i = 0; i < _videoUrls.length; i++) {
  await _player.setUrl(i, _videoUrls[i], 
    thumbnailUrl: 'https://example.com/thumb$i.jpg');
}

// Or use AdaptiveVideoPlayer directly with thumbnail
AdaptiveVideoPlayer(
  index: index,
  controller: _player,
  thumbnailUrl: 'https://example.com/thumbnail.jpg',
  fit: VideoFit.cover,
  showDebugInfo: true,
)

API Reference #

ShortsPlayerController #

The main controller class for managing video playback.

Core Methods

// Initialize the player
Future<void> init()

// Add video URLs to the player
Future<void> appendUrls(int startIndex, List<String> urls)

// Set video URL for a specific index (with optional thumbnail)
Future<void> setUrl(int index, String url, {String? thumbnailUrl})

// Switch to and play a specific video
Future<void> switchTo(int index)

// Attach texture for rendering
Future<int> attach(int index)

// Prime video for faster startup
Future<void> prime(int index)

// Playback control
Future<void> play()
Future<void> pause()
Future<void> togglePlayPause()

// Configuration
Future<void> setLooping(bool enabled)
Future<void> setVolume(double volume) // 0.0 to 1.0
Future<void> setMuted(bool enabled)
Future<void> setProgressTracking({bool enabled = true, int? intervalMs})

// Resource management
Future<void> release()
Future<void> disposeIndex(int index)

State Access

// Get video status for specific index
VideoStatus? getVideoStatus(int index)

// Get detailed player state
PlayerStateInfo? getPlayerState(int index)

// Get current active index
int? get activeIndex

// Get playback info
Map<String, dynamic>? get currentPlaybackInfo

AdaptiveVideoPlayer #

A widget that automatically adapts to video dimensions and aspect ratios.

AdaptiveVideoPlayer({
  required int index,
  required ShortsPlayerController controller,
  VideoFit fit = VideoFit.contain,
  Color backgroundColor = Colors.black,
  Widget? loadingWidget,
  Widget? errorWidget,
  bool showDebugInfo = false,
  String? thumbnailUrl,
  Function(int index, double width, double height, double aspectRatio)? onDimensionsChanged,
  Function(int index, String state)? onStateChanged,
})

AdaptiveVideoFeedPlayer #

Specialized widget for vertical feeds (like TikTok).

AdaptiveVideoFeedPlayer({
  required int index,
  required ShortsPlayerController controller,
  required bool isActive,
  VideoFit fit = VideoFit.cover,
  bool showDebugInfo = false,
  VoidCallback? onTap,
})

VideoFit Modes #

  • VideoFit.contain: Maintain aspect ratio, fit entirely within bounds (letterbox/pillarbox)
  • VideoFit.cover: Maintain aspect ratio, fill bounds completely (crop if necessary)
  • VideoFit.fill: Fill bounds exactly, may distort aspect ratio

Advanced Usage #

Performance Optimization #

// Prewarm adjacent videos for smooth scrolling
await _player.prewarm(next: nextIndex, prev: prevIndex);

// Configure video quality for adaptive streaming
await _player.setQuality(
  peakBps: 2000000, // 2 Mbps
  maxWidth: 1080,
  maxHeight: 1920,
);

// Enable progress tracking with custom interval
await _player.setProgressTracking(
  enabled: true,
  intervalMs: 500, // Update every 500ms
);

Debug Information #

// Enable debug overlay
AdaptiveVideoPlayer(
  showDebugInfo: true,
  // ... other parameters
)

// Get detailed diagnostics
await _player.diagnoseVideoState(index);

// Listen to player state updates
_player.onPlayerStateInfoUpdate = (PlayerStateInfo stateInfo) {
  print('Player ${stateInfo.index}: ${stateInfo.playerStatus}');
};

Custom Callbacks #

final methodChannel = _player.methodChannel;

methodChannel.onVideoLoaded = (int index, String url) {
  print('Video $index loaded: $url');
};

methodChannel.onBufferingUpdate = (int index, String url, int percent) {
  print('Video $index buffering: $percent%');
};

methodChannel.onError = (int index, String url, String errorMessage, String errorCode) {
  print('Error in video $index: $errorMessage');
};

Example #

Check out the full example in the /example folder, which demonstrates:

  • Vertical video feed with PageView
  • Dynamic video fitting modes
  • Comprehensive debug information
  • Thumbnail support with fade animations
  • Performance monitoring
  • Error handling

Requirements #

  • Flutter 2.5.0+
  • Dart 2.14.0+
  • iOS 11.0+
  • Android API level 21+

Platform Support #

Platform Support
iOS
Android
Web
Desktop

License #

This project is licensed under the MIT License - see the LICENSE file for details.

0
likes
125
points
0
downloads

Publisher

unverified uploader

Weekly Downloads

Shorts for Flutter.

Documentation

API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on zhabby_shorts

Packages that implement zhabby_shorts