πŸ“Ή Video Player SDK

A Flutter SDK for rendering, organizing, and interacting with video playlists. The SDK provides a powerful and customizable solution to integrate video playback, sharing, and offline support in your Flutter apps. Ideal for apps requiring curated video playlists like fitness, learning, therapy, and training platforms.


✨ Features

  • πŸ“Ί Video Player Screen with auto-play and playlist support
  • πŸ›°οΈ Connectivity Wrapper to manage internet availability
  • πŸ“€ WhatsApp Integration for easy video sharing
  • 🧠 Playlist Model support for organizing videos
  • πŸ”„ Offline Caching Ready (via cached_network_image)

πŸš€ Getting Started

Prerequisites

Make sure your app is set up to support the following packages:

πŸ”§ Android Configuration

Add the following permissions in your android/app/src/main/AndroidManifest.xml file:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

Ensure the minimum SDK version is 19 or higher:

defaultConfig {
  minSdkVersion 19
}

🍎 iOS Configuration

Add the following to your ios/Runner/Info.plist:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>
<key>NSAllowsLocalNetworking</key>
<true/>

Also include network permission descriptions (optional but recommended):

<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs internet access to check connectivity.</string>

πŸ› οΈ Usage

Here is a complete example demonstrating the use of the SDK:

import 'package:flutter/material.dart';
import 'package:video_player_sdk/video_player_sdk.dart';

void main() {
  runApp(const MainApp());
}

/// Main entry point of the app
class MainApp extends StatefulWidget {
  const MainApp({super.key});

  @override
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(brightness: Brightness.dark),
      // The app is wrapped in Scaffold to include AppBar and body content
      home: Scaffold(
        appBar: AppBar(title: const Text("Video Player")),
        // ConnectivityWrapper is from the SDK; handles internet status
        body: const ConnectivityWrapper(child: MyApp()),
      ),
    );
  }
}

/// This widget renders a list of playlists and videos
class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // Sample playlist along with dummy video details
  final List<PlaylistModel> videoDetails = [
    PlaylistModel(
      playlistName: "Health & Wellness",
      videos: [
        VideoData(
          id: "1",
          title: "Yoga for Sciatica Pain",
          url:
              "https://videos.pexels.com/video-files/1578318/1578318-hd_1920_1080_30fps.mp4",
          duration: "00:13",
          thumbnail:
              "https://picsum.photos/seed/Yoga-for-Sciatica-Pain/200/120",
          language: "Hindi",
          sharedVideoLink: "smartleader.info/videos/1",
        ),
        VideoData(
          id: "2",
          title: "Meditation Techniques",
          url:
              "https://videos.pexels.com/video-files/3145223/3145223-sd_640_360_30fps.mp4",
          duration: "01:13",
          thumbnail: "https://picsum.photos/seed/Meditation-Techniques/200/120",
          language: "English",
          sharedVideoLink: "smartleader.info/videos/2",
        ),
      ],
    ),
    PlaylistModel(
      playlistName: "Calmness and Confidence",
      videos: [
        VideoData(
          id: "3",
          title: "Yoga for Back Pain",
          url:
              "https://videos.pexels.com/video-files/6981411/6981411-sd_640_360_25fps.mp4",
          duration: "00:13",
          thumbnail: "https://picsum.photos/seed/Yoga-for-Back-Pain/200/120",
          language: "Urdu",
          sharedVideoLink: "smartleader.info/videos/3",
        ),
        VideoData(
          id: "4",
          title: "Yoga for Joint Pain",
          url:
              "https://videos.pexels.com/video-files/5307742/5307742-uhd_2560_1440_30fps.mp4",
          duration: "00:42",
          thumbnail: "https://picsum.photos/seed/Yoga-for-Joint-Pain/200/120",
          language: "Marathi",
        ),
      ],
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      padding: const EdgeInsets.all(10),
      itemCount: videoDetails.length,
      itemBuilder: (context, index) {
        // Get current playlist name and videos
        final playlistName = videoDetails[index].playlistName;
        final playListVideos = videoDetails[index].videos;

        return Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Display playlist title
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 8.0),
              child: Text(
                playlistName,
                style: Theme.of(context).textTheme.titleLarge,
              ),
            ),

            // Display all videos in the playlist
            ...playListVideos.asMap().entries.map((entry) {
              final videoIndex = entry.key;
              final video = entry.value;

              return GestureDetector(
                onTap: () {
                  // Open the video player screen with current video index
                  Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (_) => VideoPlayerScreen(
                        playListName: playlistName,
                        videos: playListVideos,
                        currentIndex:
                            videoIndex, // plays selected video (if not provided it plays the first video in the playlist)
                        autoPlay: true,
                      ),
                    ),
                  );
                },
                child: Padding(
                  padding: const EdgeInsets.only(bottom: 10),
                  child: VideoInfoCard(
                    // SDK-provided widget to display video info
                    thumbNail: video.thumbnail,
                    duration: video.duration,
                    playListName: playlistName,
                    videoName: video.title,
                    sharedVideoMessage: video.sharedVideoLink,
                  ),
                ),
              );
            }),
          ],
        );
      },
    );
  }
}

...

πŸ“š Additional Information

  • πŸ“¦ Contribute: Fork the repo and open a PR for enhancements or bug fixes.
  • 🐞 Issues: Please report issues through the GitHub issue tracker.