add ability to download and upload recorded video
This commit is contained in:
parent
fff2e44a0f
commit
58739430a5
2 changed files with 44 additions and 14 deletions
|
|
@ -6,6 +6,10 @@ import { MicrophoneIcon, PauseIcon } from "@heroicons/react/24/outline";
|
||||||
import { ResumeIcon, TrashIcon } from "@radix-ui/react-icons";
|
import { ResumeIcon, TrashIcon } from "@radix-ui/react-icons";
|
||||||
import { StopIcon } from "@heroicons/react/24/solid";
|
import { StopIcon } from "@heroicons/react/24/solid";
|
||||||
import StopTime from "~/components/StopTime";
|
import StopTime from "~/components/StopTime";
|
||||||
|
import axios from "axios";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { api } from "~/utils/api";
|
||||||
|
|
||||||
export default function Recorder() {
|
export default function Recorder() {
|
||||||
const [steam, setStream] = useState<null | MediaStream>(null);
|
const [steam, setStream] = useState<null | MediaStream>(null);
|
||||||
|
|
@ -18,6 +22,10 @@ export default function Recorder() {
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
const [step, setStep] = useState<"pre" | "in" | "post">("pre");
|
const [step, setStep] = useState<"pre" | "in" | "post">("pre");
|
||||||
|
const router = useRouter();
|
||||||
|
const [submitting, setSubmitting] = useState<boolean>(false);
|
||||||
|
const apiUtils = api.useContext();
|
||||||
|
const getSignedUrl = api.video.getUploadUrl.useMutation();
|
||||||
|
|
||||||
const handleRecording = async () => {
|
const handleRecording = async () => {
|
||||||
const screenStream = await navigator.mediaDevices.getDisplayMedia({
|
const screenStream = await navigator.mediaDevices.getDisplayMedia({
|
||||||
|
|
@ -101,10 +109,33 @@ export default function Recorder() {
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
if (blob) {
|
if (blob) {
|
||||||
invokeSaveAsDialog(blob);
|
const dateString =
|
||||||
|
"Recording - " + dayjs().format("D MMM YYYY") + ".webm";
|
||||||
|
invokeSaveAsDialog(blob, dateString);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleUpload = async () => {
|
||||||
|
if (!blob) return;
|
||||||
|
const dateString = "Recording - " + dayjs().format("D MMM YYYY") + ".webm";
|
||||||
|
setSubmitting(true);
|
||||||
|
const { signedUrl, id } = await getSignedUrl.mutateAsync({
|
||||||
|
key: dateString,
|
||||||
|
});
|
||||||
|
await axios
|
||||||
|
.put(signedUrl, blob.slice(), {
|
||||||
|
headers: { "Content-Type": "video/webm" },
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
void router.push("share/" + id);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
setSubmitting(false);
|
||||||
|
void apiUtils.video.getAll.invalidate();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{step === "pre" ? (
|
{step === "pre" ? (
|
||||||
|
|
@ -213,7 +244,6 @@ export default function Recorder() {
|
||||||
) : null}
|
) : null}
|
||||||
{step === "post" ? (
|
{step === "post" ? (
|
||||||
<div>
|
<div>
|
||||||
<span>post recording</span>
|
|
||||||
{blob && (
|
{blob && (
|
||||||
<video
|
<video
|
||||||
src={URL.createObjectURL(blob)}
|
src={URL.createObjectURL(blob)}
|
||||||
|
|
@ -223,6 +253,18 @@ export default function Recorder() {
|
||||||
style={{ width: "700px", margin: "1em" }}
|
style={{ width: "700px", margin: "1em" }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<button
|
||||||
|
onClick={handleSave}
|
||||||
|
className="mt-2 rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||||
|
>
|
||||||
|
Download
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => void handleUpload()}
|
||||||
|
className="ml-2 mt-2 rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||||
|
>
|
||||||
|
Upload
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -63,18 +63,6 @@ export default function VideoUploadModal() {
|
||||||
className="relative z-10"
|
className="relative z-10"
|
||||||
onClose={() => void closeModal}
|
onClose={() => void closeModal}
|
||||||
>
|
>
|
||||||
<Transition.Child
|
|
||||||
as={Fragment}
|
|
||||||
enter="ease-out duration-300"
|
|
||||||
enterFrom="opacity-0"
|
|
||||||
enterTo="opacity-100"
|
|
||||||
leave="ease-in duration-200"
|
|
||||||
leaveFrom="opacity-100"
|
|
||||||
leaveTo="opacity-0"
|
|
||||||
>
|
|
||||||
<div className="fixed inset-0 bg-black bg-opacity-25" />
|
|
||||||
</Transition.Child>
|
|
||||||
|
|
||||||
<div className="fixed inset-0 overflow-y-auto">
|
<div className="fixed inset-0 overflow-y-auto">
|
||||||
<div className="flex min-h-full items-center justify-center p-4 text-center">
|
<div className="flex min-h-full items-center justify-center p-4 text-center">
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue