Skip to content

Commit 7a241ab

Browse files
feat: Enhance video recorder (#831)
* Enhance video recorder * Updated Config * Fixed Bug - Disabled Send button should not work after the click --------- Co-authored-by: Zishan Ahmad <zishan.barun@gmail.com>
1 parent 5ada56e commit 7a241ab

6 files changed

Lines changed: 322 additions & 96 deletions

File tree

packages/react/src/hooks/useMediaRecorder.js

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useRef } from 'react';
1+
import { useState, useRef, useEffect } from 'react';
22

33
function useUserMedia(constraints, videoRef) {
44
const [stream, setStream] = useState();
@@ -47,3 +47,80 @@ export function useMediaRecorder({ constraints, onStop, videoRef }) {
4747

4848
return [start, stop];
4949
}
50+
51+
export function useNewMediaRecorder({ constraints, videoRef, onStop }) {
52+
const [stream, setStream] = useState();
53+
const [isStreaming, setIsStreaming] = useState(false);
54+
const [recorder, setRecorder] = useState();
55+
const [recordingData, setRecordingData] = useState(null);
56+
const chunks = useRef([]);
57+
58+
async function startCameraAndMic() {
59+
if (isStreaming) return;
60+
try {
61+
const _stream = await navigator.mediaDevices.getUserMedia(constraints);
62+
setStream(_stream);
63+
setIsStreaming(true);
64+
if (videoRef.current) {
65+
videoRef.current.srcObject = _stream;
66+
}
67+
} catch (error) {
68+
console.error('Error starting camera and mic:', error);
69+
}
70+
}
71+
72+
async function startRecording() {
73+
if (!isStreaming) {
74+
console.error('Camera and mic must be on to start recording.');
75+
return;
76+
}
77+
78+
chunks.current = [];
79+
const _recorder = new MediaRecorder(stream);
80+
_recorder.start();
81+
setRecorder(_recorder);
82+
83+
_recorder.addEventListener('dataavailable', (event) => {
84+
chunks.current.push(event.data);
85+
});
86+
87+
_recorder.addEventListener('stop', () => {
88+
setRecordingData(new Blob(chunks.current, { type: 'video/mp4' }));
89+
onStop && onStop(chunks.current);
90+
});
91+
}
92+
93+
async function stopRecording() {
94+
if (recorder && recorder.state === 'recording') {
95+
recorder.stop();
96+
}
97+
}
98+
99+
function getRecording() {
100+
return recordingData;
101+
}
102+
103+
function deleteRecording() {
104+
setRecordingData(null);
105+
chunks.current = [];
106+
}
107+
108+
function stopCameraAndMic() {
109+
if (stream) {
110+
stream.getTracks().forEach((track) => track.stop());
111+
setStream(null);
112+
setIsStreaming(false);
113+
}
114+
}
115+
116+
useEffect(() => () => stopCameraAndMic(), []);
117+
118+
return {
119+
startCameraAndMic,
120+
startRecording,
121+
stopRecording,
122+
getRecording,
123+
deleteRecording,
124+
stopCameraAndMic,
125+
};
126+
}

packages/react/src/views/ChatInput/ChatInput.styles.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,48 @@ export const getCommonRecorderStyles = (theme) => {
118118
border-radius: 50%;
119119
background-color: ${theme.colors.destructive};
120120
margin: auto;
121-
margin-right: 8px;
121+
margin-right: 5px;
122+
margin-left: 5px;
123+
`,
124+
125+
oppositeDot: css`
126+
width: 0.5rem;
127+
height: 0.5rem;
128+
border-radius: 50%;
129+
background-color: ${theme.colors.background};
130+
margin: auto;
131+
margin-right: 5px;
132+
margin-left: 5px;
122133
`,
123134

124135
controller: css`
125-
gap: 0.15rem;
136+
width: 100%;
126137
display: inline-flex;
127138
`,
128139

129140
timer: css`
130141
margin: auto;
131142
`,
143+
144+
spacer: css`
145+
flex-grow: 1;
146+
`,
147+
132148
record: css`
133149
display: flex;
134150
margin: auto;
135151
`,
152+
153+
leftSection: css`
154+
display: flex;
155+
align-items: left;
156+
`,
157+
158+
rightSection: css`
159+
display: flex;
160+
align-items: right;
161+
margin-top: 0.3rem;
162+
`,
136163
modal: {
137164
'@media(max-width: 768px)': {
138165
height: '100%',

0 commit comments

Comments
 (0)