播放器引擎 V3 技术规范
📋 目录
1. 概述
1.1 项目背景
当前播放器引擎(V2)存在以下问题:
复杂的意图系统导致维护困难
分散的状态管理增加调试复杂度
六阶段数据流造成性能开销
策略系统过于抽象,难以理解
1.2 设计目标
主要目标 :
🎯 简化架构 : 使用状态机统一管理播放逻辑
🔍 提高可调试性 : 状态转换路径清晰,易于追踪
⚡ 优化性能 : 减少不必要的计算和状态检查
🛠 增强可维护性 : 代码结构清晰,职责分离明确
次要目标 :
保持向后兼容性
支持渐进式迁移
提供更好的开发体验
1.3 核心原则
单一职责原则 : 每个组件只负责一个特定功能
状态驱动 : 所有播放行为由状态机驱动
事件驱动 : 通过事件进行组件间通信
可预测性 : 相同输入产生相同输出
可测试性 : 所有组件都能独立测试
2. 架构设计
2.1 整体架构
┌─────────────────────────────────────────────────────────────┐
│ 播放器引擎 V3 │
├─────────────────────────────────────────────────────────────┤
│ 用户接口层 (Public API) │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ PlayEngine │ │ EventEmitter │ │
│ └─────────────────┘ └─────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 核心状态层 (Core State Layer) │
│ ┌────────────────────┐ ┌─────────────────┐ │
│ │ PlayerStateMachine │ │ StateManager │ │
│ └────────────────────┘ └─────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 功能模块层 (Feature Modules) │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐│
│ │ SentenceManager │ │ LoopManager │ │ AutoController ││
│ └─────────────────┘ └─────────────────┘ └─────────────────┘│
├─────────────────────────────────────────────────────────────┤
│ 控制层 (Control Layer) │
│ ┌──────────────────┐ ┌─────────────────┐ │
│ │PlaybackController│ │ EventHandler │ │
│ └──────────────────┘ └─────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 基础设施层 (Infrastructure) │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐│
│ │ MediaClock │ │ Logger │ │ TypeDefs ││
│ └─────────────────┘ └─────────────────┘ └─────────────────┘│
└─────────────────────────────────────────────────────────────┘
2.2 分层职责
层级
职责
组件
用户接口层
对外提供统一API
PlayEngine, EventEmitter
核心状态层
状态管理和转换
PlayerStateMachine, StateManager
功能模块层
具体业务逻辑
SentenceManager, LoopManager, AutoController
控制层
设备控制和事件处理
PlaybackController, EventHandler
基础设施层
公共服务和工具
MediaClock, Logger, TypeDefs
2.3 依赖关系
graph TD
A[PlayEngine] --> B[PlayerStateMachine]
A --> C[EventHandler]
B --> D[StateManager]
B --> E[SentenceManager]
B --> F[LoopManager]
B --> G[AutoController]
C --> H[PlaybackController]
E --> I[MediaClock]
F --> I
G --> I
H --> I
Loading
3. 状态机设计
3.1 状态定义
基于提供的状态图,定义以下状态:
enum PlayerState {
// 主要播放状态
PLAYING = 'playing' ,
PAUSED = 'paused' ,
USER_PAUSED = 'userPaused' ,
// 句子生命周期状态
SENTENCE_COMPLETED = 'sentenceCompleted' ,
// 循环控制状态
CHECK_LOOP = 'checkLoop' ,
SEEK_TO_START = 'seekToStart' ,
DECREMENT_LOOP = 'decrementLoop' ,
CHECK_AUTO_PAUSE_AFTER_LOOP = 'checkAutoPauseAfterLoop' ,
// 暂停和恢复状态
CHECK_AUTO_PAUSE = 'checkAutoPause' ,
WAITING_FOR_RESUME = 'waitingForResume' ,
CHECK_AUTO_RESUME = 'checkAutoResume' ,
AUTO_RESUMING = 'autoResuming' ,
MANUAL_RESUMING = 'manualResuming' ,
CHECK_LOOP_AFTER_RESUME = 'checkLoopAfterResume' ,
SEEK_TO_START_AFTER_RESUME = 'seekToStartAfterResume' ,
// 间隙跳跃状态
CHECK_GAP_SKIP = 'checkGapSkip' ,
DETECT_GAP = 'detectGap' ,
SKIP_GAP = 'skipGap' ,
// 用户交互状态
USER_SEEKED = 'userSeeked' ,
// 终态
COMPLETED = 'completed' ,
ERROR = 'error'
}
3.2 事件定义
enum PlayerEvent {
// 播放控制事件
PLAY = 'PLAY' ,
PAUSE = 'PAUSE' ,
TOGGLE_PLAY = 'TOGGLE_PLAY' ,
SEEK = 'SEEK' ,
USER_SEEK = 'USER_SEEK' ,
// 句子生命周期事件
SENTENCE_ENDED = 'SENTENCE_ENDED' ,
LAST_SENTENCE_ENDED = 'LAST_SENTENCE_ENDED' ,
// 循环控制事件
LOOP_ENABLED = 'LOOP_ENABLED' ,
LOOP_DISABLED = 'LOOP_DISABLED' ,
LOOP_COUNT_ZERO = 'LOOP_COUNT_ZERO' ,
LOOP_COUNT_POSITIVE = 'LOOP_COUNT_POSITIVE' ,
INFINITE_LOOP = 'INFINITE_LOOP' ,
// 自动暂停事件
AUTO_PAUSE_ENABLED = 'AUTO_PAUSE_ENABLED' ,
AUTO_PAUSE_DISABLED = 'AUTO_PAUSE_DISABLED' ,
// 自动恢复事件
AUTO_RESUME_ENABLED = 'AUTO_RESUME_ENABLED' ,
AUTO_RESUME_DISABLED = 'AUTO_RESUME_DISABLED' ,
AUTO_RESUME_TIMEOUT = 'AUTO_RESUME_TIMEOUT' ,
MANUAL_RESUME = 'MANUAL_RESUME' ,
USER_PAUSE_AFTER_RESUME = 'USER_PAUSE_AFTER_RESUME' ,
// 间隙跳跃事件
GAP_SKIP_ENABLED = 'GAP_SKIP_ENABLED' ,
GAP_SKIP_DISABLED = 'GAP_SKIP_DISABLED' ,
LARGE_GAP_DETECTED = 'LARGE_GAP_DETECTED' ,
NO_GAP_DETECTED = 'NO_GAP_DETECTED' ,
// 错误和完成事件
PLAYBACK_ERROR = 'PLAYBACK_ERROR' ,
FILE_ENDED = 'FILE_ENDED'
}
3.3 状态转换表
当前状态
事件
下一状态
条件
动作
PLAYING
SENTENCE_ENDED
SENTENCE_COMPLETED
当前句播放完成
updateCurrentSentence
SENTENCE_COMPLETED
-
CHECK_LOOP
自动
-
CHECK_LOOP
LOOP_ENABLED & (LOOP_COUNT_POSITIVE | INFINITE_LOOP)
SEEK_TO_START
单句循环开启
-
CHECK_LOOP
LOOP_DISABLED | LOOP_COUNT_ZERO
CHECK_AUTO_PAUSE
循环关闭或次数为0
-
SEEK_TO_START
-
DECREMENT_LOOP
seek完成
seekToSentenceStart
DECREMENT_LOOP
-
CHECK_AUTO_PAUSE_AFTER_LOOP
次数递减
decrementLoopCount
CHECK_AUTO_PAUSE_AFTER_LOOP
AUTO_PAUSE_ENABLED
PAUSED
自动暂停开启
pausePlayback
CHECK_AUTO_PAUSE_AFTER_LOOP
AUTO_PAUSE_DISABLED
PLAYING
自动暂停关闭
resumePlayback
CHECK_AUTO_PAUSE
AUTO_PAUSE_ENABLED
PAUSED
自动暂停开启
pausePlayback
CHECK_AUTO_PAUSE
AUTO_PAUSE_DISABLED
CHECK_GAP_SKIP
自动暂停关闭
-
PAUSED
-
WAITING_FOR_RESUME
自动
-
WAITING_FOR_RESUME
-
CHECK_AUTO_RESUME
自动
-
CHECK_AUTO_RESUME
AUTO_RESUME_ENABLED
AUTO_RESUMING
自动恢复开启
startAutoResumeTimer
CHECK_AUTO_RESUME
MANUAL_RESUME
MANUAL_RESUMING
用户手动恢复
cancelAutoResumeTimer
CHECK_AUTO_RESUME
USER_PAUSE_AFTER_RESUME
USER_PAUSED
用户暂停
-
AUTO_RESUMING
AUTO_RESUME_TIMEOUT
CHECK_LOOP_AFTER_RESUME
等待时间到
-
MANUAL_RESUMING
-
CHECK_LOOP_AFTER_RESUME
自动
-
CHECK_LOOP_AFTER_RESUME
LOOP_ENABLED
SEEK_TO_START_AFTER_RESUME
需要回到句子开头
-
CHECK_LOOP_AFTER_RESUME
LOOP_DISABLED
CHECK_GAP_SKIP
不需要循环
-
SEEK_TO_START_AFTER_RESUME
-
PLAYING
seek完成
seekToSentenceStart, resumePlayback
CHECK_GAP_SKIP
GAP_SKIP_ENABLED
DETECT_GAP
间隙跳跃开启
-
CHECK_GAP_SKIP
GAP_SKIP_DISABLED
PLAYING
间隙跳跃关闭
playNextSentence
DETECT_GAP
LARGE_GAP_DETECTED
SKIP_GAP
检测到大间隙
-
DETECT_GAP
NO_GAP_DETECTED
PLAYING
无大间隙
playNextSentence
SKIP_GAP
-
PLAYING
跳转完成
seekToNextSentence, resumePlayback
PLAYING
PAUSE
USER_PAUSED
用户手动暂停
pausePlayback
USER_PAUSED
PLAY
PLAYING
用户恢复播放
resumePlayback
PLAYING
USER_SEEK
USER_SEEKED
用户手动跳转
seekToTime
USER_SEEKED
-
PLAYING
跳转完成
resumePlayback
PLAYING
LAST_SENTENCE_ENDED
COMPLETED
最后一句结束
completePlayback
SENTENCE_COMPLETED
LAST_SENTENCE_ENDED
COMPLETED
当前句是最后一句
completePlayback
*
PLAYBACK_ERROR
ERROR
播放错误
handleError
3.4 状态机配置
// XState 状态机配置
const playerStateMachineConfig = {
id : 'playerEngine' ,
initial : 'playing' ,
context : {
currentTime : 0 ,
duration : 0 ,
currentSentenceIndex : - 1 ,
loopCount : 0 ,
loopRemaining : 0 ,
autoResumeTimer : null
// ...其他上下文数据
} ,
states : {
playing : {
on : {
SENTENCE_ENDED : 'sentenceCompleted' ,
PAUSE : 'userPaused' ,
USER_SEEK : 'userSeeked' ,
LAST_SENTENCE_ENDED : 'completed' ,
PLAYBACK_ERROR : 'error'
} ,
entry : [ 'resumePlayback' ] ,
exit : [ 'clearPlaybackState' ]
} ,
sentenceCompleted : {
always : 'checkLoop' ,
entry : [ 'updateCurrentSentence' ]
} ,
checkLoop : {
always : [
{
target : 'seekToStart' ,
cond : 'shouldLoop'
} ,
{
target : 'checkAutoPause'
}
]
}
// ...其他状态定义
}
}
4. 核心组件规范
4.1 PlayEngine (主入口)
职责 : 对外提供统一的播放器API
interface PlayEngine {
// 生命周期管理
init ( config : PlayEngineConfig ) : Promise < void >
dispose ( ) : Promise < void >
// 播放控制
play ( ) : Promise < void >
pause ( ) : void
togglePlay ( ) : Promise < void >
seek ( time : number ) : void
userSeek ( time : number ) : void
// 状态查询
getState ( ) : PlayerState
getContext ( ) : PlaybackContext
isPlaying ( ) : boolean
getCurrentTime ( ) : number
// 配置管理
updateConfig ( config : Partial < PlayEngineConfig > ) : void
getConfig ( ) : PlayEngineConfig
// 事件监听
on ( event : string , listener : Function ) : void
off ( event : string , listener : Function ) : void
// 调试支持
getDebugInfo ( ) : DebugInfo
exportStateMachine ( ) : string
}
实现要求 :
必须使用 TypeScript 严格模式
所有公共方法必须有 JSDoc 注释
错误处理必须通过 Promise reject 或事件形式
必须支持异步初始化和清理
4.2 PlayerStateMachine (状态机)
职责 : 管理播放器的核心状态和转换逻辑
interface PlayerStateMachine {
// 状态管理
getCurrentState ( ) : PlayerState
getContext ( ) : StateMachineContext
// 事件发送
send ( event : PlayerEvent , payload ?: any ) : void
// 状态监听
onStateChange ( listener : StateChangeListener ) : UnsubscribeFunction
onTransition ( listener : TransitionListener ) : UnsubscribeFunction
// 调试支持
getStateHistory ( ) : StateTransition [ ]
exportStateChart ( ) : string
// 生命周期
start ( ) : void
stop ( ) : void
}
技术要求 :
使用 XState 库实现
状态转换必须是确定性的
必须支持状态历史记录
必须提供可视化调试支持
4.3 SentenceManager (句子管理)
职责 : 管理字幕句子的生命周期和边界检测
interface SentenceManager {
// 句子查询 (复用 V2 SubtitleIndexCalculator 算法)
getCurrentSentence ( ) : SubtitleItem | null
getSentenceByIndex ( index : number ) : SubtitleItem | null
getSentenceByTime ( time : number ) : SubtitleItem | null
// 句子导航 (基于 V2 索引计算逻辑)
goToSentence ( index : number ) : void
goToNextSentence ( ) : void
goToPreviousSentence ( ) : void
// 边界检测 (复用 V2 TimeMath 边界检测)
checkSentenceEnd ( currentTime : number ) : boolean
getSentenceProgress ( currentTime : number ) : number
// 配置管理
updateSubtitles ( subtitles : SubtitleItem [ ] ) : void
setCurrentIndex ( index : number ) : void
// 事件发送
onSentenceChange : EventEmitter < SentenceChangeEvent >
onSentenceEnd : EventEmitter < SentenceEndEvent >
}
实现要求 :
必须支持高精度时间比较 (复用 V2 TimeMath.EPS 和边界检测算法)
句子边界检测必须稳定,避免抖动 (复用 V2 的边界抖动检测逻辑)
必须支持空字幕场景
性能要求:O(log n) 时间复杂度查找 (复用 V2 SubtitleIndexCalculator 的二分搜索)
4.4 LoopManager (循环管理)
职责 : 处理单句循环的所有逻辑
interface LoopManager {
// 循环控制
enable ( count ?: number ) : void
disable ( ) : void
isEnabled ( ) : boolean
// 循环状态
getRemainingCount ( ) : number
decrementCount ( ) : number
resetCount ( count : number ) : void
// 循环模式
setMode ( mode : LoopMode ) : void
getMode ( ) : LoopMode
// 循环执行
shouldLoop ( ) : boolean
executeLoop ( sentenceIndex : number ) : Promise < void >
// 事件发送
onLoopStateChange : EventEmitter < LoopStateChangeEvent >
onLoopExecution : EventEmitter < LoopExecutionEvent >
}
实现要求 :
支持有限循环和无限循环
循环计数必须持久化
必须与 SentenceManager 协同工作
循环执行必须是原子操作
4.5 AutoController (自动控制)
职责 : 处理自动暂停、自动恢复和间隙跳跃
interface AutoController {
// 自动暂停
enableAutoPause ( ) : void
disableAutoPause ( ) : void
isAutoPauseEnabled ( ) : boolean
// 自动恢复
enableAutoResume ( delay : number ) : void
disableAutoResume ( ) : void
isAutoResumeEnabled ( ) : boolean
startAutoResumeTimer ( ) : void
cancelAutoResumeTimer ( ) : void
// 间隙跳跃
enableGapSkip ( threshold : number ) : void
disableGapSkip ( ) : void
isGapSkipEnabled ( ) : boolean
detectGap ( currentTime : number , nextSentenceTime : number ) : boolean
executeGapSkip ( targetTime : number ) : Promise < void >
// 事件发送
onAutoResumeTimer : EventEmitter < AutoResumeTimerEvent >
onGapDetection : EventEmitter < GapDetectionEvent >
}
实现要求 :
定时器必须可取消和重置
间隙检测必须可配置阈值
所有自动操作必须可手动中断
必须处理组件销毁时的清理
4.6 PlaybackController (播放控制)
职责 : 封装视频元素的底层操作
interface PlaybackController {
// 连接管理 (从 V2 VideoController 扩展)
connect ( videoElement : HTMLVideoElement ) : void
disconnect ( ) : void
isConnected ( ) : boolean
// 播放控制 (复用 V2 VideoController 接口)
play ( ) : Promise < void >
pause ( ) : void
seek ( time : number ) : void
// 状态查询 (复用 V2 VideoController 接口)
getCurrentTime ( ) : number
getDuration ( ) : number
isPaused ( ) : boolean
getPlaybackRate ( ) : number
getVolume ( ) : number
// 属性设置 (复用 V2 VideoController 接口)
setPlaybackRate ( rate : number ) : void
setVolume ( volume : number ) : void
setMuted ( muted : boolean ) : void
// 事件监听 (基于 V2 MediaClock 事件系统设计)
onTimeUpdate : EventEmitter < TimeUpdateEvent >
onPlay : EventEmitter < PlayEvent >
onPause : EventEmitter < PauseEvent >
onSeeking : EventEmitter < SeekingEvent >
onSeeked : EventEmitter < SeekedEvent >
onEnded : EventEmitter < EndedEvent >
onError : EventEmitter < ErrorEvent >
}
实现要求 :
必须处理视频元素的所有异常情况
播放操作必须返回 Promise
必须支持连接状态检查
所有事件必须去重和节流 (复用 V2 MediaClock 的去重逻辑)
5. 数据流设计
5.1 数据流架构
用户交互 ──┐
├─→ EventHandler ──→ PlayerStateMachine ──→ 功能模块 ──→ PlaybackController ──→ 视频元素
媒体事件 ──┘ ↓
状态变更
↓
StateManager ──→ 外部状态 (Zustand)
5.2 数据流原则
单向数据流 : 数据只能从上层组件流向下层组件
事件驱动 : 组件间通过事件进行通信
状态集中 : 核心状态由状态机统一管理
副作用隔离 : 所有副作用在控制层处理
5.3 状态同步策略
interface StateManager {
// 状态同步
syncToExternal ( state : InternalState ) : void
syncFromExternal ( externalState : ExternalState ) : void
// 状态订阅
subscribeToExternal ( callback : StateChangeCallback ) : UnsubscribeFunction
// 状态验证
validateState ( state : any ) : boolean
reconcileState ( internal : InternalState , external : ExternalState ) : InternalState
}
6. 接口定义
6.1 配置接口
interface PlayEngineConfig {
// 播放设置
autoPlay : boolean
playbackRate : number
volume : number
muted : boolean
// 循环设置
loopEnabled : boolean
loopMode : LoopMode
loopCount : number
// 自动控制设置
autoPauseEnabled : boolean
pauseOnSubtitleEnd : boolean
autoResumeEnabled : boolean
autoResumeDelay : number
// 间隙跳跃设置
gapSkipEnabled : boolean
gapSkipThreshold : number
// 调试设置
enableDebugLogs : boolean
enableStateLogging : boolean
// 性能设置
clockThrottleMs : number
maxStateHistorySize : number
}
6.2 事件接口
interface PlayEngineEvents {
// 播放状态事件
'state:change' : ( state : PlayerState , previousState : PlayerState ) => void
'playback:play' : ( ) => void
'playback:pause' : ( ) => void
'playback:seek' : ( time : number ) => void
'playback:ended' : ( ) => void
// 句子事件
'sentence:change' : ( sentence : SubtitleItem , index : number ) => void
'sentence:end' : ( sentence : SubtitleItem , index : number ) => void
// 循环事件
'loop:start' : ( count : number ) => void
'loop:end' : ( ) => void
'loop:count-change' : ( remaining : number ) => void
// 自动控制事件
'auto:pause' : ( ) => void
'auto:resume-start' : ( delay : number ) => void
'auto:resume-cancel' : ( ) => void
'auto:resume-complete' : ( ) => void
// 错误事件
error : ( error : PlayEngineError ) => void
}
6.3 数据类型定义
// 循环模式
enum LoopMode {
SINGLE = 'single' , // 单句循环
PLAYLIST = 'playlist' , // 列表循环 (预留)
RANDOM = 'random' // 随机循环 (预留)
}
// 播放上下文
interface PlaybackContext {
// 播放器状态
currentTime : number
duration : number
playbackRate : number
volume : number
muted : boolean
// 句子状态
currentSentenceIndex : number
sentences : SubtitleItem [ ]
// 循环状态
loopEnabled : boolean
loopMode : LoopMode
loopCount : number
loopRemaining : number
// 自动控制状态
autoPauseEnabled : boolean
autoResumeEnabled : boolean
autoResumeDelay : number
gapSkipEnabled : boolean
gapSkipThreshold : number
}
// 字幕项
interface SubtitleItem {
id : string
startTime : number
endTime : number
text : string
confidence ?: number
}
// 状态转换记录
interface StateTransition {
from : PlayerState
to : PlayerState
event : PlayerEvent
timestamp : number
payload ?: any
}
// 错误类型
class PlayEngineError extends Error {
code : string
severity : 'low' | 'medium' | 'high' | 'critical'
context ?: any
constructor ( message : string , code : string , severity : PlayEngineError [ 'severity' ] , context ?: any ) {
super ( message )
this . name = 'PlayEngineError'
this . code = code
this . severity = severity
this . context = context
}
}
7. 错误处理
7.1 错误分类
错误类型
严重级别
处理策略
网络错误
Medium
重试机制
视频格式错误
High
用户提示
字幕解析错误
Low
静默处理
状态机错误
Critical
重置状态机
内存泄漏
High
强制清理
7.2 错误处理流程
interface ErrorHandler {
handleError ( error : PlayEngineError ) : void
registerErrorRecovery ( errorCode : string , recovery : ErrorRecoveryFunction ) : void
getErrorHistory ( ) : PlayEngineError [ ]
clearErrorHistory ( ) : void
}
type ErrorRecoveryFunction = ( error : PlayEngineError ) => Promise < boolean >
7.3 错误恢复策略
自动重试 : 网络相关错误自动重试 3 次
状态回滚 : 状态机错误时回滚到最后已知稳定状态
资源清理 : 内存相关错误时强制清理资源
用户通知 : 严重错误时通过事件通知用户
8. 性能要求
8.1 性能指标
指标
要求
测量方法
状态转换延迟
< 5ms
Performance API
内存使用
< 50MB
Chrome DevTools
事件处理延迟
< 10ms
自定义计时器
句子查找时间
< 1ms
二分搜索
状态机启动时间
< 100ms
初始化计时
8.2 性能优化策略
事件节流 : 高频事件使用防抖和节流
状态缓存 : 计算结果缓存避免重复计算
懒加载 : 非核心功能按需加载
内存管理 : 及时清理无用引用
索引优化 : 使用索引加速句子查找
8.3 性能监控
interface PerformanceMonitor {
startTiming ( label : string ) : void
endTiming ( label : string ) : number
getMetrics ( ) : PerformanceMetrics
resetMetrics ( ) : void
}
interface PerformanceMetrics {
stateTransitions : {
count : number
averageTime : number
maxTime : number
}
eventProcessing : {
count : number
averageTime : number
maxTime : number
}
memoryUsage : {
current : number
peak : number
leaks : MemoryLeak [ ]
}
}
9. 测试策略
9.1 测试层级
单元测试 : 测试单个组件的功能
集成测试 : 测试组件间的协作
端到端测试 : 测试完整的播放流程
性能测试 : 测试性能指标
压力测试 : 测试极限情况
9.2 测试覆盖率要求
组件
覆盖率要求
核心状态机
95%
功能模块
90%
控制层
85%
工具函数
95%
9.3 测试工具
单元测试 : Vitest + Testing Library
状态机测试 : @xstate/test
端到端测试 : Playwright
性能测试 : 自定义性能套件
9.4 测试用例设计
// 状态机测试用例示例
describe ( 'PlayerStateMachine' , ( ) => {
describe ( '循环播放流程' , ( ) => {
it ( '应该在句子结束后检查循环设置' , async ( ) => {
// Given: 启用单句循环
// When: 句子播放结束
// Then: 应该转换到 CHECK_LOOP 状态
} )
it ( '应该在循环次数为0时停止循环' , async ( ) => {
// Given: 循环次数为1的循环播放
// When: 循环执行一次后
// Then: 应该停止循环并继续播放下一句
} )
} )
} )
10. 迁移计划
10.1 迁移阶段
阶段一: 基础架构复用 (Week 1)
✅ 直接复用 : TimeMath、MediaClock、ClockScheduler (95%代码可用)
✅ 接口适配 : VideoController、StateUpdater 增强为 PlaybackController
🔧 重构复用 : SubtitleIndexCalculator → SentenceManager 核心算法
阶段二: 状态机实现 (Week 2)
🆕 新建 : 基于 XState 的 PlayerStateMachine
🔧 参考重写 : 从 PlayerOrchestrator 提取事件处理逻辑
✅ 复用 : SubtitleLockFSM 概念用于状态协调
阶段三: 功能模块迁移 (Week 3)
✅ 算法复用 : V2 策略的核心逻辑 → V3 功能模块
🔧 架构简化 : 去除复杂的意图系统,采用直接的状态驱动
✅ 测试复用 : V2 的测试用例和边界条件检测
阶段四: 集成与优化 (Week 4)
性能对比验证 (目标: 不劣于V2)
兼容性测试
生产部署
10.2 兼容性策略
保持接口兼容 : 新引擎实现现有的公共接口
渐进式替换 : 使用适配器模式逐步替换组件
特性开关 : 使用配置开关控制新旧引擎的使用
回滚机制 : 出现问题时能快速回滚到旧版本
10.3 风险控制
风险
概率
影响
缓解措施
性能回退
中
高
详细的性能测试和基准对比
功能丢失
低
高
完整的功能映射和测试
稳定性问题
中
中
充分的集成测试和灰度发布
迁移延期
高
中
分阶段迁移,优先级排序
10.4 成功标准
功能完整性 : 100% 功能特性覆盖
性能指标 : 不劣于现有版本
稳定性 : 错误率 < 0.1%
开发体验 : 新增功能开发效率提升 50%
维护成本 : 代码复杂度降低 30%
附录
A. V2 到 V3 组件映射表
V2 组件
V3 组件
复用度
迁移策略
TimeMath
TimeMath
95%
直接复用,已完美符合V3需求
MediaClock
MediaClock
85%
直接复用,具备所有V3要求的特性
ClockScheduler
调度功能
90%
直接复用,集成到基础设施层
SubtitleIndexCalculator
SentenceManager 核心
80%
算法复用,接口重新设计
VideoController
PlaybackController
70%
接口扩展,增加连接管理
StateUpdater
状态同步接口
70%
接口适配,保持兼容性
SubtitleLockFSM
状态协调机制
60%
概念复用,简化实现
PlayerOrchestrator
PlayEngine
30%
参考事件处理,简化架构
Intent/Strategy 系统
功能模块
20%
提取核心逻辑,去除复杂抽象
B. 词汇表
术语
定义
状态机
有限状态机,用于管理播放器的状态转换
句子
字幕中的一个完整语句单元
循环
重复播放当前句子的功能
间隙跳跃
自动跳过字幕间的空白时间
自动暂停
在句子结束后自动暂停播放
自动恢复
在暂停后自动恢复播放
C. 参考资料
注意 : 本规范是一个活跃文档,随着开发进展会持续更新。所有变更都应该通过 PR 审查流程。
播放器引擎 V3 技术规范
📋 目录
1. 概述
1.1 项目背景
当前播放器引擎(V2)存在以下问题:
1.2 设计目标
主要目标:
次要目标:
1.3 核心原则
2. 架构设计
2.1 整体架构
2.2 分层职责
2.3 依赖关系
graph TD A[PlayEngine] --> B[PlayerStateMachine] A --> C[EventHandler] B --> D[StateManager] B --> E[SentenceManager] B --> F[LoopManager] B --> G[AutoController] C --> H[PlaybackController] E --> I[MediaClock] F --> I G --> I H --> I3. 状态机设计
3.1 状态定义
基于提供的状态图,定义以下状态:
3.2 事件定义
3.3 状态转换表
3.4 状态机配置
4. 核心组件规范
4.1 PlayEngine (主入口)
职责: 对外提供统一的播放器API
实现要求:
4.2 PlayerStateMachine (状态机)
职责: 管理播放器的核心状态和转换逻辑
技术要求:
4.3 SentenceManager (句子管理)
职责: 管理字幕句子的生命周期和边界检测
实现要求:
4.4 LoopManager (循环管理)
职责: 处理单句循环的所有逻辑
实现要求:
4.5 AutoController (自动控制)
职责: 处理自动暂停、自动恢复和间隙跳跃
实现要求:
4.6 PlaybackController (播放控制)
职责: 封装视频元素的底层操作
实现要求:
5. 数据流设计
5.1 数据流架构
5.2 数据流原则
5.3 状态同步策略
6. 接口定义
6.1 配置接口
6.2 事件接口
6.3 数据类型定义
7. 错误处理
7.1 错误分类
7.2 错误处理流程
7.3 错误恢复策略
8. 性能要求
8.1 性能指标
8.2 性能优化策略
8.3 性能监控
9. 测试策略
9.1 测试层级
9.2 测试覆盖率要求
9.3 测试工具
9.4 测试用例设计
10. 迁移计划
10.1 迁移阶段
阶段一: 基础架构复用 (Week 1)
TimeMath、MediaClock、ClockScheduler(95%代码可用)VideoController、StateUpdater增强为PlaybackControllerSubtitleIndexCalculator→SentenceManager核心算法阶段二: 状态机实现 (Week 2)
PlayerStateMachinePlayerOrchestrator提取事件处理逻辑SubtitleLockFSM概念用于状态协调阶段三: 功能模块迁移 (Week 3)
阶段四: 集成与优化 (Week 4)
10.2 兼容性策略
10.3 风险控制
10.4 成功标准
附录
A. V2 到 V3 组件映射表
TimeMathTimeMathMediaClockMediaClockClockSchedulerSubtitleIndexCalculatorSentenceManager核心VideoControllerPlaybackControllerStateUpdaterSubtitleLockFSMPlayerOrchestratorPlayEngineIntent/Strategy系统B. 词汇表
C. 参考资料