保利威文档中心

幫助中心

Polyv Flutter Media Player - 專案文件

更新時間:2026-05-14 11:19:41

基於 保利威 iOS 點播播放器 SDK 封裝的 Flutter 影片播放器插件,支援 iOS 和 Android 雙平台。

目錄


專案概述

polyv-flutter-media-player-demo 是一個 Flutter Plugin 專案,將保利威原生播放器 SDK(iOS PolyvMediaPlayerSDK、Android media-player-full)封裝為統一的 Dart API,供 Flutter 應用跨平台呼叫。

專案分為兩層:

層級 目錄 職責
Plugin(插件層) polyv_media_player/ 播放核心能力 + 可共享業務服務模組,無業務 UI
Demo App(範例層) example/ 完整 UI 實作(播放器皮膚、控制欄、彈幕、字幕等),供客戶參考複製

技術棧

類別 技術
框架 Flutter (Dart SDK ^3.9.0)
狀態管理 Provider (ChangeNotifier 模式)
iOS 原生 SDK PolyvMediaPlayerSDK ~> 2.7.2 (Objective-C)
Android 原生 SDK net.polyv.android:media-player-full:2.7.2 (Kotlin)
跨平台通訊 Flutter Platform Channel (MethodChannel + EventChannel)
依賴 http, crypto, shared_preferences, provider

底層 SDK 參考

本插件封裝的保利威原生 SDK 文件:


架構設計

┌─────────────────────────────────────────────────────────┐
│                    Demo App (example/)                    │
│  ┌──────────┐ ┌──────────────┐ ┌────────────────────┐   │
│  │ HomePage │ │ LongVideoPage│ │ DownloadCenterPage │   │
│  └──────────┘ └──────────────┘ └────────────────────┘   │
└────────────────────────┬────────────────────────────────┘
                         │ 依赖
┌────────────────────────▼────────────────────────────────┐
│                Plugin (polyv_media_player/)               │
│                                                          │
│  ┌─────────────────────────────────────────────────┐     │
│  │  Widgets Layer                                   │     │
│  │  PolyvVideoPlayer · PolyvVideoView               │     │
│  └───────────────────┬─────────────────────────────┘     │
│                      │                                    │
│  ┌───────────────────▼─────────────────────────────┐     │
│  │  UI Components                                   │     │
│  │  ControlBar · ProgressSlider · QualitySelector   │     │
│  │  SpeedSelector · Danmaku · Gestures · Settings   │     │
│  └───────────────────┬─────────────────────────────┘     │
│                      │                                    │
│  ┌───────────────────▼─────────────────────────────┐     │
│  │  Core Layer                                      │     │
│  │  PlayerController · PlayerState · PlayerEvents   │     │
│  └───────────────────┬─────────────────────────────┘     │
│                      │                                    │
│  ┌───────────────────▼─────────────────────────────┐     │
│  │  Platform Channel                                │     │
│  │  MethodChannel · EventChannel · PlayerAPI        │     │
│  └───────────────────┬─────────────────────────────┘     │
│                      │                                    │
│  ┌───────────────────▼─────────────────────────────┐     │
│  │  Infrastructure (共享业务服务)                     │     │
│  │  DanmakuService · VideoListService · Download     │     │
│  └─────────────────────────────────────────────────┘     │
└──────────────────────────────────────────────────────────┘
                         │ Platform Channel
            ┌────────────┴────────────┐
            ▼                         ▼
   ┌────────────────┐      ┌────────────────┐
   │  iOS Native    │      │ Android Native  │
   │  (Objective-C) │      │   (Kotlin)      │
   │                │      │                 │
   │ PolyvMedia     │      │ PolyvMedia      │
   │ PlayerSDK      │      │ PlayerSDK       │
   └────────────────┘      └────────────────┘

核心設計原則

  1. Plugin 只提供核心能力:播放控制、狀態管理、Platform Channel 封裝
  2. 業務邏輯在 Dart 層統一實作:不在原生層呼叫 Polyv 業務 HTTP 介面
  3. 原生層只封裝播放器 SDK:暴露底層能力(播放、下載、字幕等),不包含業務決策
  4. 清晰度切換進度恢復:由原生層負責(Dart 層僅觸發切換、消費事件)

功能特性

播放核心

功能 說明
影片播放 透過 VID 播放保利威點播影片
播放控制 播放、暫停、停止、重播
進度控制 Seek 到指定位置,進度即時回呼
倍速播放 支援 0.5x ~ 2.0x 變速播放
清晰度切換 多碼率切換(流暢、高清、超清等),自動恢復進度
字幕系統 多語言字幕軌道、雙語字幕、字幕開關
離線播放 自動偵測已下載影片,優先本地播放
播放進度記憶 自動儲存和恢復上次播放進度

影片下載

功能 說明
下載管理 建立、暫停、繼續、重試、刪除下載任務
狀態持久化 App 重啟後自動同步下載狀態
進度回呼 即時下載進度通知

彈幕系統

功能 說明
彈幕渲染 支援滾動彈幕層
彈幕服務介面 可插拔的 DanmakuService / DanmakuSendService
HTTP 彈幕 內建保利威彈幕 API 實作
彈幕設定 透明度、速度、字型大小等
彈幕發送 全螢幕模式下的彈幕輸入框

互動體驗

功能 說明
手勢控制 滑動調節進度/音量/亮度
雙擊全螢幕 雙擊播放區域切換全螢幕
鎖定螢幕模式 全螢幕時鎖定控制欄
控制欄自動隱藏 可設定隱藏延遲
橫直螢幕適配 全螢幕/非全螢幕佈局自適應

專案結構

