简体   繁体   English

如何区分两个“onpause”事件——由点击“pause”按钮引起,以及由到达媒体片段末尾引起?

[英]How to distinguish between two “onpause” events - caused by clicking “pause” button, and caused by reaching the end of a media fragment?

If the user wants to stop the HTML5 media, for example by clicking “pause” native control button, we get "onpause" event.如果用户想要停止 HTML5 媒体,例如通过单击“暂停”本机控件按钮,我们会收到“onpause”事件。 At the same time, if media element reaches the end of the specified fragment, it triggers the same "onpause" event automatically.同时,如果媒体元素到达指定片段的末尾,它会自动触发相同的“onpause”事件。 Is it possible to separate one from another?是否有可能将一个与另一个分开? In JQuery style,在 JQuery 风格中,

<video id="video1" src="url/video.webm#t=10,20" controls></video>

<script type="text/javascript">
  $(window).load(function () { 
    $('#video1').on("manualpause", function () {
      alert("you paused this media manually!");
    });
    $('#video1').on("fragmentend", function () {
      alert("you've reached the end of the fragment! your media is now paused automatically!");
    });
  });
</script>

I tried to make use of "ontimeupdate" event, but refused: I want to react exactly when an automatic pause (caused by reaching the end of a fragment) takes place.我试图利用“ontimeupdate”事件,但被拒绝:我想在自动暂停(由到达片段末尾引起)发生时做出准确的反应。

An ended event will only be issued when the complete track has finished.只有在完整轨道完成后才会发出结束事件。 When you play a fragment it will only pause the track at the end of the fragment as the track itself has not ended (unless the end time for the fragment happened to be the end as well).当您播放片段时,它只会在片段末尾暂停曲目,因为曲目本身尚未结束(除非片段的结束时间恰好也是结束时间)。

A media element is said to have paused for user interaction when its paused attribute is false, the readyState attribute is either HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA and the user agent has reached a point in the media resource where the user has to make a selection for the resource to continue.当一个媒体元素的 paused 属性为 false,readyState 属性为 HAVE_FUTURE_DATA 或 HAVE_ENOUGH_DATA 并且用户代理已经到达媒体资源中的一个点,用户必须为资源做出选择时,就说它已暂停以进行用户交互继续。

The ended event will only occur if:只有在以下情况下才会发生结束事件:

A media element is said to have ended playback when:在以下情况下,媒体元素被称为已结束播放:

The element's readyState attribute is HAVE_METADATA or greater, and元素的 readyState 属性为 HAVE_METADATA 或更大,并且

Either:任何一个:

  • The current playback position is the end of the media resource, and当前播放位置是媒体资源的结尾,并且
  • The direction of playback is forwards, and播放方向为向前,并且
  • Either the media element does not have a loop attribute specified, or the media element has a current media controller.媒体元素没有指定循环属性,或者媒体元素具有当前的媒体控制器。
Or: 或者:
  • The current playback position is the earliest possible position, and当前播放位置是最早的可能位置,并且
  • The direction of playback is backwards.播放方向为倒退。

Source 来源

To detect if the pause event was triggered due to end of fragment you can compare the currentTime with the fragment end-time (and yes, there is a theoretical chance that you could hit the pause button at exactly this time as well, but this will be as close as you get with the audio element unless the event itself has a secret property revealing the source of pause, of which I am unaware of).要检测是否由于片段结束而触发了暂停事件,您可以将 currentTime 与片段结束时间进行比较(是的,理论上您也可以在此时按下暂停按钮,但这将尽可能接近音频元素,除非事件本身具有揭示暂停来源的秘密属性,我不知道)。

Since we're dealing with floating point values you need to compare the time using an epsilon.由于我们正在处理浮点值,因此您需要使用 epsilon 来比较时间。 Assuming you parse or other wise have a way to get the end-time for the fragment, you can do:假设您解析或以其他方式获得片段的结束时间,您可以执行以下操作:

function onPauseHandler(e) {
    var fragmentEndTime = ...;   // get/parse end-fragment into this var
    if (isEqual(this.currentTime, fragmentEndTime)) {
      // likely that fragment ended
    }
    else {
      // a manual pause
    }
}

function isEqual(n1, n2) {
   return Math.abs(n1 - n2) < 0.00001
}

This came up for me today when searching for "why does onpause also fire when onended occurs".今天在搜索“为什么 onpause 在 onended 发生时也会触发”时,我想到了这一点。 I wanted to separate the logic between an onpause event and on onended event.我想将 onpause 事件和 onended 事件之间的逻辑分开。

This was my take on it:这是我的看法:

videoRef.onpause = (e) => {
  if (e.target.currentTime != e.target.duration) {
    // handleOnPause();
  }
}

I have both onpause and onended handlers registered, with onpause running code when it's not at the end of the video.我同时注册了onpauseonended处理程序,当它不在视频末尾时, onpause运行代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM