aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/RecordingBox
diff options
context:
space:
mode:
authorMichael <michael.foiani@gmail.com>2022-06-10 15:41:38 -0400
committerMichael <michael.foiani@gmail.com>2022-06-10 15:41:38 -0400
commit1688af3de54419029773fb85b78bca4500f7f0de (patch)
tree73e777815eb2c6e91e0adb3c4702bb7ef2f7178d /src/client/views/nodes/RecordingBox
parent3627d2597ffb52f00c3b82456b1b6693006c93fa (diff)
big bug problems with recording. some reason interacting with the canvas is making the recording inactive - i think :/
Diffstat (limited to 'src/client/views/nodes/RecordingBox')
-rw-r--r--src/client/views/nodes/RecordingBox/ProgressBar.tsx8
-rw-r--r--src/client/views/nodes/RecordingBox/RecordingBox.tsx12
-rw-r--r--src/client/views/nodes/RecordingBox/RecordingView.tsx99
3 files changed, 70 insertions, 49 deletions
diff --git a/src/client/views/nodes/RecordingBox/ProgressBar.tsx b/src/client/views/nodes/RecordingBox/ProgressBar.tsx
index 493069394..1bb2b7c84 100644
--- a/src/client/views/nodes/RecordingBox/ProgressBar.tsx
+++ b/src/client/views/nodes/RecordingBox/ProgressBar.tsx
@@ -161,12 +161,12 @@ export function ProgressBar(props: ProgressBarProps) {
}
// pointerdown event for the progress bar
- const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
- // don't move the videobox element
- e.stopPropagation()
+ const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
+ // don't move the videobox element
+ e.stopPropagation();
// if recording, do nothing
- if (props.recording) return;
+ if (props.recording) return;
// get the segment the user clicked on to be dragged
const clickedSegment = e.target as HTMLDivElement & EventTarget
diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
index 5e97e3eb5..6fe67b6db 100644
--- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
@@ -8,8 +8,8 @@ import { FieldView } from "../FieldView";
import { VideoBox } from "../VideoBox";
import { RecordingView } from './RecordingView';
import { DocumentType } from "../../../documents/DocumentTypes";
-import { RecordingApi } from "../../../util/RecordingApi";
-import { Doc, FieldsSym } from "../../../../fields/Doc";
+import { Presentation } from "../../../util/RecordingApi";
+import { Doc } from "../../../../fields/Doc";
import { Id } from "../../../../fields/FieldSymbols";
@@ -21,7 +21,7 @@ export class RecordingBox extends ViewBoxBaseComponent() {
private _ref: React.RefObject<HTMLDivElement> = React.createRef();
constructor(props: any) {
- super(props);
+ super(props);
}
componentDidMount() {
@@ -38,7 +38,7 @@ export class RecordingBox extends ViewBoxBaseComponent() {
}
@action
- setResult = (info: Upload.AccessPathInfo, trackScreen: boolean) => {
+ setResult = (info: Upload.AccessPathInfo, presentation?: Presentation) => {
this.result = info
this.dataDoc.type = DocumentType.VID;
this.dataDoc[this.fieldKey + "-duration"] = this.videoDuration;
@@ -47,9 +47,7 @@ export class RecordingBox extends ViewBoxBaseComponent() {
this.dataDoc[this.props.fieldKey] = new VideoField(this.result.accessPaths.client);
this.dataDoc[this.fieldKey + "-recorded"] = true;
// stringify the presenation and store it
- if (trackScreen) {
- this.dataDoc[this.fieldKey + "-presentation"] = JSON.stringify(RecordingApi.Instance.clear());
- }
+ presentation?.movements && (this.dataDoc[this.fieldKey + "-presentation"] = JSON.stringify(presentation));
}
render() {
diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx
index 138e72274..208eaf45a 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx
@@ -8,16 +8,17 @@ import { IconContext } from "react-icons";
import { Networking } from '../../../Network';
import { Upload } from '../../../../server/SharedMediaTypes';
import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils';
-import { RecordingApi } from '../../../util/RecordingApi';
+import { Presentation, RecordingApi } from '../../../util/RecordingApi';
export interface MediaSegment {
videoChunks: any[],
endTime: number,
- startTime: number
+ startTime: number,
+ presenation?: Presentation,
}
interface IRecordingViewProps {
- setResult: (info: Upload.AccessPathInfo, trackScreen: boolean) => void
+ setResult: (info: Upload.AccessPathInfo, presentation?: Presentation) => void
setDuration: (seconds: number) => void
id: string
}
@@ -58,13 +59,18 @@ export function RecordingView(props: IRecordingViewProps) {
sampleRate: 44100
}
}
+
+ useEffect(() => console.info('progess', progress), [progress])
useEffect(() => {
- if (finished) {
+ if (finished) {
+ // make the total presentation that'll match the concatted video
+ const concatPres = trackScreen ? RecordingApi.Instance.concatPresentations(videos.map(v => v.presenation as Presentation)) : undefined;
+
// this async function uses the server to create the concatted video and then sets the result to it's accessPaths
(async () => {
- const videoFiles = videos.map((vid, i) => new File(vid.videoChunks, `segvideo${i}.mkv`, { type: vid.videoChunks[0].type, lastModified: Date.now() }));
+ const videoFiles = videos.map((vid, i) => new File(vid.videoChunks, `segvideo${i}.mkv`, { type: vid.videoChunks[0].type, lastModified: Date.now() }));
// upload the segments to the server and get their server access paths
const serverPaths: string[] = (await Networking.UploadFilesToServer(videoFiles))
@@ -72,7 +78,7 @@ export function RecordingView(props: IRecordingViewProps) {
// concat the segments together using post call
const result: Upload.AccessPathInfo | Error = await Networking.PostToServer('/concatVideos', serverPaths);
- !(result instanceof Error) ? props.setResult(result, trackScreen) : console.error("video conversion failed");
+ !(result instanceof Error) ? props.setResult(result, concatPres) : console.error("video conversion failed");
})();
}
}, [videos])
@@ -133,53 +139,70 @@ export function RecordingView(props: IRecordingViewProps) {
trackScreen && RecordingApi.Instance.start();
}
- videoRecorder.current.onstop = () => {
+ videoRecorder.current.onstop = () => {
+ RecordingApi.Instance.stop();
// if we have a last portion
- if (videoChunks.length > 1) {
+ if (videoChunks.length > 1) {
// append the current portion to the video pieces
- setVideos(videos => [...videos, { videoChunks: videoChunks, endTime: recordingTimerRef.current, startTime: videos?.lastElement()?.endTime || 0 }])
+ setVideos(videos => [...videos, {
+ videoChunks: videoChunks,
+ endTime: recordingTimerRef.current,
+ startTime: videos?.lastElement()?.endTime || 0,
+ // RecordingApi.stop() will return undefined if no track screen
+ presenation: RecordingApi.Instance.getPresentation()
+ }])
+ // now that we got the presentation data, we can clear for the next segment to be recorded
+ RecordingApi.Instance.clear();
}
- // reset the temporary chunks
- videoChunks = []
- setRecording(false);
- trackScreen && RecordingApi.Instance.pause();
+ // reset the temporary chunks
+ videoChunks = []
+ setRecording(false);
}
videoRecorder.current.start(200)
}
- const stop = (e: React.PointerEvent) => {
- e.stopPropagation();
- if (videoRecorder.current) {
- if (videoRecorder.current.state !== "inactive") {
- videoRecorder.current.stop();
- }
-
- // this will call upon progessbar to update videos to be in the correct order
- setFinished(true);
-
- // end the streams (audio/video) to remove recording icon
- const stream = videoElementRef.current!.srcObject;
- stream instanceof MediaStream && stream.getTracks().forEach(track => track.stop());
- }
+ const finish = (e: React.PointerEvent) => {
+ e.stopPropagation();
+ console.log('finish', videoRecorder.current)
+ // if inactive, then we're done recording all the segments
+ if (videoRecorder.current && videoRecorder.current.state !== "inactive") {
+ console.log('stopping recorder', videoRecorder.current?.state)
+
+
+
+ // call stop on the video recorder
+ videoRecorder.current?.stop();
+
+ // end the streams (audio/video) to remove recording icon
+ const stream = videoElementRef.current!.srcObject;
+ stream instanceof MediaStream && stream.getTracks().forEach(track => track.stop());
+
+ // clear the recoringApi - this is done in the stop method
+ // RecordingApi.Instance.clear();
+
+ // this will call upon progessbar to update videos to be in the correct order
+ console.log('setFinished to true', finished)
+ setFinished(true);
+ }
}
const pause = (e: React.PointerEvent) => {
- e.stopPropagation()
- if (videoRecorder.current) {
- if (videoRecorder.current.state === "recording") {
- videoRecorder.current.stop();
- }
- }
+ e.stopPropagation()
+ // if recording, then this is just a new segment
+ videoRecorder.current?.state === "recording" && videoRecorder.current.stop();
}
- const startOrResume = (e: React.PointerEvent) => {
+ const start = (e: React.PointerEvent) => {
// the code to start or resume does not get triggered if we start dragging the button
setupMoveUpEvents({}, e, returnTrue, returnFalse, e => {
- (!videoRecorder.current || videoRecorder.current.state === "inactive") && record();
- return true; // cancels propagation to documentView to avoid selecting it.
+ if (!videoRecorder.current || videoRecorder.current.state === "inactive") {
+ record();
+ // trackScreen && RecordingApi.Instance.start();
+ }
+ return true; // cancels propagation to documentView to avoid selecting it.
}, false, false);
}
@@ -218,7 +241,7 @@ export function RecordingView(props: IRecordingViewProps) {
<div className="record-button-wrapper">
{recording ?
<button className="stop-button" onPointerDown={pause} /> :
- <button className="record-button" onPointerDown={startOrResume} />
+ <button className="record-button" onPointerDown={start} />
}
</div>
@@ -229,7 +252,7 @@ export function RecordingView(props: IRecordingViewProps) {
<MdBackspace onPointerDown={undoPrevious} />
</IconContext.Provider>
<IconContext.Provider value={{ color: "#cc1c08", className: "video-edit-buttons" }}>
- <FaCheckCircle onPointerDown={stop} />
+ <FaCheckCircle onPointerDown={finish} />
</IconContext.Provider>
</div>