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 或预算耗尽时 nextLinenull
BackendFactory
对具体 backend 构造的间接层,使测试可以注入 fake,无需 stub dart:io Platform / 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。 NiumaPlayerViewmaybeOf 判断自己是 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:io Platform / 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)。