nirmaan_youtube_player 2.0.0 copy "nirmaan_youtube_player: ^2.0.0" to clipboard
nirmaan_youtube_player: ^2.0.0 copied to clipboard

Cross-platform Flutter player for YouTube embeds and authorized offline video playback on Android, iOS, macOS, and Windows.

nirmaan_youtube_player #

pub package License Platforms

A Flutter package for presenting YouTube embeds and locally stored video in a consistent player experience across Android, iOS, macOS, and Windows.

Use responsibly: Only play or download video that you own or are explicitly authorised to use. This package does not grant rights to access, download, redistribute, or bypass restrictions for third-party content. See the full Legal notice before shipping an app with this package.

Highlights #

  • One player API for Android, iOS, macOS, and Windows.
  • YouTube IFrame playback with custom HTML-based controls — no YouTube branding shown by default.
  • Local MP4 playback on all supported platforms.
  • Offline video manager for starting, cancelling, listing, and removing saved videos.
  • Playback controls for play, pause, seek, mute, speed, fullscreen, and progress.
  • ValueNotifier-based controller — plain Flutter patterns, nothing extra to learn.
  • Customisable offline-player icons and HTML player appearance.
  • Offline video metadata persisted in app-managed storage automatically.

Platform support #

Capability Android iOS macOS Windows
YouTube playback (live + VOD)
Local MP4 playback
Offline download management
Native fullscreen
Controller commands

Installation #

From pub.dev #

Use this after the package has been published:

dependencies:
  nirmaan_youtube_player: ^2.0.0

From GitHub #

Use this while testing a branch or before a pub.dev release:

dependencies:
  nirmaan_youtube_player:
    git:
      url: https://github.com/Hemant88080/nirmaan_youtube_player.git
      ref: main

From a local path #

dependencies:
  nirmaan_youtube_player:
    path: ../nirmaan_youtube_player

Then fetch packages:

flutter pub get

Quick start #

1. Initialise once #

Call NirmaanYoutubePlayer.initialize() before runApp(). It prepares local storage and the offline download service.

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

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await NirmaanYoutubePlayer.initialize();

  runApp(const MyApp());
}

2. Display a video #

class LessonPlayer extends StatefulWidget {
  const LessonPlayer({super.key});

  @override
  State<LessonPlayer> createState() => _LessonPlayerState();
}

class _LessonPlayerState extends State<LessonPlayer> {
  final NirmaanYoutubeController _controller = NirmaanYoutubeController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 16 / 9,
      child: buildPlatformYoutubePlayer(
        url: 'https://www.youtube.com/watch?v=YOUR_VIDEO_ID',
        controller: _controller,
        autoPlay: false,
      ),
    );
  }
}

Supported URL formats:

https://www.youtube.com/watch?v=VIDEO_ID
https://youtu.be/VIDEO_ID
https://www.youtube.com/embed/VIDEO_ID
https://www.youtube.com/shorts/VIDEO_ID
https://www.youtube.com/live/VIDEO_ID

Complete example application #

A ready-to-add example app is available in example/lib/main.dart.

The example demonstrates:

  1. package initialisation;
  2. online YouTube playback;
  3. play, pause, mute, seek, and playback-speed controls;
  4. downloading an authorised video for offline use;
  5. switching automatically between online and local playback.

To run the example locally:

cd example
flutter create .
flutter pub get
flutter run

After Flutter creates the platform folders, apply the platform configuration below.

Offline workflow #

Download an authorised video #

NirmaanDownloadService returns the local MP4 path when a download completes. The path can be stored in your own lesson model or passed directly to the player.

final service = NirmaanYoutubePlayer.downloadService;

final localPath = await service.downloadYoutubeVideo(
  youtubeUrl: 'https://www.youtube.com/watch?v=YOUR_VIDEO_ID',
  lectureId: 'lesson-42',
  lectureIdInt: 42,
  courseId: 7,
  title: 'Introduction',
  courseTitle: 'Flutter Foundations',
  thumbnailUrl: 'https://example.com/lesson-42-thumbnail.jpg',
  duration: '15:30',
  onProgress: (progress) {
    debugPrint('Download: ${(progress * 100).toStringAsFixed(0)}%');
  },
);

if (localPath != null) {
  debugPrint('Saved to: $localPath');
}

Play a saved video #

Pass the returned local path to localVideoPath. When a non-null path is supplied, the package uses its local HTML5 player instead of the online YouTube player.

buildPlatformYoutubePlayer(
  url: 'https://www.youtube.com/watch?v=YOUR_VIDEO_ID',
  controller: _controller,
  autoPlay: true,
  localVideoPath: localPath,
);

Manage saved videos #

final service = NirmaanYoutubePlayer.downloadService;

final isDownloaded = service.hasDownloadedSync('lesson-42');
final savedPath = await service.getLocalPath('lesson-42');

service.cancelDownload('lesson-42');
await service.deleteDownload('lesson-42');

final downloads = await service.getAllDownloads();

Downloads are stored in the application documents directory. The exact file location is platform-dependent and should be treated as app-managed storage.

Player controls #

final controller = NirmaanYoutubeController();

await controller.play();
await controller.pause();
await controller.togglePlayPause();

await controller.mute();
await controller.unMute();
await controller.toggleMute();

await controller.seekTo(const Duration(seconds: 90));
await controller.seekForward10();
await controller.seekBackward10();
await controller.setPlaybackRate(1.5);

Listen for player state changes with ValueListenableBuilder:

ValueListenableBuilder<NirmaanYoutubeValue>(
  valueListenable: controller,
  builder: (context, value, child) {
    final label = value.isPlaying ? 'Playing' : 'Paused';
    return Text('$label • ${value.position.inSeconds}s');
  },
)

Platform configuration #

The package uses a local loopback HTTP server on native platforms to serve the player page and local MP4 content. Complete the relevant setup once in the host application.

Android #

Add internet access and permit the app to load content from the local server.

android/app/src/main/AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:name="${applicationName}"
        android:label="your_app"
        android:icon="@mipmap/ic_launcher"
        android:networkSecurityConfig="@xml/network_security_config"
        android:usesCleartextTraffic="true">
        <!-- existing application configuration -->
    </application>
</manifest>

android/app/src/main/res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="false">127.0.0.1</domain>
        <domain includeSubdomains="false">localhost</domain>
    </domain-config>
</network-security-config>

Use an Android minSdk of 19 or higher.

iOS #

Add the following inside the root <dict> of ios/Runner/Info.plist:

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

<key>io.flutter.embedded_views_preview</key>
<true/>

Use an iOS deployment target of 12.0 or higher.

macOS #

Add local-network access in both macos/Runner/DebugProfile.entitlements and macos/Runner/Release.entitlements:

<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>

Also add this inside the root <dict> in macos/Runner/Info.plist:

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

Use a macOS deployment target of 10.14 or higher.

Windows #

No code configuration is required. The machine running the app must have the Microsoft Edge WebView2 Runtime available. Windows 11 and up-to-date Windows 10 include it by default. For older machines, install it from Microsoft's WebView2 page.

Customisation #

Offline-player icons #

Replace any of the offline control icons using inline SVG or an image URL:

buildPlatformYoutubePlayer(
  url: 'https://www.youtube.com/watch?v=YOUR_VIDEO_ID',
  controller: _controller,
  autoPlay: false,
  offlineIcons: NirmaanPlayerIcons(
    play: NirmaanPlayerIcon.svg('<svg viewBox="0 0 24 24">...</svg>'),
    pause: NirmaanPlayerIcon.svg('<svg viewBox="0 0 24 24">...</svg>'),
    fullscreen: NirmaanPlayerIcon.image(
      'https://example.com/icons/fullscreen.png',
    ),
  ),
);

Advanced HTML configuration #

For full control over the HTML player output, use NirmaanYoutubeHtmlConfig with buildNirmaanYoutubeHtml():

final html = buildNirmaanYoutubeHtml(
  NirmaanYoutubeHtmlConfig(
    videoId: 'YOUR_VIDEO_ID',
    autoPlay: false,
    sourceName: 'my-app',
    bridgeType: NirmaanYoutubeBridgeType.inAppWebView,
    fullscreenType: NirmaanYoutubeFullscreenType.nativeFlutter,
    brandText: 'My Academy',
    courseTitle: 'Flutter Foundations',
    showWatermark: true,
    watermarkText: 'INTERNAL USE',
    accentColor: '#FF6B6B',
    borderRadius: 12,
  ),
);

Public API #

API Purpose
NirmaanYoutubePlayer.initialize() Initialises the package once before runApp().
NirmaanYoutubePlayer.downloadService Accesses the shared download service.
buildPlatformYoutubePlayer(...) Builds the correct player implementation for the current platform.
NirmaanYoutubeController Sends playback commands and exposes NirmaanYoutubeValue.
NirmaanDownloadService Starts, tracks, cancels, lists, and removes offline downloads.
OfflineLecture Model for persisted offline-video metadata.
extractYoutubeVideoId(url) Extracts a YouTube video ID from a supported URL format.
NirmaanPlayerIcons Replaces selected offline-player icons.
NirmaanYoutubeHtmlConfig Configures the advanced HTML player builder.

Troubleshooting #

The player is blank on Android #

Confirm that INTERNET, usesCleartextTraffic, and network_security_config.xml are present. Then run:

flutter clean
flutter pub get
flutter run

The player is blank on iOS or macOS #

Confirm that NSAllowsLocalNetworking is included in Info.plist. On macOS, also confirm that both client and server network entitlements are enabled.

Windows shows a WebView2 error #

Install or update the Microsoft Edge WebView2 Runtime, then restart the application.

Offline playback does not start #

Check that the local file still exists:

final path = await NirmaanYoutubePlayer.downloadService.getLocalPath('lesson-42');
debugPrint(path ?? 'File is not available');

A download fails #

Confirm that the URL is valid, the device has network access, and you are authorised to download the content. Availability may vary according to the source, the video's own restrictions, and the platform.

Development #

flutter pub get
dart format --set-exit-if-changed .
flutter analyze
flutter test
dart pub publish --dry-run

Read this section before shipping an application that uses this package.

Independence #

This is an independent open-source project. It is not affiliated with, endorsed by, or sponsored by YouTube, Google LLC, or any of their subsidiaries. "YouTube" is a trademark of Google LLC and is used here only to describe compatibility.

Online playback #

Online playback is delivered through YouTube's official IFrame Player API, which is the mechanism YouTube provides for embedding videos in third-party applications. Your application must still comply with the YouTube Terms of Service and the YouTube API Services Terms of Service, including their rules on embedding, advertising, and content presentation.

Offline download #

The download capability is a technical tool intended only for content you have the legal right to store offline — for example:

  • videos you created and uploaded yourself;
  • videos for which you hold a written licence or the copyright owner's explicit permission;
  • content distributed under a licence that permits offline copies.

Downloading YouTube content without such rights may violate the YouTube Terms of Service and copyright law in your jurisdiction. This package does not verify ownership or licences — that responsibility rests entirely with the application developer and the end user. The package does not circumvent DRM, encryption, or any technical protection measure; it cannot and does not download DRM-protected content.

Your responsibilities as an app developer #

  1. Ensure every video offered for download in your app is content you are authorised to distribute offline.
  2. Present your own terms of use to your end users where appropriate.
  3. Monitor changes to YouTube's terms and applicable law; if a service's terms change, update or disable affected features in your app.
  4. Do not use this package to build products whose primary purpose is unauthorised downloading of third-party content.

No warranty and no liability #

This software is provided "as is", without warranty of any kind, as stated in the LICENSE. The authors and contributors accept no liability for any misuse of this package or for any violation of third-party terms or laws committed by applications that embed it. If any part of this package conflicts with the law in your jurisdiction or with the terms of a service you use it with, you must not use that part.

Issues and contributions #

Please report reproducible issues through the GitHub issue tracker. Include the Flutter version, target platform, steps to reproduce, expected behaviour, and relevant logs.

License #

BSD 3-Clause License. See LICENSE.

3
likes
160
points
256
downloads

Documentation

API reference

Publisher

verified publisherhabilkul.com

Weekly Downloads

Cross-platform Flutter player for YouTube embeds and authorized offline video playback on Android, iOS, macOS, and Windows.

Repository (GitHub)
View/report issues

Topics

#youtube #video-player #flutter #webview #offline-video

License

BSD-3-Clause (license)

Dependencies

flutter, flutter_inappwebview, fullscreen_window, path_provider, youtube_explode_dart

More

Packages that depend on nirmaan_youtube_player