fix recording duration and make it seekable
This commit is contained in:
parent
e2ec7d12b8
commit
74d73b89c6
3 changed files with 1528 additions and 27 deletions
1508
package-lock.json
generated
1508
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -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": {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue