This commit is contained in:
Flatlogic Bot 2026-02-26 16:01:27 +00:00
parent ee308ed2f9
commit 0c4c4fdf8d

View File

@ -96,15 +96,16 @@ const ObservationPage = () => {
facingMode: 'environment', facingMode: 'environment',
width: { ideal: 1920 }, width: { ideal: 1920 },
height: { ideal: 1080 } height: { ideal: 1080 }
} },
audio: true // Integrate audio for synchronized recording
}); });
if (videoRef.current) { if (videoRef.current) {
videoRef.current.srcObject = stream; videoRef.current.srcObject = stream;
setIsCameraActive(true); setIsCameraActive(true);
} }
} catch (err) { } catch (err) {
console.error("Camera access denied:", err); console.error("Camera/Audio access denied:", err);
alert("Camera access is required for live observation simulation."); alert("Camera and Microphone access are required for full simulation recording.");
} }
}; };
@ -180,9 +181,14 @@ const ObservationPage = () => {
if (!videoRef.current || !videoRef.current.srcObject) return; if (!videoRef.current || !videoRef.current.srcObject) return;
const stream = videoRef.current.srcObject as MediaStream; const stream = videoRef.current.srcObject as MediaStream;
const recorder = new MediaRecorder(stream, {
mimeType: 'video/webm' // Check for supported types with audio
}); const options = { mimeType: 'video/webm;codecs=vp8,opus' };
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
options.mimeType = 'video/webm';
}
const recorder = new MediaRecorder(stream, options);
const chunks: Blob[] = []; const chunks: Blob[] = [];
recorder.ondataavailable = (event) => { recorder.ondataavailable = (event) => {
@ -215,7 +221,7 @@ const ObservationPage = () => {
const a = document.createElement('a'); const a = document.createElement('a');
a.style.display = 'none'; a.style.display = 'none';
a.href = videoUrl; a.href = videoUrl;
a.download = `JWST-REC-${new Date().getTime()}.webm`; a.download = `JWST-AV-REC-${new Date().getTime()}.webm`;
document.body.appendChild(a); document.body.appendChild(a);
a.click(); a.click();
window.URL.revokeObjectURL(videoUrl); window.URL.revokeObjectURL(videoUrl);
@ -319,7 +325,7 @@ const ObservationPage = () => {
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<div className={`w-2 h-2 rounded-full ${isRecording ? 'bg-red-500 animate-pulse' : 'bg-green-500 animate-ping'}`}></div> <div className={`w-2 h-2 rounded-full ${isRecording ? 'bg-red-500 animate-pulse' : 'bg-green-500 animate-ping'}`}></div>
<div className="font-bold text-[#E3B341] tracking-widest uppercase"> <div className="font-bold text-[#E3B341] tracking-widest uppercase">
{isRecording ? 'REC ACTIVE' : (isFocusing ? 'Acquiring Target' : 'Observation Stable')} {isRecording ? 'A/V REC ACTIVE' : (isFocusing ? 'Acquiring Target' : 'Observation Stable')}
</div> </div>
</div> </div>
<div className="mt-3 grid grid-cols-2 gap-x-6 text-[10px]"> <div className="mt-3 grid grid-cols-2 gap-x-6 text-[10px]">
@ -349,7 +355,7 @@ const ObservationPage = () => {
<button <button
onClick={startRecording} onClick={startRecording}
className="p-3 bg-black/80 border border-white/20 hover:bg-red-600 transition-all text-white" className="p-3 bg-black/80 border border-white/20 hover:bg-red-600 transition-all text-white"
title="Start Recording" title="Start A/V Recording"
> >
<BaseIcon path={mdiRecord} size={20} className="text-red-500" /> <BaseIcon path={mdiRecord} size={20} className="text-red-500" />
</button> </button>
@ -366,7 +372,7 @@ const ObservationPage = () => {
<button <button
onClick={downloadVideo} onClick={downloadVideo}
className="p-3 bg-blue-600 border border-white/20 transition-all text-white" className="p-3 bg-blue-600 border border-white/20 transition-all text-white"
title="Download Video" title="Download A/V Video"
> >
<BaseIcon path={mdiDownload} size={20} /> <BaseIcon path={mdiDownload} size={20} />
</button> </button>