feat: make video recording optional, deleting video tracks (#954)

* feat: make video recording optional, deleting video tracks
This commit is contained in:
Juan Diego García
2026-04-08 17:05:50 -05:00
committed by GitHub
parent 5f0c5635eb
commit ee8db36f2c
12 changed files with 202 additions and 9 deletions

View File

@@ -95,6 +95,7 @@ const roomInitialState = {
platform: "whereby",
skipConsent: false,
emailTranscriptTo: "",
storeVideo: false,
};
export default function RoomsList() {
@@ -185,6 +186,7 @@ export default function RoomsList() {
platform: detailedEditedRoom.platform,
skipConsent: detailedEditedRoom.skip_consent || false,
emailTranscriptTo: detailedEditedRoom.email_transcript_to || "",
storeVideo: detailedEditedRoom.store_video || false,
}
: null,
[detailedEditedRoom],
@@ -335,6 +337,7 @@ export default function RoomsList() {
platform,
skip_consent: room.skipConsent,
email_transcript_to: room.emailTranscriptTo || null,
store_video: room.storeVideo,
};
if (isEditing) {
@@ -400,6 +403,7 @@ export default function RoomsList() {
platform: roomData.platform,
skipConsent: roomData.skip_consent || false,
emailTranscriptTo: roomData.email_transcript_to || "",
storeVideo: roomData.store_video || false,
});
setEditRoomId(roomId);
setIsEditing(true);
@@ -842,6 +846,38 @@ export default function RoomsList() {
</Field.HelperText>
</Field.Root>
)}
{room.platform === "daily" &&
room.recordingType === "cloud" && (
<Field.Root mt={4}>
<Checkbox.Root
name="storeVideo"
checked={room.storeVideo}
onCheckedChange={(e) => {
const syntheticEvent = {
target: {
name: "storeVideo",
type: "checkbox",
checked: e.checked,
},
};
handleRoomChange(syntheticEvent);
}}
>
<Checkbox.HiddenInput />
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>
<Checkbox.Label>
Store video recording
</Checkbox.Label>
</Checkbox.Root>
<Field.HelperText>
When enabled, a composed video recording will be
saved alongside audio. Disabling saves significant
storage.
</Field.HelperText>
</Field.Root>
)}
</Tabs.Content>
<Tabs.Content value="share" pt={6}>

View File

@@ -267,12 +267,13 @@ export default function DailyRoom({ meeting, room }: DailyRoomProps) {
const handleFrameJoinMeeting = useCallback(() => {
if (meeting.recording_type === "cloud") {
console.log("Starting dual recording via REST API", {
console.log("Starting recording via REST API", {
cloudInstanceId,
rawTracksInstanceId,
storeVideo: meeting.store_video,
});
// Start both cloud and raw-tracks via backend REST API (with retry on 404)
// Start recordings via backend REST API (with retry on 404)
// Daily.co needs time to register call as "hosting" for REST API
const startRecordingWithRetry = (
type: DailyRecordingType,
@@ -320,12 +321,17 @@ export default function DailyRoom({ meeting, room }: DailyRoomProps) {
}, RECORDING_START_DELAY_MS);
};
// Start both recordings
startRecordingWithRetry("cloud", cloudInstanceId);
// Always start raw-tracks (needed for transcription pipeline)
startRecordingWithRetry("raw-tracks", rawTracksInstanceId);
// Only start cloud (composed video) if store_video is enabled
if (meeting.store_video) {
startRecordingWithRetry("cloud", cloudInstanceId);
}
}
}, [
meeting.recording_type,
meeting.store_video,
meeting.id,
startRecordingMutation,
cloudInstanceId,

View File

@@ -1134,6 +1134,11 @@ export interface components {
skip_consent: boolean;
/** Email Transcript To */
email_transcript_to?: string | null;
/**
* Store Video
* @default false
*/
store_video: boolean;
};
/** CreateRoomMeeting */
CreateRoomMeeting: {
@@ -1852,6 +1857,11 @@ export interface components {
daily_composed_video_s3_key?: string | null;
/** Daily Composed Video Duration */
daily_composed_video_duration?: number | null;
/**
* Store Video
* @default false
*/
store_video: boolean;
};
/** MeetingConsentRequest */
MeetingConsentRequest: {
@@ -1955,6 +1965,11 @@ export interface components {
skip_consent: boolean;
/** Email Transcript To */
email_transcript_to?: string | null;
/**
* Store Video
* @default false
*/
store_video: boolean;
};
/** RoomDetails */
RoomDetails: {
@@ -2013,6 +2028,11 @@ export interface components {
skip_consent: boolean;
/** Email Transcript To */
email_transcript_to?: string | null;
/**
* Store Video
* @default false
*/
store_video: boolean;
/** Webhook Url */
webhook_url: string | null;
/** Webhook Secret */
@@ -2389,6 +2409,8 @@ export interface components {
skip_consent?: boolean | null;
/** Email Transcript To */
email_transcript_to?: string | null;
/** Store Video */
store_video?: boolean | null;
};
/** UpdateTranscript */
UpdateTranscript: {