패키지, 저장소 및 앱 카테고리 검색

GitHub 저장소gyoussef55/pip_plugin

pip_plugin

gyoussef55/pip_plugin open-source repository details.

pip_plugin 프로젝트 이미지
스타
3
포크
2
최근 푸시(UTC)
2025. 6. 7.
프로젝트 상태
활성

원본 README

아래는 영문 원문 스냅샷입니다. 최신 내용은 GitHub에서 확인하세요.

pip_plugin

⚠️ Experimental
A Flutter plugin that enables a customizable Picture-in-Picture window displaying text.


Table of Contents


Introduction

pip_plugin is an experimental Flutter plugin that lets you display text overlays in Picture-in-Picture mode on Android, iOS, Web, and Desktop. It exposes a simple Dart API to configure the PiP window’s appearance and control its lifecycle.


Preview

ios macos web


Installation

Add the plugin to your pubspec:

dependencies:
  pip_plugin: ^<latest_version>

Then run:

flutter pub get

Platform-specific Setup

Android
  1. In your AndroidManifest.xml, enable PiP support:

    <application
        android:supportsPictureInPicture="true"
        …>
        …
    </application>
    
  2. Enable PiP callbacks there are two approaches:

1. Activity Wrapper (Recommended)

Wrap your main activity with the provided helper—this is the simplest integration.

  • Kotlin

    import cl.puntito.simple_pip_mode.PipCallbackHelperActivityWrapper
    
    class MainActivity: PipCallbackHelperActivityWrapper() {
        // No additional code needed
    }
    
  • Java

    import cl.puntito.simple_pip_mode.PipCallbackHelperActivityWrapper;
    
    public class MainActivity extends PipCallbackHelperActivityWrapper {
        // No additional code needed
    }
    

Once inherited, PiP callbacks and the PiP widget become available automatically.

2. Callback Helper

If you prefer not to subclass your activity, you can manually wire up the callbacks:

  • Kotlin

    import cl.puntito.simple_pip_mode.PipCallbackHelper
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.embedding.android.FlutterActivity
    import android.content.res.Configuration
    
    class MainActivity: FlutterActivity() {
      private val pipHelper = PipCallbackHelper()
    
      override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        pipHelper.configureFlutterEngine(flutterEngine)
      }
    
      override fun onPictureInPictureModeChanged(
        isInPipMode: Boolean,
        newConfig: Configuration?
      ) {
        super.onPictureInPictureModeChanged(isInPipMode, newConfig)
        pipHelper.onPictureInPictureModeChanged(isInPipMode)
      }
    }
    
  • Java

    import cl.puntito.simple_pip_mode.PipCallbackHelper;
    import io.flutter.embedding.engine.FlutterEngine;
    import io.flutter.embedding.android.FlutterActivity;
    import android.content.res.Configuration;
    
    public class MainActivity extends FlutterActivity {
        private final PipCallbackHelper pipHelper = new PipCallbackHelper();
    
        @Override
        public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
            super.configureFlutterEngine(flutterEngine);
            pipHelper.configureFlutterEngine(flutterEngine);
        }
    
        @Override
        public void onPictureInPictureModeChanged(
          boolean isInPipMode,
          Configuration newConfig
        ) {
            super.onPictureInPictureModeChanged(isInPipMode, newConfig);
            pipHelper.onPictureInPictureModeChanged(isInPipMode);
        }
    }
    

iOS

In your Info.plist, add PiP to the background modes:

<key>UIBackgroundModes</key>
<array>
  <string>audio</string>
  <string>airplay</string>
  <string>picture-in-picture</string>
</array>

Other Platforms
  • Web and Desktop: No extra configuration.

Usage

Plugin API

Import the main plugin class and manage PiP mode:
⚠️ Initialize first: call setupPip(...) before using other PiP methods.


/// Prepares PiP with an optional title and configuration.
Future<bool> setupPip({
  /// On desktop platforms, you can optionally set a `windowTitle`.
  String? windowTitle,
  PipConfiguration? configuration,
});

/// Enters Picture-in-Picture mode.
Future<bool> startPip();

/// Exits Picture-in-Picture mode.
/// (On Android this is a no-op, as PiP closes automatically.)
Future<bool> stopPip();

/// Returns whether PiP is supported on the current platform.
Future<bool> isPipSupported();

/// Dynamically updates the PiP window’s appearance:
/// - backgroundColor, textColor, textSize, textAlign, ratio
Future<bool> update({
  Color? backgroundColor,
  Color? textColor,
  double? textSize,
  /// Only `left`, `right`, and `center` are supported.
  TextAlign? textAlign,
  /// ignored on Web platforms.
  (int, int)? ratio,
});

/// Changes the displayed text in PiP.
Future<bool> updateText(String text);

/// Emits `true`/`false` whenever PiP becomes active/inactive.
Stream<bool> get pipActiveStream;

/// Whether the plugin has been initialized.
bool get isInitialized;

/// Releases any resources held by the plugin.
void dispose();

Showing Text in PiP
  • Android: Wrap your UI with the built-in TextPipWidget to render the PiP text overlay, then drive it with the plugin API.
  • All other platforms: No widget required—just invoke the PipPlugin methods directly.
Android Example
import 'package:flutter/material.dart';
import 'package:pip_plugin/pip_plugin.dart';
import 'package:pip_plugin/text_pip_widget.dart';

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final pip = PipPlugin();

  @override
  void initState() {
    super.initState();
    _initPlugin();
  }

  void _initPlugin() async {
    final supported = await pip.isPipSupported();
    if (supported) {
      await pip.setupPip();
      await pip.updateText('inside PiP');
    }
  }

  @override
  Widget build(BuildContext context) {
    return TextPipWidget(
      child: Scaffold(
        body: const Center(child: Text('outside PiP')),
        floatingActionButton: FloatingActionButton(
          onPressed: () async {
            await pip.startPip();            
          },
          child: const Icon(Icons.picture_in_picture),
        ),
      ),
    );
  }
}

Platform Support

Platform Minimum Version / Notes
Android API 26+
iOS iOS 15+ (for Simulator testing, use an iPad simulator)
Web Follows the Document Picture-in-Picture API.
Desktop All major versions (macOS, Windows, Linux)
Youssef Gamal GitHub avatar
GitHub 작성자

Youssef Gamal ↗

Software Engineer

언어C++CMakeDartSwiftRubyCKotlinHTMLObjective-C

이 저장소가 배포한 패키지

사용 중인 의존성

의존성 목록 7 개

  • flutter{"sdk":"flutter"}
  • flutter_web_plugins{"sdk":"flutter"}
  • plugin_platform_interface^2.1.8
  • simple_pip_mode^1.1.0
  • web^1.1.1
  • flutter_test개발 의존성{"sdk":"flutter"}
  • flutter_lints개발 의존성^4.0.0

프로젝트에 맞는 저장소를 선택하려면?

사용 목적에 따라 검색하고 개발 활동을 비교한 뒤 원본 저장소에서 요구 사항을 확인하세요.

  1. 이름, 작성자 또는 설명으로 검색하고 기술 주제로 범위를 좁힙니다.
  2. 스타, 포크, 최근 푸시를 함께 비교하세요. 스타는 관심의 지표이며 품질을 보장하지 않습니다.
  3. 사용하기 전에 GitHub에서 README, 라이선스, Issues를 확인하세요.

출처 및 관리

“A repository is the most basic element of GitHub.”

GitHub Docs — About repositories ↗