| // src/components/messages/VideoNoteRecorder.tsx | |
| import React, { useRef, useState } from 'react'; | |
| interface VideoNoteRecorderProps { | |
| onSend: (blob: Blob, duration: number, mode: 'video' | 'audio') => void; | |
| onCancel: () => void; | |
| } | |
| export function VideoNoteRecorder({ onSend, onCancel }: VideoNoteRecorderProps) { | |
| const [mode, setMode] = useState<'video' | 'audio'>('video'); | |
| const [recording, setRecording] = useState(false); | |
| const mediaRef = useRef<MediaRecorder | null>(null); | |
| const chunksRef = useRef<Blob[]>([]); | |
| const startRecording = async () => { | |
| const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: mode === 'video' }); | |
| const recorder = new MediaRecorder(stream); | |
| mediaRef.current = recorder; | |
| recorder.ondataavailable = (e) => chunksRef.current.push(e.data); | |
| recorder.onstop = () => { | |
| const blob = new Blob(chunksRef.current, { type: 'video/webm' }); | |
| onSend(blob, 0, mode); | |
| chunksRef.current = []; | |
| stream.getTracks().forEach(track => track.stop()); | |
| }; | |
| recorder.start(); | |
| setRecording(true); | |
| }; | |
| const stopRecording = () => { | |
| mediaRef.current?.stop(); | |
| setRecording(false); | |
| }; | |
| return ( | |
| <div className="bg-white dark:bg-gray-800 rounded-xl p-4 shadow-lg border"> | |
| <div className="flex gap-2 mb-3"> | |
| <button onClick={() => setMode('video')} className={`btn btn-sm ${mode === 'video' ? 'btn-primary' : 'btn-secondary'}`}>Video</button> | |
| <button onClick={() => setMode('audio')} className={`btn btn-sm ${mode === 'audio' ? 'btn-primary' : 'btn-secondary'}`}>Audio</button> | |
| </div> | |
| <div className="flex justify-between"> | |
| {!recording ? ( | |
| <button onClick={startRecording} className="btn btn-primary">🎙️ Start</button> | |
| ) : ( | |
| <button onClick={stopRecording} className="btn btn-danger">⏹️ Stop</button> | |
| )} | |
| <button onClick={onCancel} className="btn btn-secondary">Cancel</button> | |
| </div> | |
| </div> | |
| ); | |
| } |
Xet Storage Details
- Size:
- 2.01 kB
- Xet hash:
- 44a468e726e2fa90c99352a858b4cac83e0a93cad72608b345f4e975215a4b46
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.