- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我需要做以下事情:
从 <video>
获取视频在<canvas>
里面玩
将来自 Canvas 的流记录为 Blob
就是这样。第一部分没问题。
对于第二部分,我设法记录了一个 Blob。问题是 Blob 是空的。
<video id="video" controls="true" src="http://upload.wikimedia.org/wikipedia/commons/7/79/Big_Buck_Bunny_small.ogv"></video>
<canvas id="myCanvas" width="532" height="300"></canvas>
// Init
console.log(MediaRecorder.isTypeSupported('video/webm')) // true
const canvas = document.querySelector("canvas")
const ctx = canvas.getContext("2d")
const video = document.querySelector("video")
// Start the video in the player
video.play()
// On play event - draw the video in the canvas
video.addEventListener('play', () => {
function step() {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
requestAnimationFrame(step)
}
requestAnimationFrame(step);
// Init stream and recorder
const stream = canvas.captureStream()
const recorder = new MediaRecorder(stream, {
mimeType: 'video/webm',
});
// Get the blob data when is available
let allChunks = [];
recorder.ondataavailable = function(e) {
console.log({e}) // img1
allChunks.push(e.data);
}
// Start to record
recorder.start()
// Stop the recorder after 5s and check the result
setTimeout(() => {
recorder.stop()
const fullBlob = new Blob(allChunks, { 'type' : 'video/webm' });
const downloadUrl = window.URL.createObjectURL(fullBlob)
console.log({fullBlob}) // img2
}, 5000);
})
这是 console.log
的 ondataavailable
事件:
这是 console.log
Blob 的:
这是 JSFiddle。您可以在控制台中查看结果:
https://jsfiddle.net/1b7v2pen/
这种行为(Blob 数据大小:0)发生在 Chrome 和 Opera 上。
在 Firefox 上它的行为略有不同。它记录了一个非常小的视频 Blob(725 字节)。视频长度应该是 5 秒,但它只是一个黑屏。
从 Canvas 记录流的正确方法是什么?
代码有问题吗?
为什么 Blob 出来是空的?
最佳答案
MediaRecorder.stop()
是一种异步方法。
在 stop 算法中,有一个对 requestData 的调用,它本身将排队任务以触发事件 dataavailable自上次此类事件以来的可用数据。
这意味着在您调用 MediaRecorder#stop() 之后同步获取的最后数据还不会成为您的 allChunks
数组的一部分。它们会在不久之后变为(通常在同一个事件循环中)。
因此,当您要保存从 MediaRecorder 制作的记录时,请务必始终从 MediaRecorder's onstop
构建最终的 Blob。表示 MediaRecorder 实际结束的事件确实触发了它的最后一个 dataavailable 事件,并且一切都很好。
一开始我错过了一件事,就是您请求的是跨域视频。如果没有正确的跨源请求,这样做会使您的 Canvas (和 MediaElement)受到污染,因此您的 MediaStream 将被静音。
由于您尝试请求的视频来自维基媒体,您可以简单地将其作为跨源资源请求,但对于其他资源,您必须确保服务器配置为允许这些请求。
const canvas = document.querySelector("canvas")
const ctx = canvas.getContext("2d")
const video = document.querySelector("video")
// Start the video in the player
video.play()
// On play event - draw the video in the canvas
video.addEventListener('play', () => {
function step() {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
requestAnimationFrame(step)
}
requestAnimationFrame(step);
// Init stream and recorder
const stream = canvas.captureStream()
const recorder = new MediaRecorder(stream, {
mimeType: 'video/webm',
});
// Get the blob data when is available
let allChunks = [];
recorder.ondataavailable = function(e) {
allChunks.push(e.data);
}
recorder.onstop = (e) => {
const fullBlob = new Blob(allChunks, { 'type' : 'video/webm' });
const downloadUrl = window.URL.createObjectURL(fullBlob)
console.log({fullBlob})
console.log({downloadUrl})
}
// Start to record
recorder.start()
// Stop the recorder after 5s and check the result
setTimeout(() => {
recorder.stop()
}, 5000);
})
<!--add the 'crossorigin' attribute to your video -->
<video id="video" controls="true" src="https://upload.wikimedia.org/wikipedia/commons/7/79/Big_Buck_Bunny_small.ogv" crossorigin="anonymous"></video>
<canvas id="myCanvas" width="532" height="300"></canvas>
此外,我不得不指出,如果您不从您的 Canvas 上做任何特殊的绘图,您可能希望直接保存视频源,或者至少,录制
关于javascript - 如何正确录制 MediaStream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52512996/
我正在尝试记录远程用户的媒体流。从远程用户传递的Media Stream对象似乎与从getUserMedia生成的本地Media Stream对象非常相似,但是将其传递到Media Stream可视化
情况 我需要做以下事情: 从 获取视频在里面玩 将来自 Canvas 的流记录为 Blob 就是这样。第一部分没问题。 对于第二部分,我设法记录了一个 Blob。问题是 Blob 是空的。 View
大多数 Mediastream 示例由 webCam-stream 解释。但我需要从本地视频文件(.webm 或 mp4)创建 MediaStream。请告诉我。 最佳答案 2017 年 5 月 4
我想要一些关于如何在 Chrome/Canary 中最好地获取音频 MediaStreamTrack javascript 对象的麦克风事件级别的建议。 MediaStreamTrack 对象是 ge
好的,我将尝试尽可能清楚地说明我的问题,但我很困惑,所以如果我没有传达信息,请告诉我。 我正在尝试使用 getUserMedia 来使用网络摄像头,然后使用这个 http://www.w3.org/T
我需要使用来自不同 MediaStreams 的音频和视频创建一个 MediaStream。在 Firefox 中,我可以从轨道数组中实例化一个新的 MediaStream: var output
在 Electron 中,我可以获得 MediaStream 对象,但如何将其转换为可读流。 MediaStream 没有管道方法,如何读取? const { desktopCapturer } =
我目前正在构建一个 WebRTC 应用程序,并希望收集一些统计数据来评价我的解决方案。我感兴趣的一个指标是接收到的音频(和视频)流的当前带宽。我能够在 chrome://webrtc-internal
我目前正在构建一个 WebRTC 应用程序,并希望收集一些统计数据来评价我的解决方案。我感兴趣的一个指标是接收到的音频(和视频)流的当前带宽。我能够在 chrome://webrtc-internal
在我的网络应用程序中,我获得了 MediaStream通过getUserMedia或 getDisplayMedia .在某些情况下,该流的视频轨道可以改变其大小。例如,如果 getDisplayMe
我正在尝试从网站用户的手机捕获音频,并将其传输到远程 RTCPeerConnection。 假设我有一个获取本地MediaStream的函数: function getLocalAudioStream
我正在创建一个 MediaStream 对象,并使用 captureStream() 函数从 Canvas 向其添加视频轨道。这很好用。 但是我正在尝试将音频添加为与视频元素分开的轨道。我似乎找不到从
我创建了一个非常基本的 WebRTC 视频聊天界面(仅限 Chrome 测试)。我通过 websockets 向 SDP 发送信号,并使用 Twilio 服务进行 STUN/TURN 配置。 “off
我目前有一个函数可以从 navigator.getUserMedia() 接收 MediaStream,效果很好。我想提供上传音频文件并通过相同功能模拟它的选项。我想知道是否可以上传一个音频文件并创建
我有多个 NodeJS Node 捕获一系列图像。有时他们需要通过 WebRTC 发送数据对一些浏览器同行。 我目前正在通过对图像进行 Base64 编码来处理问题,通过 DataChannel 发送
我对 WebRTC 和 Node.js 完全陌生,我试图使用教程 http://www.tutorialspoint.com/webrtc/webrtc_media_stream_apis.htm 构
我有一个远程 MediaStream 对象,通过远程WebRTC Peer Connection 获得。 我想检查远程何时 MediaStream 变为非事件状态(独立于原因)。 我已经读到,为此我应
简而言之:我正在尝试更改 MediaStream 对象的 VideoTrack。 (文档:https://developer.mozilla.org/en-US/docs/WebRTC/MediaSt
我正在从事一个项目,我想: 加载视频 js 并将其显示在 Canvas 上。 使用滤镜改变 Canvas (以及视频)的外观。 使用 MediaStream captureStream() 方法和 M
我想从音频/视频流更改为“屏幕共享”流: peerConnection.removeStream(streamA) // __o_j_sep... in Screenshots below peerC
我是一名优秀的程序员,十分优秀!