niuma_player library
niuma_player —— headless 视频播放内核。
只导出内核:NiumaPlayerController + 编排逻辑 + 手势 / 全屏 headless
controller + 无样式渲染面 NiumaPlayerView;不含任何控件皮肤,接入方
监听 controller.value 自拼 UI。曾经的参考皮在 git 历史
(git log --all -- 'example/lib/niuma_ui/**')。
Classes
- AutoFailoverOrchestrator
-
初始化失败后决定下一条尝试的 MediaLine,按 MediaLine.priority
升序遍历;无法 failover 或预算耗尽时 nextLine 返
null。 - BackendFactory
-
对具体 backend 构造的间接层,使测试可以注入 fake,无需 stub
dart:ioPlatform / native channels。生产实现在data/default_backend_factory.dart。 - BackendSelected
- 每次 NiumaPlayerController.initialize 成功后精确触发一次,告知最终 选中的 backend。
- DefaultBackendFactory
- 生产实现——构造真实的 video_player / niuma native 后端。
- DefaultPlatformBridge
- 生产环境 PlatformBridge。
- FallbackTriggered
-
内核降级 / 初始化超时信号。
reason == error仅 Android:controller 拆掉 video_player 换 IJK 软解前触发;reason == timeout三端通用, 是 initialize 的 wall-clock 超时排障信号(iOS / Web 上不伴随内核回退)。 - GestureFeedbackState
- 手势 HUD 数据快照。
- HeaderInjectionMiddleware
- 把一组固定 HTTP headers 合并到每个网络 NiumaDataSource 上, 用于注入鉴权 token、Referer 等静态请求头。
- LineSwitched
- NiumaPlayerController.switchLine 成功在目标线路上拉起新 backend 后精确触发一次。
- LineSwitchFailed
- NiumaPlayerController.switchLine 无法拉起新线路时触发。当前 backend(如果有)保持原状;调用方自行决定是否手动尝试其它线路。
- LineSwitching
- NiumaPlayerController.switchLine 开始拆掉当前 backend、准备拉起 新线路时触发。
- MediaLine
- 一条可切换的播放线路——画质变体或备用 CDN 入口。 调用方通过 id 标识线路;有意不重写 equality。
- MediaQuality
- 描述媒体流画质的技术性元数据,用于多码率变体比较 / 标注。
- MultiSourcePolicy
- 控制 source 初始化失败时是否自动尝试下一条优先级线路; 希望错误直接抛到 UI 时用 MultiSourcePolicy.manual。
- NiumaCapabilities
- 设备媒体能力探测(io 平台实现)。
- NiumaDataSource
- 描述视频从哪儿来。
- NiumaFullscreenController
- 全屏的 headless 编排器:进 / 退全屏时的屏幕方向锁定 + system UI 切换。 只管系统态;路由 push/pop 等 widget 部分由接入方全屏页负责。 Web 上 SystemChrome 是 no-op,enter / exit 只翻 isFullscreen 标志。
- NiumaFullscreenScope
-
标记"此 subtree 处于全屏路由内"的 InheritedWidget marker。
NiumaPlayerView 用 maybeOf 判断自己是 inline 还是全屏那份,
决定把
HtmlElementView挂哪边(web 单<video>不能两处 mount)。 - NiumaGestureController
- 视频手势的 headless 编排器:把手势几何量映射成播放意图 + HUD 反馈状态, 不持有任何 widget 概念;接入方透传手势坐标、监听 feedback 渲染 HUD。 手势:双击播放暂停、长按 2x 倍速、水平 pan seek、左/右半屏垂直 pan 亮度/音量。
- NiumaMediaSource
- 可携带多条可切换线路的媒体源描述符。单 URL 用 NiumaMediaSource.single,画质选择 / CDN failover 用 NiumaMediaSource.lines,首播走 defaultLineId 线路。
- NiumaPlayerController
- 播放内核的单一公共门面:选 backend(三端主路径官方 video_player,web 走 自家 WebVideoBackend,Android 失败当次会话回退 IJK 软解)、多线路编排、 PiP。
- NiumaPlayerEvent
- 在 NiumaPlayerController.events 上发出的事件,让 app 记录或响应 backend 选择 / 回退行为。
- NiumaPlayerOptions
- 调整 NiumaPlayerController 行为的选项。所有字段都有合理默认值。
- NiumaPlayerPool
- 内存感知的 headless 播放器池——feed 多实例场景限容量(LRU evict)
- NiumaPlayerValue
- NiumaPlayerController 状态的不可变快照,以 PlayerPhase 为唯一 事实来源;经典布尔 getter 作兼容保留。
- NiumaPlayerView
- 渲染 NiumaPlayerController 当前激活的 backend。 backend 切换(例如回退到 IJK)时自动 rebuild。
- NiumaSdkAssets
- niuma_player SDK 运行时资源常量。
- PipModeChanged
- PiP 模式状态变化事件,原生侧推送。
- PipRemoteAction
- PiP 窗内 RemoteAction 触发事件(Android only——iOS stock 控件由 AVPlayer 自己处理,不走此事件)。
- PlatformBridge
-
对
dart:ioPlatform /kIsWeb与系统能力 channel 的薄间接层。 存在的目的是让测试不引入 dart:io 也能注入 fake。 - PlayerBackend
- 每个 backend(video_player / IJK / 测试替身)都必须实现的内部契约。 NiumaPlayerController 针对该抽象编写,因此回退就只是 dispose 一个 实例、构造另一个。
- PlayerError
-
phase == error时附在 NiumaPlayerValue 上的结构化错误, 消费方直接 switch category,不必模式匹配信息文本。 - RetryPolicy
- 控制播放器初始化失败时是否重试以及何时重试;现成策略见 RetryPolicy.smart / RetryPolicy.exponential / RetryPolicy.none。
- SignedUrlMiddleware
- 用调用方提供的签名函数把每个网络 NiumaDataSource 的 URL 换成 签名后的 URL,原 headers 保留;非网络 source 不调 signer。
- SourceMiddleware
- 在 NiumaDataSource 进入播放后端之前对其进行变换。 每次涉网操作(initialize / switchLine / 重试)都会执行, 让每次尝试拿到新 headers 或重签名 URL。
Enums
- FallbackReason
- controller 从 video_player 回退到 IJK 的原因。
- GestureHudIcon
- 手势 HUD 的语义图标——headless 核只产出"是什么意图",不绑定具体资源路径。
- GestureKind
- 视频手势类型枚举。
- NiumaSourceType
- NiumaDataSource 的 source 类型。
- NiumaWebFullscreenMode
- 当前 web 浏览器的全屏策略——接入方据此分流全屏 UI。
- PlayerBackendKind
- 当前驱动 NiumaPlayerController 的 Dart 侧 backend 类型。
- PlayerErrorCategory
- PlayerError 的粗粒度分类,供上层判断是否重试 / 提示 / 切线路。
- PlayerPhase
-
互斥的播放阶段——"当前在做什么"的唯一事实来源,
isPlaying等 布尔状态全部由它派生。
Properties
- webFullscreenMode → NiumaWebFullscreenMode
-
当前 web 浏览器的全屏策略(见 NiumaWebFullscreenMode)。
DOM 能力检测收在核里,接入方直接据此分流全屏 UI。
no setter
-
webFullscreenRouteCountListenable
→ ValueListenable<
int> -
_webFullscreenRouteCount的只读视图;写侧只走 enter / exit 协调 API。no setter
Functions
-
enterWebFullscreenRoute(
) → void - 进入一个 web 全屏路由:计数 +1。全屏页 push 时调一次。
-
exitBrowserFullscreen(
) → Future< void> - 退出浏览器真全屏(仅 web)。
-
exitWebFullscreenRoute(
) → void - 退出一个 web 全屏路由:计数 -1(下限 0)。全屏页 pop 时调一次。
-
formatVideoTime(
Duration d) → String - 把 Duration 格式化成 "mm:ss" 或 "H:mm:ss"(小时数 ≥ 1 时)。
-
onBrowserFullscreenChange(
void cb(bool isFullscreen)) → void Function() - 监听浏览器全屏状态变化(含 ESC 退出),返回反注册函数;dispose 时务必 调用反注册。仅 web 有意义。
-
requestBrowserFullscreen(
) → Future< void> - 对整个 Flutter 画布进入浏览器真全屏(仅 web)。 必须在用户手势栈内同步调用,否则浏览器以「缺少用户激活」拒绝。
-
runSourceMiddlewares(
NiumaDataSource input, List< SourceMiddleware> middlewares) → Future<NiumaDataSource> -
把
input从左到右依次经过middlewares(前者输出为后者输入), 返回最终变换结果;空列表短路原样返回。
Typedefs
- PoolControllerFactory = NiumaPlayerController Function(NiumaMediaSource source)
- 池如何创建一个 NiumaPlayerController——由 consumer 提供, 池只管生命周期,options / backend / middleware 由工厂决定。
Exceptions / Errors
- EngineFallbackFailure
- Android 上 video_player 与 IJK 兜底双双失败时抛出的组合异常。 同时携带两段错误——只报 IJK 的会掩盖主内核的根因(如 HTTP 403)。