【问题标题】:Pause the stream returned by getUserMedia暂停 getUserMedia 返回的流
【发布时间】:2018-04-20 05:47:07
【问题描述】:

我已将 getUserMedia 返回的流引导到 html 页面中的 <video> 元素,现在可以在该元素中看到视频。问题是,如果我从视频元素的控件中暂停视频,然后在 x 秒后恢复,那么视频元素中显示的计时器将跳转到 pauseTime + x 秒。我猜这是因为当我们暂停视频元素中的播放时,流没有暂停。如果可以,我们也可以暂停直播。

【问题讨论】:

    标签: javascript html html5-video getusermedia


    【解决方案1】:

    看起来MediaStreamTrack.enabled 可以切换为暂时暂停视频流。

    MediaStreamTrack 接口上的 enabled 属性是一个布尔值,如果允许轨道呈现源流,则为 true,否则为 false。这可用于有意使轨道静音。启用后,轨道的数据会从源输出到目标;否则,输出空帧。

    【讨论】:

      【解决方案2】:
      // using `await`, remember to use `async function(){}` as needed, or switch to Promise().then() if desired...
      const myStream = await navigator.mediaDevices.getUserMedia({audio: true, video: true})
      const myTracks = myStream.getTracks();
      const myAudio = myTracks.filter(track => track.kind === "audio")[0];
      const myVideo = myTracks.filter(track => track.kind === "video")[0];
      
      function toggleTrackMute(track) {
        track.enabled = !track.enabled;
        console.log(`${track.enabled ? 'unmuted' : 'muted'} track.kind`);
      }
      
      toggleTrackMute(myAudio)
      

      【讨论】:

        【解决方案3】:

        免责声明

        这个答案回答了另一个问题... 我当时误解了 OP 的问题,并假设他们想“暂停”流,以便以后能够在同一时间点恢复它。
        那里所有出现的“暂停”都假定了这个定义,并且与 OP 愿意阻止流提供 MediaElement 的 currentTime 没有太大关系。对于这种情况,请参阅其他答案。 (我不能自己删除这个,因为它目前已被接受)


        这就是 Streams 的特性,你不能暂停它们...

        但是你可以做的是缓冲这个流,然后播放你缓冲的内容。

        要使用 MediaStream 实现此目的,您可以使用 MediaRecorder API 以及 MediaSource API

        但请注意,现在,您显然会比直接读取流时获得更多延迟。

        navigator.mediaDevices.getUserMedia({
            video: true
          })
          .then(stream => {
            const mediaSource = new MediaSource();
            let data, sourceBuffer;
            vid.src = URL.createObjectURL(mediaSource);
            mediaSource.addEventListener('sourceopen', sourceOpen);
        
            const recorder = new MediaRecorder(stream, {
              mimeType: 'video/webm; codecs="vp8"'
            });
            const chunks = [];
            recorder.ondataavailable = e => push(e.data);
        
            function push(data) {
              if (mediaSource.readyState !== "open") return;
              let fr = new FileReader();
              fr.onload = e => sourceBuffer.appendBuffer(fr.result);
              fr.readAsArrayBuffer(new Blob([data]));
            }
        
            function sourceOpen(_) {
              recorder.start(50);
              sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vp8"');
              vid.play();
            }
        
          });
        <video id="vid" controls></video>

        还有as a fiddle,因为 StackSnippets 对 gUM 不太友好。

        【讨论】:

        • 这解决了问题,但我发现有一个问题,那就是暂停一次会使视频开始显示陈旧的录制,相机前面的任何东西都不再在视频元素中,我们可以也跳过我们暂停视频时的缓冲区。
        • @MohdRizwan 你是什么意思?您在此评论中描述的只是显示 MediaStream 的默认行为,不是吗?。
        • 但是你想要完全禁用暂停?
        • @Rizvan 很明显,我在回答你的问题时误解了你的问题,你能不接受吗?看来 Stan James 的回答更适合您的需求。
        • @Kaiido,您可能会更新您的答案以反映您正在回答一个关于如何在这种特定意义上暂停的问题的具体看法,并指向另一个答案(并删除声明'您不能暂停流”,这可能会误导阅读已接受答案第一句话的人)。
        猜你喜欢
        • 2021-06-12
        • 1970-01-01
        • 1970-01-01
        • 2016-12-17
        • 2012-09-18
        • 1970-01-01
        • 2019-05-06
        • 1970-01-01
        • 2023-03-05
        相关资源
        最近更新 更多