javascript - 在浏览器中录制音频和视频
问题描述
嗨,我需要在前端录制从服务器流式传输到浏览器的音频和视频内容我找到了一些有关MediaStreams的信息,所以我做到了,似乎我没有录制我的 html 视频和音频输出,而是相机输出
<audio id="audio" autoplay="true"></audio>
<video id="video" autoplay="true" playsinline="true" controls></video>
var constraints = {
audio: true,
video: true,
};
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStreamObj) {
let start = document.getElementById('btnStart');
let stop = document.getElementById('btnStop');
let vidSave = document.getElementById('vid2');
let mediaRecorder = new MediaRecorder(mediaStreamObj);
let chunks = [];
start.addEventListener('click', (ev)=>{
mediaRecorder.start();
console.log(mediaRecorder.state);
})
stop.addEventListener('click', (ev)=>{
mediaRecorder.stop();
console.log(mediaRecorder.state);
});
mediaRecorder.ondataavailable = function(ev) {
chunks.push(ev.data);
}
mediaRecorder.onstop = (ev)=>{
let blob = new Blob(chunks, { 'type' : 'video/mp4;' });
chunks = [];
let videoURL = window.URL.createObjectURL(blob);
vidSave.src = videoURL;
}
})
.catch(function(err) {
console.log(err.name, err.message);
});
}
感谢任何帮助,因为我想以干净的方式做到这一点,但现在我看到的唯一选择是记录整个浏览器窗口
解决方案
好吧,我猜您的目标是类似网络摄像头的设置,所以这在服务器上有效,请记住,除非您通过服务器托管 HTML,否则您无法下载视频/音频。但是,在对文件进行测试时它不起作用:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
body {
padding: 0;
margin: 0;
}
svg:not(:root) {
display: block;
}
.playable-code {
background-color: #f4f7f8;
border: none;
border-left: 6px solid #558abb;
border-width: medium medium medium 6px;
color: #4d4e53;
height: 100px;
width: 90%;
padding: 10px 10px 0;
}
.playable-canvas {
border: 1px solid #4d4e53;
border-radius: 2px;
}
.playable-buttons {
text-align: right;
width: 90%;
padding: 5px 10px 5px 26px;
}
</style>
<style type="text/css">
body {
font: 14px "Open Sans", "Arial", sans-serif;
}
video {
margin-top: 2px;
border: 1px solid black;
}
.button {
cursor: pointer;
display: block;
width: 160px;
border: 1px solid black;
font-size: 16px;
text-align: center;
padding-top: 2px;
padding-bottom: 4px;
color: white;
background-color: darkgreen;
text-decoration: none;
}
h2 {
margin-bottom: 4px;
}
.left {
margin-right: 10px;
float: left;
width: 160px;
padding: 0px;
}
.right {
margin-left: 10px;
float: left;
width: 160px;
padding: 0px;
}
.bottom {
clear: both;
padding-top: 10px;
}
</style>
<title>Recording a media element - Example - code sample</title>
</head>
<body>
<p>Click the "Start" button to begin video recording for a few seconds. You can stop
the video by clicking the creatively-named "Stop" button. The "Download"
button will download the received data (although it's in a raw, unwrapped form
that isn't very useful).
</p>
<br>
<div class="left">
<div id="startButton" class="button">
Start
</div>
<h2>Preview</h2>
<video id="preview" width="160" height="120" autoplay muted></video>
</div>
<div class="right">
<div id="stopButton" class="button">
Stop
</div>
<h2>Recording</h2>
<video id="recording" width="160" height="120" controls></video>
<a id="downloadButton" class="button">
Download
</a>
</div>
<div class="bottom">
<pre id="log"></pre>
</div>
<script>
let preview = document.getElementById("preview");
let recording = document.getElementById("recording");
let startButton = document.getElementById("startButton");
let stopButton = document.getElementById("stopButton");
let downloadButton = document.getElementById("downloadButton");
let logElement = document.getElementById("log");
let recordingTimeMS = 5000;
function log(msg) {
logElement.innerHTML += msg + "\n";
}
function wait(delayInMS) {
return new Promise(resolve => setTimeout(resolve, delayInMS));
}
function startRecording(stream, lengthInMS) {
let recorder = new MediaRecorder(stream);
let data = [];
recorder.ondataavailable = event => data.push(event.data);
recorder.start();
log(recorder.state + " for " + (lengthInMS/1000) + " seconds...");
let stopped = new Promise((resolve, reject) => {
recorder.onstop = resolve;
recorder.onerror = event => reject(event.name);
});
let recorded = wait(lengthInMS).then(
() => recorder.state == "recording" && recorder.stop()
);
return Promise.all([
stopped,
recorded
])
.then(() => data);
}
function stop(stream) {
stream.getTracks().forEach(track => track.stop());
}
startButton.addEventListener("click", function() {
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
preview.srcObject = stream;
downloadButton.href = stream;
preview.captureStream = preview.captureStream || preview.mozCaptureStream;
return new Promise(resolve => preview.onplaying = resolve);
}).then(() => startRecording(preview.captureStream(), recordingTimeMS))
.then (recordedChunks => {
let recordedBlob = new Blob(recordedChunks, { type: "video/webm" });
recording.src = URL.createObjectURL(recordedBlob);
downloadButton.href = recording.src;
downloadButton.download = "RecordedVideo.webm";
log("Successfully recorded " + recordedBlob.size + " bytes of " +
recordedBlob.type + " media.");
})
.catch(log);
}, false);
stopButton.addEventListener("click", function() {
stop(preview.srcObject);
}, false);
</script>
</body>
</html>
如果您在服务器上托管,这将起作用,就像我说的那样,所以假设您是,这就是您的代码。如果您还没有设置服务器,请考虑使用我个人最喜欢的Python和Flask 。
顺便说一下,上面的代码来自 MDN Web Docs。在这里您可以找到完整的教程和代码:https ://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API/Recording_a_media_element 。
谢谢,我希望这对你有帮助,如果没有,请告诉我!
推荐阅读
- sql - Google Cloud SQL 导入 2005 备份失败
- python-3.x - AttributeError:“NoneType”对象没有属性“image_data_format”keras
- python - ImportError:没有名为“dask.dataframe”的模块;
- r - 如何使 purrr 包中的 map_df 返回一个小标题?
- mysql - 在 mysql phpmyadmin 中创建过程时出错
- java - 而 True 循环阻止应用程序加载:Java Netbeans
- css - VSCODE 上的 JAVA FX css 编辑器警告
- reactjs - React Material UI 防止列表重新渲染
- reactjs - (React.js) 冒泡排序问题
- java - HashiCorp Vault + Spring Boot。客户端 SSL 配置