import type { Engine, GeometryFromShape } from '@galacean/effects'; import { MaskableGraphic, Texture, spec } from '@galacean/effects'; /** * 用于创建 videoItem 的数据类型, 经过处理后的 spec.VideoContent */ export interface VideoItemProps extends Omit { listIndex?: number; renderer: { shape?: GeometryFromShape; texture: Texture; } & Omit; mask?: spec.MaskOptions; } /** * Video component class * 视频播放状态由以下两个维度的结束行为组合决定: * - 合成结束行为(rootEndBehavior):destroy / freeze / restart / forward * - 视频结束行为(videoEndBehavior):destroy / freeze / restart */ export declare class VideoComponent extends MaskableGraphic { video?: HTMLVideoElement; /** * 视频元素是否激活 */ isVideoActive: boolean; /** * 是否为透明视频 */ protected transparent: boolean; /** * 是否由用户手动控制播放速率(覆盖合成的播放速率) */ private manualPlaybackRate; /** * 是否由用户手动控制循环播放(覆盖合成的结束行为) */ private manualLoop; /** * 是否由用户手动暂停视频 */ private manualPause; /** * 视频是否已开始播放 */ private playTriggered; /** * 上一次的视频时间,用于检测重播 */ private lastVideoTime; /** * 视频是否已经销毁(用于 destroy 结束行为,确保只重置一次) */ private videoDestroyed; /** * 视频是否处于 seek 中 * seek 期间禁止上传帧,避免 destroy 后 seek 回 0 期间渲染旧帧 */ private videoSeeking; /** * 待执行的 seek 目标时间,延迟到 onUpdate 中处理以避免竞态。 * 值为 null 表示没有待执行的 seek。 */ private pendingSeekTime; /** * 是否正在处理 gotoAndStop 的 seek * 用于跳过 pause 事件触发的 pauseVideoElement,等 seek 完成后再暂停 */ private isGotoAndStopSeeking; /** * 是否刚收到 goto 事件,等待后续 play/pause 事件来区分场景 */ private isWaitingForGotoResult; /** * 当前正在执行的 play() Promise,用于串行化 play 调用,避免上的竞态 */ private playPromise; /** * 存储事件监听器的移除函数,用于销毁时清理 */ private eventDisposers; private static readonly threshold; constructor(engine: Engine); setTexture(input: Texture): void; setTexture(input: string): Promise; onAwake(): void; fromData(data: VideoItemProps): void; onUpdate(dt: number): void; onDestroy(): void; onDisable(): void; onEnable(): void; /** * 处理 goto 事件:重置播放状态,记录待 seek 时间 */ private handleGoto; /** * 处理合成 pause 事件 * 如果刚收到 goto 事件且等待结果,说明是 gotoAndStop 场景 */ private handleCompositionPause; /** * 处理合成 play 事件(合成开始/重播/恢复时触发) */ private handleCompositionPlay; /** * 根据合成结束行为决定视频的后续处理 */ private handleCompositionEnd; /** * 视频是否已播放到末尾 */ private checkVideoEnded; /** * 合成是否已到达结束时间 */ private checkCompositionEnded; /** * 是否应该冻结视频(暂停在当前帧) */ private shouldFreezeVideo; /** * 是否应该启动视频播放 */ private shouldStartVideo; /** * 处理延迟 seek,返回 true 表示本帧已处理 seek,应跳过后续逻辑 */ private processPendingSeek; /** * 检测合成是否发生了 restart,并重置相关状态 */ private detectCompositionRestart; /** * 冻结视频:停止播放,保持当前帧 */ private freezeVideo; /** * 确保 restart 行为的视频设置了 loop 标志 * 手动模式下不自动设置,保持用户设置的值 */ private ensureLoopFlag; /** * 处理 destroy 结束行为:视频播放到末尾后,seek 回 0 并清空纹理 * 确保合成 restart 时视频已在第 0 帧,不会闪最后一帧 */ private handleDestroyBehavior; /** * 开始播放视频 */ private startVideo; /** * 安全地调用 video.play(),串行化调用 */ private safePlay; /** * 暂停底层视频元素 */ private pauseVideoElement; /** * seek 期间设置 videoSeeking=true,阻止 uploadCurrentVideoFrame 上传旧帧 * @param time 目标时间 * @param clearTexture 是否在 seek 期间清空纹理 * @param isGotoAndStop 是否为 gotoAndStop 场景 */ private performSeek; /** * 更新视频播放速率 * 手动模式下保持用户设置的速率不变,自动模式下根据 engine.speed * composition.speed 计算 */ private updatePlaybackRate; /** * 当前 item 可播放的本地视频时间。 * item.time 在 delay 前为负数,视频时间需要从 0 开始。 */ private getItemSeekTime; /** * 获取 item 的本地时间。优先使用 timeline 写入的 item.time, * 未写入时使用合成时间和 item delay 做兜底。 */ private getItemLocalTime; /** * 将 seek 目标限制到视频有效时间范围内。 */ private getClampedSeekTime; /** * 组件重新启用时将视频时间对齐到 item 本地时间,但不直接触发播放。 */ private syncVideoToItemTime; /** * 当前 item 已经进入自己的时间区间,且视频允许自动播放。 */ private canPlayCurrentItem; /** * 获取当前视频时长 */ getDuration(): number; /** * 获取当前视频播放时刻 */ getCurrentTime(): number; /** * 设置当前视频播放时刻 * @param time 目标时间,会被限制在 [0, duration] 范围内 */ setCurrentTime(time: number): void; /** * 设置视频是否循环播放,调用后会覆盖合成的结束行为,改为由用户手动控制循环。 * 调用 {@link resetLoop} 可恢复为由合成结束行为自动控制。 * @param loop 是否循环播放 */ setLoop(loop: boolean): void; /** * 重置循环播放为合成自动控制模式 */ resetLoop(): void; /** * 设置视频是否静音 * @param muted 是否静音 */ setMuted(muted: boolean): void; /** * 设置视频音量 * @param volume 视频音量 */ setVolume(volume: number): void; /** * 设置当前视频是否为透明视频 * @param transparent 是否为透明视频 */ setTransparent(transparent: boolean): void; /** * 设置视频播放速率,调用后会覆盖合成的速率,改为由用户手动控制速率。 * 调用 {@link resetPlaybackRate} 可恢复为由合成速率自动控制。 * @param rate 视频播放速率 */ setPlaybackRate(rate: number): void; /** * 重置播放速率为合成自动控制模式 */ resetPlaybackRate(): void; /** * 播放视频,同时取消手动暂停状态 * @since 2.3.0 */ playVideo(): void; /** * 手动暂停视频 * @since 2.3.0 */ pauseVideo(): void; }