polyv-flutter-media-player-demo/          # Git 仓库根目录
├── polyv_media_player/                   # Flutter Plugin 插件
│   ├── lib/
│   │   ├── polyv_media_player.dart       # 主入口(导出所有公共 API)
│   │   ├── core/                         # 核心层
│   │   │   ├── player_controller.dart    # 播放器控制器(ChangeNotifier)
│   │   │   ├── player_state.dart         # 播放器状态模型
│   │   │   ├── player_events.dart        # 事件类型定义
│   │   │   ├── player_event_parser.dart  # 原生事件解析器
│   │   │   ├── player_exception.dart     # 异常类
│   │   │   ├── player_config.dart        # 配置类
│   │   │   ├── subtitle_selection_policy.dart  # 字幕自动选择策略
│   │   │   ├── offline_playback_decider.dart   # 离线播放决策
│   │   │   └── system_locale_provider.dart     # 系统语言检测
│   │   ├── platform_channel/             # Platform Channel 封装
│   │   │   ├── player_api.dart           # Channel 名称 + 方法常量
│   │   │   ├── method_channel_handler.dart  # MethodChannel 处理
│   │   │   └── event_channel_handler.dart   # EventChannel 处理
│   │   ├── services/                     # 服务层
│   │   │   ├── polyv_config_service.dart # 账号配置管理
│   │   │   ├── player_initializer.dart   # 播放器初始化
│   │   │   ├── video_progress_service.dart  # 播放进度记忆
│   │   │   └── subtitle_preference_service.dart  # 字幕偏好
│   │   ├── infrastructure/               # 基础设施(共享业务服务)
│   │   │   ├── danmaku/                  # 弹幕系统
│   │   │   │   ├── danmaku_model.dart    # 弹幕数据模型
│   │   │   │   └── danmaku_service.dart  # 弹幕服务接口 + 实现
│   │   │   ├── download/                 # 下载管理
│   │   │   │   ├── download_task.dart    # 下载任务模型
│   │   │   │   ├── download_task_status.dart  # 下载状态枚举
│   │   │   │   ├── download_state_manager.dart  # 下载状态管理
│   │   │   │   ├── download_event_handler.dart  # 下载事件处理
│   │   │   │   └── download_native_repository.dart  # 原生下载能力封装
│   │   │   ├── video_list/               # 视频列表
│   │   │   │   ├── video_list_models.dart  # 视频列表数据模型
│   │   │   │   ├── video_list_service.dart  # 视频列表服务
│   │   │   │   └── video_list_api_client.dart  # API 客户端
│   │   │   └── polyv_api_client.dart     # Polyv API 通用客户端
│   │   ├── widgets/                      # Widget 层
│   │   │   ├── polyv_video_player.dart   # 全功能播放器 Widget
│   │   │   └── polyv_video_view.dart     # 原生视频视图(PlatformView)
│   │   ├── ui/                           # 内置 UI 组件
│   │   │   ├── control_bar.dart          # 控制栏
│   │   │   ├── control_bar_state_machine.dart  # 控制栏状态机
│   │   │   ├── player_colors.dart        # 播放器颜色常量
│   │   │   ├── double_tap_detector.dart  # 双击检测
│   │   │   ├── progress_slider/          # 进度条组件
│   │   │   ├── quality_selector/         # 清晰度选择器
│   │   │   ├── speed_selector/           # 倍速选择器
│   │   │   ├── subtitle_toggle.dart      # 字幕开关
│   │   │   ├── danmaku/                  # 弹幕 UI 组件
│   │   │   │   ├── danmaku_layer.dart    # 弹幕渲染层
│   │   │   │   ├── danmaku_toggle.dart   # 弹幕开关
│   │   │   │   ├── danmaku_input_overlay.dart  # 弹幕输入浮层
│   │   │   │   └── danmaku_settings.dart # 弹幕设置面板
│   │   │   ├── gestures/                 # 手势系统
│   │   │   │   ├── player_gesture_controller.dart
│   │   │   │   ├── player_gesture_detector.dart
│   │   │   │   └── seek_preview_overlay.dart
│   │   │   └── settings_menu/            # 设置菜单
│   │   └── utils/                        # 工具类
│   │       └── plv_logger.dart           # 日志工具
│   ├── ios/                              # iOS 原生代码
│   │   ├── Classes/
│   │   │   ├── PolyvMediaPlayerPlugin.m  # 插件入口
│   │   │   ├── PLVFlutterMethodRouter.m  # Method 路由分发
│   │   │   ├── PLVFlutterPlayerSession.m # 播放器会话管理
│   │   │   ├── PLVFlutterEventEmitter.m  # 事件发射器
│   │   │   ├── PLVFlutterDownloadMonitor.m # 下载监控
│   │   │   ├── PLVFlutterSubtitleCoordinator.m  # 字幕协调
│   │   │   ├── PLVVideoViewFactory.m     # PlatformView 工厂
│   │   │   └── ...字幕解析相关文件
│   │   └── polyv_media_player.podspec    # CocoaPods 配置
│   ├── android/                          # Android 原生代码
│   │   └── src/main/kotlin/
│   │       ├── PolyvMediaPlayerPlugin.kt # 插件入口
│   │       ├── MethodRouter.kt           # Method 路由
│   │       ├── PlayerCoordinator.kt      # 播放协调
│   │       ├── DownloadCoordinator.kt    # 下载协调
│   │       ├── SubtitleCoordinator.kt    # 字幕协调
│   │       ├── PlaybackEventEmitter.kt   # 播放事件发射
│   │       ├── DownloadEventEmitter.kt   # 下载事件发射
│   │       └── PolyvVideoViewFactory.kt  # PlatformView 工厂
│   └── test/                             # 单元测试
├── example/                              # Demo App
│   ├── lib/
│   │   ├── main.dart                     # 应用入口
│   │   ├── config/
│   │   │   └── app_config.dart           # 账号配置(环境变量注入)
│   │   ├── pages/
│   │   │   ├── home_page.dart            # 首页(长视频/下载中心入口)
│   │   │   ├── long_video_page.dart      # 长视频播放页
│   │   │   └── download_center/          # 下载中心
│   │   │       ├── download_center_page.dart
│   │   │       └── downloading_task_item.dart
│   │   └── player_skin/
│   │       └── video_list/               # 视频列表组件
│   └── pubspec.yaml
└── docs/                                 # 项目文档

快速整合

環境要求

要求 版本
Flutter >= 3.3.0
Dart SDK ^3.9.0
iOS >= 13.0
Android minSdk >= 21

步驟 1: 新增依賴

polyv_media_player 目錄複製到專案中(與 lib/ 平級),然後在 pubspec.yaml 中新增:

dependencies:
  polyv_media_player:
    path: polyv_media_player

執行:

flutter pub get

步驟 2: iOS 設定

在 iOS 專案的 Podfile 中確保平台版本 >= 13.0:

platform :ios, '13.0'

然後執行:

cd ios && pod install

插件會自動透過 CocoaPods 引入以下依賴:

PolyvMediaPlayerSDK (~> 2.7.2)
PLVFoundationSDK/AbstractBase (~> 1.30.2)
PLVFDB (~> 1.0.5)
PLVLOpenSSL (~> 1.1.12101)
SSZipArchive (~> 2.0)

步驟 3: 初始化 SDK

main.dart 中初始化保利威帳號設定:

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await PolyvMediaPlayer.initialize(
    userId: 'your_user_id',
    secretKey: 'your_secret_key',
    readToken: 'your_read_token',   // 可选
    writeToken: 'your_write_token', // 可选
  );

  runApp(const MyApp());
}

帳號設定資訊可在 保利威後台 註冊後取得。

步驟 4: 使用播放器

最簡用法,一行程式碼即可播放影片:

PolyvVideoPlayer(
  vid: 'your_video_id',
  autoPlay: true,
)

API 參考

SDK 初始化

await PolyvMediaPlayer.initialize(
  userId: String,     // 必填:保利威用户 ID
  secretKey: String,  // 必填:密钥
  readToken: String?, // 可选:读取 Token
  writeToken: String?,// 可选:写入 Token
);

// 检查是否已初始化
bool initialized = PolyvMediaPlayer.isInitialized;

// 获取用户 ID
String userId = await PolyvMediaPlayer.userId;

PlayerController

PlayerController 是播放器的核心控制類別,繼承自 ChangeNotifier,透過 Provider 模式驅動 UI 更新。

播放控制

方法 / 屬性 說明
loadVideo(vid, {autoPlay}) 載入影片
play() 播放
pause() 暫停
stop() 停止
replay() 重播(回到開頭重新播放)
seekTo(position) 跳轉到指定位置(毫秒)

設定

方法 說明
setPlaybackSpeed(speed) 設定倍速(0.5 ~ 2.0)
setQuality(index) 切換清晰度
setSubtitle(index) 設定字幕(-1 關閉)
toggleSubtitle() 切換字幕開關
setSubtitleWithKey({enabled, trackKey}) 透過 key 設定字幕

狀態

屬性 類型 說明
state PlayerState 目前播放器完整狀態
qualities List<QualityItem> 可用清晰度列表
availableSubtitles List<SubtitleItem> 可用字幕列表
effectiveIsPlaying bool 播放狀態(推薦用於 UI)

生命週期

方法 說明
dispose() 釋放資源(必須在 Widget dispose 時呼叫)

PlayerState

class PlayerState {
  PlayerLoadingState loadingState;  // idle/loading/prepared/playing/paused/buffering/completed/error
  int position;           // 当前位置(毫秒)
  int duration;           // 总时长(毫秒)
  int bufferedPosition;   // 缓冲位置(毫秒)
  double playbackSpeed;   // 播放速度
  String? errorMessage;   // 错误信息
  String? vid;            // 当前视频 VID
  bool subtitleEnabled;   // 字幕是否开启
  String? currentSubtitleId;  // 当前字幕 ID
  List<SubtitleItem> availableSubtitles;  // 可用字幕列表
}

事件類型

事件 說明 資料
stateChanged 播放狀態變化 新狀態 (playing/paused/buffering...)
progress 進度更新 position, duration, bufferedPosition
error 錯誤 code, message
qualityChanged 清晰度變化 qualities[], currentIndex
subtitleChanged 字幕變化 subtitles[], currentIndex
playbackSpeedChanged 倍速變化 speed
completed 播放完成 -

Platform Channel 常數

MethodChannel: com.polyv.media_player/player
EventChannel:  com.polyv.media_player/events
DownloadEvent: com.polyv.media_player/download_events

PolyvVideoPlayer Widget

參數 類型 預設值 說明
vid String 必填 影片 ID
autoPlay bool true 是否自動播放
showControls bool true 是否顯示控制欄
enableDanmaku bool true 是否啟用彈幕
enableGestures bool true 是否啟用手勢
enableDoubleTapFullscreen bool true 是否啟用雙擊全螢幕
isFullscreen bool false 是否全螢幕模式
showLockButton bool false 全螢幕時顯示鎖定螢幕按鈕
showDanmakuSend bool false 全螢幕時顯示彈幕發送
showTopBar bool false 全螢幕時顯示頂部欄
videoTitle String? null 全螢幕頂部欄標題
aspectRatio double 16/9 影片寬高比
backgroundColor Color Colors.black 背景色
autoHideDuration Duration 3s 控制欄自動隱藏時長
controller PlayerController? null 外部控制器
danmakuService DanmakuService? null 彈幕資料服務
danmakuSendService DanmakuSendService? null 彈幕發送服務
danmakuHeightFactor double 0.6 彈幕顯示區域高度比例
onFullscreenChanged Function? null 全螢幕切換回呼
onLoaded Function? null 載入完成回呼
onPlayingChanged Function? null 播放狀態變化回呼
onCompleted Function? null 播放完成回呼
onError Function? null 錯誤回呼

UI 元件

插件內建了完整的播放器 UI 元件庫,可獨立使用或組合使用。

可用元件

元件 匯入路徑 說明
ControlBar ui/control_bar.dart 完整控制欄(進度條 + 播放按鈕 + 倍速 + 清晰度)
ProgressSlider ui/progress_slider/ 進度條元件(含緩衝進度)
QualitySelector ui/quality_selector/ 清晰度選擇器
SpeedSelector ui/speed_selector/ 倍速選擇器
SubtitleToggle ui/subtitle_toggle.dart 字幕開關
DanmakuLayer ui/danmaku/danmaku.dart 彈幕渲染層
DanmakuToggle ui/danmaku/danmaku_toggle.dart 彈幕開關
DanmakuInputOverlay ui/danmaku/danmaku_input_overlay.dart 彈幕發送輸入框
DanmakuSettings ui/danmaku/danmaku_settings.dart 彈幕設定面板
SettingsMenu ui/settings_menu/ 設定選單(清晰度 + 倍速 + 彈幕)
PlayerGestureDetector ui/gestures/gestures.dart 手勢偵測(滑動進度/音量/亮度)
SeekPreviewOverlay ui/gestures/seek_preview_overlay.dart Seek 預覽浮層
PlayerColors ui/player_colors.dart 播放器顏色常數

自訂 UI 範例

使用底層元件組裝自訂播放器:

class CustomVideoPage extends StatefulWidget {
  @override
  State<CustomVideoPage> createState() => _CustomVideoPageState();
}

class _CustomVideoPageState extends State<CustomVideoPage> {
  late final PlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = PlayerController();
    _controller.loadVideo('your_video_id');
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: Stack(
        children: [
          // 原生视频视图
          const PolyvVideoView(),
          // 自定义控制栏
          Align(
            alignment: Alignment.bottomCenter,
            child: ControlBar(controller: _controller),
          ),
        ],
      ),
    );
  }
}

平台原生層

iOS 原生架構

iOS 原生程式碼採用模組化拆分,每個元件職責單一:

元件 檔案 職責
Plugin 入口 PolyvMediaPlayerPlugin.m 持有 Flutter registrar/channel,註冊 Plugin
Method 路由 PLVFlutterMethodRouter MethodChannel 方法分發
播放器會話 PLVFlutterPlayerSession 播放器實例生命週期管理、SDK 呼叫封裝
事件發射 PLVFlutterEventEmitter 統一封裝 player/download EventChannel 事件發送
下載監控 PLVFlutterDownloadMonitor 下載狀態輪詢與下載事件發送
字幕協調 PLVFlutterSubtitleCoordinator 字幕軌道事件、label 維護
影片視圖 PLVVideoViewFactory PlatformView 工廠,建立原生影片渲染視圖
字幕解析 PLVVodMediaSubtitleParser SRT/ASS 字幕檔案解析

iOS 依賴(透過 CocoaPods)

s.dependency 'PolyvMediaPlayerSDK', '~> 2.7.2'
s.dependency 'PLVFoundationSDK/AbstractBase', '~> 1.30.2'
s.dependency 'PLVFDB', '~> 1.0.5'
s.dependency 'PLVLOpenSSL', '~> 1.1.12101'
s.dependency 'SSZipArchive', '~> 2.0'
s.platform = :ios, '13.0'

Android 原生架構

元件 檔案 職責
Plugin 入口 PolyvMediaPlayerPlugin.kt 註冊 MethodChannel、EventChannel
Method 路由 MethodRouter.kt 方法分發
播放協調 PlayerCoordinator.kt 播放器實例管理
下載協調 DownloadCoordinator.kt 下載任務管理
字幕協調 SubtitleCoordinator.kt 字幕軌道管理
播放事件 PlaybackEventEmitter.kt 播放事件發送到 Flutter
下載事件 DownloadEventEmitter.kt 下載事件發送到 Flutter
影片視圖 PolyvVideoViewFactory.kt PlatformView 工廠

Android 依賴

implementation("net.polyv.android:media-player-full:2.7.2")
implementation("net.polyv.android:media-player-sdk-addon-business:2.7.2")
implementation("net.polyv.android:media-player-sdk-addon-download:2.7.2")

業務服務模組

插件在 __PLV_K

联系客服,在线咨询