From 16d259ccc4c33a54241be9c3eb28bdbba4dbddbd Mon Sep 17 00:00:00 2001 From: Kimberlee Johnson Date: Mon, 22 Nov 2021 16:57:27 -0800 Subject: [PATCH] First pass at more recording types, updated README --- custom/recording/README.md | 6 ++-- custom/recording/components/RecordingModal.js | 24 ++++++++++++++- .../recording/contexts/RecordingProvider.js | 29 +++++++++++++++++-- custom/shared/contexts/CallProvider.js | 27 +++++++++-------- 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/custom/recording/README.md b/custom/recording/README.md index 523abe6..ebabce6 100644 --- a/custom/recording/README.md +++ b/custom/recording/README.md @@ -6,14 +6,14 @@ ## What does this demo do? -- Use [startRecording](https://docs.daily.co/reference#%EF%B8%8F-startrecording) to create a video and audio recording of your call. You can read more about Daily call recording (and the different modes and types) [here](https://docs.daily.co/reference#recordings) -- Supports both `cloud` and `local` recording modes (specified when creating the room or managed using the Daily dashboard) +- Use [startRecording](https://docs.daily.co/reference#%EF%B8%8F-startrecording) to create a video and audio recording of your call. You can read more about Daily call recording (and the different modes and types) [here](https://docs.daily.co/guides/recording-calls-with-the-daily-api) +- Supports `cloud`, `cloud-beta`, `local`, and `rtp-tracks` recording modes (specified when creating the room or managed using the Daily dashboard). _Heads up: if recording on mobile devices or Safari, then `cloud-beta` must be the specified mode._ - Coming soon: support different recording layouts / composites - Coming soon: use the Daily REST API to retrieve a list of cloud recordings for the currently active room **To turn on recording, you need to be on the Scale plan. There is also a per minute recording fee for cloud recording.** -Please note: this demo is not currently mobile optimised +Please note: this demo is not currently mobile optimised. ### Getting started diff --git a/custom/recording/components/RecordingModal.js b/custom/recording/components/RecordingModal.js index e89efa4..1725f4d 100644 --- a/custom/recording/components/RecordingModal.js +++ b/custom/recording/components/RecordingModal.js @@ -13,6 +13,8 @@ import { RECORDING_RECORDING, RECORDING_SAVED, RECORDING_TYPE_CLOUD, + RECORDING_TYPE_CLOUD_BETA, + RECORDING_TYPE_RTP_TRACKS, RECORDING_UPLOADING, useRecording, } from '../contexts/RecordingProvider'; @@ -105,7 +107,9 @@ export const RecordingModal = () => {

Recording started: {recordingStartedDate.toString()}

)} - {enableRecording === RECORDING_TYPE_CLOUD && ( + {[RECORDING_TYPE_CLOUD, RECORDING_TYPE_CLOUD_BETA].includes( + enableRecording + ) && ( <>
@@ -115,6 +119,24 @@ export const RecordingModal = () => {

)} + {enableRecording === RECORDING_TYPE_RTP_TRACKS && ( + <> +
+ +

+ rtp-tracks recordings can be accessed via the Daily API. See the{' '} + + Daily recording guide + {' '} + for details. +

+ + )} ); diff --git a/custom/recording/contexts/RecordingProvider.js b/custom/recording/contexts/RecordingProvider.js index 326bb37..a56a0e3 100644 --- a/custom/recording/contexts/RecordingProvider.js +++ b/custom/recording/contexts/RecordingProvider.js @@ -26,7 +26,10 @@ export const RECORDING_COUNTDOWN_3 = 'starting3'; export const RECORDING_IDLE = 'idle'; export const RECORDING_TYPE_CLOUD = 'cloud'; +export const RECORDING_TYPE_CLOUD_BETA = 'cloud-beta'; export const RECORDING_TYPE_LOCAL = 'local'; +export const RECORDING_TYPE_OUTPUT_BYTE_STREAM = 'output-byte-stream'; +export const RECORDING_TYPE_RTP_TRACKS = 'rtp-tracks'; const RecordingContext = createContext({ isRecordingLocally: false, @@ -37,8 +40,12 @@ const RecordingContext = createContext({ }); export const RecordingProvider = ({ children }) => { - const { callObject, enableRecording, startCloudRecording, state } = - useCallState(); + const { + callObject, + enableRecording, + startCloudRecording, + state, + } = useCallState(); const { participants } = useParticipants(); const [recordingStartedDate, setRecordingStartedDate] = useState(null); const [recordingState, setRecordingState] = useState(RECORDING_IDLE); @@ -85,11 +92,26 @@ export const RecordingProvider = ({ children }) => { } }; + // The 'recording-data' event is emitted when an output-byte-stream recording has started + const handleRecordingData = async (ev) => { + try { + console.log('got data', ev); + await window.writer.write(ev.data); + if (ev.finished) { + console.log('closing!'); + window.writer.close(); + } + } catch (e) { + console.error(e); + } + }; + const handleRecordingUploadCompleted = () => { setRecordingState(RECORDING_SAVED); }; callObject.on('app-message', handleAppMessage); + callObject.on('recording-data', handleRecordingData); callObject.on('recording-upload-completed', handleRecordingUploadCompleted); return () => { @@ -263,10 +285,13 @@ export const RecordingProvider = ({ children }) => { if (recordingState === RECORDING_RECORDING) { switch (enableRecording) { case RECORDING_TYPE_LOCAL: + case RECORDING_TYPE_OUTPUT_BYTE_STREAM: setRecordingState(RECORDING_SAVED); setIsRecordingLocally(false); break; case RECORDING_TYPE_CLOUD: + case RECORDING_TYPE_CLOUD_BETA: + case RECORDING_TYPE_RTP_TRACKS: setRecordingState(RECORDING_UPLOADING); break; default: diff --git a/custom/shared/contexts/CallProvider.js b/custom/shared/contexts/CallProvider.js index eb133c8..62b6919 100644 --- a/custom/shared/contexts/CallProvider.js +++ b/custom/shared/contexts/CallProvider.js @@ -3,7 +3,7 @@ * --- * Configures the general state of a Daily call, such as which features * to enable, as well as instantiate the 'call machine' hook responsible - * fir the overaching call loop (joining, leaving, etc) + * for the overaching call loop (joining, leaving, etc) */ import React, { createContext, @@ -60,19 +60,22 @@ export const CallProvider = ({ ); } const browser = Bowser.parse(window.navigator.userAgent); + const recordingType = + roomConfig?.tokenConfig?.enable_recording ?? + roomConfig?.config?.enable_recording; + + // Mobile and Safari recordings are only supported under the 'cloud-beta' type const supportsRecording = - browser.platform.type === 'desktop' && browser.engine.name === 'Blink'; - // recording and screen sharing is hidden in owner_only_broadcast for non-owners + ((browser.platform.type !== 'desktop' || + browser.engine.name !== 'Blink') && + recordingType === 'cloud-beta') || + (browser.platform.type === 'desktop' && + browser.engine.name === 'Blink'); if (supportsRecording) { - const recordingType = - roomConfig?.tokenConfig?.enable_recording ?? - roomConfig?.config?.enable_recording; - if (['local', 'cloud'].includes(recordingType)) { - setEnableRecording(recordingType); - setStartCloudRecording( - roomConfig?.tokenConfig?.start_cloud_recording ?? false - ); - } + setEnableRecording(recordingType); + setStartCloudRecording( + roomConfig?.tokenConfig?.start_cloud_recording ?? false + ); } }; updateRoomConfigState();