You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在视频播放到Map指定的时间节点时精准触发对应函数

问题根因

  • progressUpdateInterval设置为1ms会导致每秒触发1000次进度回调,性能开销过高,自然会造成视频运行异常
  • 原有代码逻辑存在多处错误:
    • 每次触发onProgress都重复初始化hapticMap,完全无必要
    • 用全等判断hapticMap.has(data.currentTime)不可行:视频返回的currentTime是浮点数,刚好和预设时间完全相等的概率几乎为0
    • hapticMap.set(hapticSet)的写法不符合Map的API规范,缺少value参数,无法正常存储映射关系

解决方案

1. 调整回调触发间隔

将progressUpdateInterval调整为100ms即可,既可以保证100ms以内的触发误差(人感知不到延迟),也不会产生过高的性能开销:

<Video
  onEnd={onEnd}
  onLoad={onLoad}
  onLoadStart={onLoadStart}
  posterResizeMode={'cover'}
  onProgress={onProgress}
  progressUpdateInterval={100}
  paused={paused}
  ref={(ref) => (videoPlayer.current = ref)}
  source={external ? { uri: videoURL } : videoURL}
  resizeMode={"contain"}
  style={{ flex: 1 }}
>
</Video>

2. 预定义触发映射和去重集合

将振动触发的时间映射提到组件外部存储,同时新增已触发时间的集合,避免同一个时间点重复触发振动:

// 预设振动触发规则:key为触发时间(单位秒,支持小数),value为振动类型
const HAPTIC_TRIGGER_MAP = new Map([
  [7, Haptics.ImpactFeedbackStyle.Heavy],
  // 其余触发点按照该格式新增即可
])
// 存储已触发过的时间点,避免重复调用
const triggeredTimeSet = new Set()

3. 重写onProgress逻辑

用区间判断代替全等判断,适配浮点数的时间误差:

const onProgress = (data) => {
  if (isLoading) return
  const currentTime = data.currentTime
  setCurrentTime(currentTime)

  for (const [triggerTime, feedbackStyle] of HAPTIC_TRIGGER_MAP) {
    // 触发条件:当前时间已超过触发时间、未触发过、误差小于100ms(和回调间隔对应)
    if (currentTime >= triggerTime && !triggeredTimeSet.has(triggerTime) && currentTime - triggerTime < 0.1) {
      Haptics.impactAsync(feedbackStyle)
      triggeredTimeSet.add(triggerTime)
    }
  }
}

4. 补充重置逻辑

如果视频支持进度拖拽、重播功能,需要在onSeek、onLoad、重播触发的回调中执行triggeredTimeSet.clear()清空已触发集合,即可支持进度调整后重新触发对应时间点的振动。


内容的提问来源于stack exchange,提问作者Paulo Henrique Leal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 03:15:00