使用 Html 5 我想录制视频并将流保存到本地文件中。下面给出的是代码。单击按钮即可调用相机并捕获 HTML 的“VIDEO”标签中的视频。我可以将流存储到本地文件中吗?或者我可以将其存储为 MP4 文件吗?
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function enter() {
if (navigator.mozGetUserMedia) {
navigator.myGetMedia=navigator.mozGetUserMedia;
navigator.myGetMedia({video: true}, connect, error);
}
else {
alert("NO");
}
function connect(stream) {
var video = document.getElementById("my_video");
video.src = window.URL ? window.URL.createObjectURL(stream) : stream;
video.play();
var canvas = document.getElementById("c");
}
function error(e) { console.log(e); }
}
</script>
</head>
<body>
<canvas width="640" height="480" id="c"></canvas>
<input type="button" value="RECORD" onClick="enter()"/>
<input type="button" value="SAVE" />
<video id="my_video" width="640" height="480"/>
</body>
</html>
我想在单击保存按钮时保存流。
RecordRTC:WebRTC 音频/视频录制
https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RecordRTC
演示:https://www.webrtc-experiment.com/RecordRTC/
从 getUserMedia() 创建 .webm 视频
http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia
演示:http://html5-demos.appspot.com/static/getusermedia/record-user-webm.html
在 HTML5 中捕获音频和视频
MediaRecorder API 是您正在寻找的解决方案,
Firefox 已经支持它有一段时间了,传闻 Chrome 将在其下一个版本(Chrome 48)中实现它,但我猜你可能仍然需要启用实验标志,显然不需要该标志从 Chrome 版本 49 开始,有关更多信息,请查看此 Chrome 问题。
同时,还有一个如何在 Firefox 中执行此操作的示例:
var video, reqBtn, startBtn, stopBtn, ul, stream, recorder;
video = document.getElementById('video');
reqBtn = document.getElementById('request');
startBtn = document.getElementById('start');
stopBtn = document.getElementById('stop');
ul = document.getElementById('ul');
reqBtn.onclick = requestVideo;
startBtn.onclick = startRecording;
stopBtn.onclick = stopRecording;
startBtn.disabled = true;
ul.style.display = 'none';
stopBtn.disabled = true;
function requestVideo() {
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
})
.then(stm => {
stream = stm;
reqBtn.style.display = 'none';
startBtn.removeAttribute('disabled');
video.src = URL.createObjectURL(stream);
}).catch(e => console.error(e));
}
function startRecording() {
recorder = new MediaRecorder(stream, {
mimeType: 'video/mp4'
});
recorder.start();
stopBtn.removeAttribute('disabled');
startBtn.disabled = true;
}
function stopRecording() {
recorder.ondataavailable = e => {
ul.style.display = 'block';
var a = document.createElement('a'),
li = document.createElement('li');
a.download = ['video_', (new Date() + '').slice(4, 28), '.webm'].join('');
a.href = URL.createObjectURL(e.data);
a.textContent = a.download;
li.appendChild(a);
ul.appendChild(li);
};
recorder.stop();
startBtn.removeAttribute('disabled');
stopBtn.disabled = true;
}
<div>
<button id='request'>
Request Camera
</button>
<button id='start'>
Start Recording
</button>
<button id='stop'>
Stop Recording
</button>
<ul id='ul'>
Downloads List:
</ul>
</div>
<video id='video' autoplay></video>
目前还没有用于通过网络录制视频的生产就绪的仅限 HTML5 解决方案。目前可用的解决方案如下:
HTML 媒体捕获
适用于移动设备,并使用操作系统的视频捕获应用程序来捕获视频并将其上传/发布到网络服务器。您将在 iOS 上获得 .mov 文件(这些文件在我尝试过的 Android 上无法播放),在 Android 上获得 .mp4 和 .3gp。至少编解码器将是相同的:99% 的设备中用于视频的 H.264 和用于音频的 AAC。
图片由https://blog.addpipe.com/the-new-video-recording-prompt-for-media-capture-in-ios9/
提供桌面上的 Flash 和媒体服务器。
Flash 中的视频录制工作原理如下:从网络摄像头和麦克风捕获音频和视频数据,使用 Sorenson Spark 或 H.264(视频)和 Nellymoser Asao 或 Speex(音频)进行编码,然后将其流式传输 (rtmp) 到媒体服务器(Red5、AMS、Wowza),它保存在 .flv 或 .f4v 文件中。
MediaStream 录制提案
MediaStream Recording 是媒体捕获任务组(WebRTC 和设备 API 工作组之间的联合任务组)针对 JS API 提出的一项提案,其目的是使浏览器中的基本视频录制变得非常简单。
主流浏览器不支持。当它实现时(如果会的话),您很可能最终会得到不同的文件类型(至少 .ogg 和 .webm)和音频/视频编解码器,具体取决于浏览器。
商业解决方案
有一些 SaaS 和软件解决方案可以处理上述部分或全部问题,包括 addpipe.com、HDFVR、Nimbb 和 Cameratag。
进一步阅读:
以下示例展示了如何在 HTML5 中捕获和处理视频帧:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Capturing & Processing Video in HTML5</title>
</head>
<body>
<div>
<h2>Camera Preview</h2>
<video id="cameraPreview" width="240" height="180" autoplay></video>
<p>
<button id="startButton" onclick="startCapture();">Start Capture</button>
<button id="stopButton" onclick="stopCapture();">Stop Capture</button>
</p>
</div>
<div>
<h2>Processing Preview</h2>
<canvas id="processingPreview" width="240" height="180"></canvas>
</div>
<div>
<h2>Recording Preview</h2>
<video id="recordingPreview" width="240" height="180" autoplay controls></video>
<p>
<a id="downloadButton">Download</a>
</p>
</div>
<script>
const ROI_X = 250;
const ROI_Y = 150;
const ROI_WIDTH = 240;
const ROI_HEIGHT = 180;
const FPS = 25;
let cameraStream = null;
let processingStream = null;
let mediaRecorder = null;
let mediaChunks = null;
let processingPreviewIntervalId = null;
function processFrame() {
let cameraPreview = document.getElementById("cameraPreview");
processingPreview
.getContext('2d')
.drawImage(cameraPreview, ROI_X, ROI_Y, ROI_WIDTH, ROI_HEIGHT, 0, 0, ROI_WIDTH, ROI_HEIGHT);
}
function generateRecordingPreview() {
let mediaBlob = new Blob(mediaChunks, { type: "video/webm" });
let mediaBlobUrl = URL.createObjectURL(mediaBlob);
let recordingPreview = document.getElementById("recordingPreview");
recordingPreview.src = mediaBlobUrl;
let downloadButton = document.getElementById("downloadButton");
downloadButton.href = mediaBlobUrl;
downloadButton.download = "RecordedVideo.webm";
}
function startCapture() {
const constraints = { video: true, audio: false };
navigator.mediaDevices.getUserMedia(constraints)
.then((stream) => {
cameraStream = stream;
let processingPreview = document.getElementById("processingPreview");
processingStream = processingPreview.captureStream(FPS);
mediaRecorder = new MediaRecorder(processingStream);
mediaChunks = []
mediaRecorder.ondataavailable = function(event) {
mediaChunks.push(event.data);
if(mediaRecorder.state == "inactive") {
generateRecordingPreview();
}
};
mediaRecorder.start();
let cameraPreview = document.getElementById("cameraPreview");
cameraPreview.srcObject = stream;
processingPreviewIntervalId = setInterval(processFrame, 1000 / FPS);
})
.catch((err) => {
alert("No media device found!");
});
};
function stopCapture() {
if(cameraStream != null) {
cameraStream.getTracks().forEach(function(track) {
track.stop();
});
}
if(processingStream != null) {
processingStream.getTracks().forEach(function(track) {
track.stop();
});
}
if(mediaRecorder != null) {
if(mediaRecorder.state == "recording") {
mediaRecorder.stop();
}
}
if(processingPreviewIntervalId != null) {
clearInterval(processingPreviewIntervalId);
processingPreviewIntervalId = null;
}
};
</script>
</body>
</html>
这是一个优雅的库,可以在所有支持的浏览器中录制视频并支持上传: