fix recording duration and make it seekable

This commit is contained in:
MarconLP 2023-08-12 19:40:55 +02:00
parent e2ec7d12b8
commit 74d73b89c6
No known key found for this signature in database
GPG key ID: A08A9C8B623F5EA5
3 changed files with 1528 additions and 27 deletions

1508
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -38,8 +38,8 @@
"axios": "^1.3.5",
"crisp-sdk-web": "^1.0.18",
"dayjs": "^1.11.7",
"ebml": "^3.0.0",
"file-saver": "^2.0.5",
"fix-webm-duration": "^1.0.5",
"jotai": "^2.0.4",
"micro": "^10.0.1",
"micro-cors": "^0.1.1",
@ -56,6 +56,7 @@
"stripe": "^12.12.0",
"superjson": "1.12.2",
"tailwindcss-radix": "^2.8.0",
"ts-ebml": "^2.0.2",
"zod": "^3.21.4"
},
"devDependencies": {

View file

@ -10,14 +10,14 @@ import axios from "axios";
import dayjs from "dayjs";
import { useRouter } from "next/router";
import { api } from "~/utils/api";
import fixWebmDuration from "fix-webm-duration";
import { TRPCClientError } from "@trpc/client";
import { useAtom } from "jotai/index";
import { useAtom } from "jotai";
import paywallAtom from "~/atoms/paywallAtom";
import recordVideoModalOpen from "~/atoms/recordVideoModalOpen";
import { usePostHog } from "posthog-js/react";
import Tooltip from "~/components/Tooltip";
import generateThumbnail from "~/utils/generateThumbnail";
import * as EBML from "ts-ebml";
interface Props {
closeModal: () => void;
@ -103,17 +103,43 @@ export default function Recorder({ closeModal, step, setStep }: Props) {
posthog?.capture("recorder: start video recording");
};
function getSeekableBlob(inputBlob: Blob, callback: (blob: Blob) => void) {
const reader = new EBML.Reader();
const decoder = new EBML.Decoder();
const tools = EBML.tools;
const fileReader = new FileReader();
fileReader.onload = function (e) {
if (!this.result || typeof this.result === "string") return;
const ebmlElms = decoder.decode(this.result);
ebmlElms.forEach(function (element) {
reader.read(element);
});
reader.stop();
const refinedMetadataBuf = tools.makeMetadataSeekable(
reader.metadatas,
duration * 1000,
reader.cues
);
const body = this.result.slice(reader.metadataSize);
const newBlob = new Blob([refinedMetadataBuf, body], {
type: "video/webm",
});
callback(newBlob);
};
fileReader.readAsArrayBuffer(inputBlob);
}
const handleStop = () => {
if (recorderRef.current === null) return;
recorderRef.current.stopRecording(() => {
if (recorderRef.current) {
fixWebmDuration(
recorderRef.current.getBlob(),
duration * 1000,
(seekableBlob) => {
setBlob(seekableBlob);
}
);
getSeekableBlob(recorderRef.current.getBlob(), function (fixedBlob) {
setBlob(fixedBlob);
});
steam?.getTracks().map((track) => track.stop());
}
});