JSFiddle - React, Tailwind, and code Playground
by mamounothman
HTML
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1"
/>
<title>MediaStream Recording -> MediaSource</title>
<link rel="stylesheet" href="main.css" />
</head>
<body>
<div id="container">
<video id="gum" playsinline="" autoplay="" muted=""></video>
<video id="recorded" playsinline="" src="" controls=""></video>
<div>
<button id="record">Start</button>
</div>
</div>
<script src="main.js" async=""></script>
</body>
</html>
CSS
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree.
*/
.hidden {
display: none;
}
.highlight {
background-color: #eee;
font-size: 1.2em;
margin: 0 0 30px 0;
padding: 0.2em 1.5em;
}
.warning {
color: red;
font-weight: 400;
}
@media screen and (min-width: 1000px) {
/* hack! to detect non-touch devices */
div#links a {
line-height: 0.8em;
}
}
audio {
max-width: 100%;
}
body {
font-family: "Roboto", sans-serif;
font-weight: 300;
margin: 0;
padding: 1em;
word-break: break-word;
}
button {
background-color: #d84a38;
border: none;
border-radius: 2px;
color: white;
font-family: "Roboto", sans-serif;
font-size: 0.8em;
margin: 0 0 1em 0;
padding: 0.5em 0.7em 0.6em 0.7em;
}
button:active {
background-color: #cf402f;
}
button:hover {
background-color: #cf402f;
}
button[disabled] {
color: #ccc;
}
button[disabled]:hover {
background-color: #d84a38;
}
canvas {
background-color: #ccc;
max-width: 100%;
width: 100%;
}
code {
font-family: "Roboto", sans-serif;
font-weight: 400;
}
div#container {
margin: 0 auto 0 auto;
max-width: 60em;
padding: 1em 1.5em 1.3em 1.5em;
}
div#links {
padding: 0.5em 0 0 0;
}
h1 {
border-bottom: 1px solid #ccc;
font-family: "Roboto", sans-serif;
font-weight: 500;
margin: 0 0 0.8em 0;
padding: 0 0 0.2em 0;
}
h2 {
color: #444;
font-weight: 500;
}
h3 {
border-top: 1px solid #eee;
color: #666;
font-weight: 500;
margin: 10px 0 10px 0;
white-space: nowrap;
}
li {
margin: 0 0 0.4em 0;
}
html {
/* avoid annoying page width change
when moving from the home page */
overflow-y: scroll;
}
img {
border: none;
max-width: 100%;
}
input[type="radio"] {
position: relative;
top: -1px;
}
p {
color: #444;
font-weight: 300;
}
p#data {
border-top: 1px dotted #666;
...
JavaScript
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree.
*/
"use strict";
const mediaSource = new MediaSource();
mediaSource.addEventListener("sourceopen", handleSourceOpen);
mediaSource.addEventListener("sourceclose", () =>
console.log("mediaSource closed")
);
mediaSource.addEventListener("sourceended", () =>
console.log("mediaSource ended")
);
let mediaRecorder;
let recordedBlobs;
let sourceBuffer;
let updatingBuffer = false;
let options;
const constraints = {
audio: true,
video: {
width: 1280,
height: 720
}
};
let userMediaStream;
const recordedVideo = document.querySelector("video#recorded");
const recordButton = document.querySelector("button#record");
recordButton.addEventListener("click", () => {
if (recordButton.textContent === "Start") {
startRecording();
} else {
stopRecording();
recordButton.textContent = "Start";
}
});
function handleSourceOpen(event) {
console.log("MediaSource opened");
sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vp9"');
sourceBuffer.addEventListener("update", () => {
console.log("sourceBuffer update");
});
sourceBuffer.addEventListener("error", e =>
console.log(`sourceBuffer error: ${JSON.stringify(e, null, 2)}`)
);
console.log("Source buffer: ", sourceBuffer);
sourceBuffer.addEventListener("abort", () =>
console.log("sourceBuffer abort")
);
sourceBuffer.addEventListener("updatestart", () =>
console.log("sourceBuffer update start")
);
sourceBuffer.addEventListener("updateend", () => {
console.log("sourceBuffer update end");
updatingBuffer = false;
});
}
async function handleDataAvailable(event) {
// console.log("handleDataAvailable", event);
if (event.data && event.data.size > 0) {
recordedBlobs.push(event.data);
}
if (recordedBlobs.length > 5) {
if...