-
setSourceDialogOpen(false)} />
)
@@ -850,449 +887,3 @@ ChatMessage.propTypes = {
chatflowid: PropTypes.string,
isDialog: PropTypes.bool
}
-
-// audio-recording.js ---------------
-//View
-let microphoneButton = document.getElementsByClassName('start-recording-button')[0]
-let recordingControlButtonsContainer = document.getElementsByClassName('recording-control-buttons-container')[0]
-let stopRecordingButton = document.getElementsByClassName('stop-recording-button')[0]
-let cancelRecordingButton = document.getElementsByClassName('cancel-recording-button')[0]
-let elapsedTimeTag = document.getElementsByClassName('elapsed-time')[0]
-let closeBrowserNotSupportedBoxButton = document.getElementsByClassName('close-browser-not-supported-box')[0]
-let overlay = document.getElementsByClassName('overlay')[0]
-let audioElement = document.getElementsByClassName('audio-element')[0]
-let audioElementSource = audioElement?.getElementsByTagName('source')[0]
-let textIndicatorOfAudiPlaying = document.getElementsByClassName('text-indication-of-audio-playing')[0]
-
-const initAudioRecording = () => {
- microphoneButton = document.getElementsByClassName('start-recording-button')[0]
- recordingControlButtonsContainer = document.getElementsByClassName('recording-control-buttons-container')[0]
- stopRecordingButton = document.getElementsByClassName('stop-recording-button')[0]
- cancelRecordingButton = document.getElementsByClassName('cancel-recording-button')[0]
- elapsedTimeTag = document.getElementsByClassName('elapsed-time')[0]
- closeBrowserNotSupportedBoxButton = document.getElementsByClassName('close-browser-not-supported-box')[0]
- overlay = document.getElementsByClassName('overlay')[0]
- audioElement = document.getElementsByClassName('audio-element')[0]
- audioElementSource = audioElement?.getElementsByTagName('source')[0]
- textIndicatorOfAudiPlaying = document.getElementsByClassName('text-indication-of-audio-playing')[0]
- //Listeners
-
- //Listen to start recording button
- if (microphoneButton) microphoneButton.onclick = startAudioRecording
-
- //Listen to stop recording button
- if (stopRecordingButton) stopRecordingButton.onclick = stopAudioRecording
-
- //Listen to cancel recording button
- if (cancelRecordingButton) cancelRecordingButton.onclick = cancelAudioRecording
-
- //Listen to when the ok button is clicked in the browser not supporting audio recording box
- if (closeBrowserNotSupportedBoxButton) closeBrowserNotSupportedBoxButton.onclick = hideBrowserNotSupportedOverlay
-
- //Listen to when the audio being played ends
- if (audioElement) audioElement.onended = hideTextIndicatorOfAudioPlaying
-}
-
-/** Displays recording control buttons */
-function handleDisplayingRecordingControlButtons() {
- //Hide the microphone button that starts audio recording
- microphoneButton.style.display = 'none'
-
- //Display the recording control buttons
- recordingControlButtonsContainer.classList.remove('hide')
-
- //Handle the displaying of the elapsed recording time
- handleElapsedRecordingTime()
-}
-
-/** Hide the displayed recording control buttons */
-function handleHidingRecordingControlButtons() {
- //Display the microphone button that starts audio recording
- microphoneButton.style.display = 'block'
-
- //Hide the recording control buttons
- recordingControlButtonsContainer.classList.add('hide')
-
- //stop interval that handles both time elapsed and the red dot
- clearInterval(elapsedTimeTimer)
-}
-
-/** Displays browser not supported info box for the user*/
-function displayBrowserNotSupportedOverlay() {
- overlay.classList.remove('hide')
-}
-
-/** Displays browser not supported info box for the user*/
-function hideBrowserNotSupportedOverlay() {
- overlay.classList.add('hide')
-}
-
-/** Creates a source element for the audio element in the HTML document*/
-function createSourceForAudioElement() {
- let sourceElement = document.createElement('source')
- audioElement.appendChild(sourceElement)
-
- audioElementSource = sourceElement
-}
-
-/** Display the text indicator of the audio being playing in the background */
-function displayTextIndicatorOfAudioPlaying() {
- textIndicatorOfAudiPlaying.classList.remove('hide')
-}
-
-/** Hide the text indicator of the audio being playing in the background */
-function hideTextIndicatorOfAudioPlaying() {
- textIndicatorOfAudiPlaying.classList.add('hide')
-}
-
-//Controller
-
-/** Stores the actual start time when an audio recording begins to take place to ensure elapsed time start time is accurate*/
-let audioRecordStartTime
-
-/** Stores the maximum recording time in hours to stop recording once maximum recording hour has been reached */
-let maximumRecordingTimeInHours = 1
-
-/** Stores the reference of the setInterval function that controls the timer in audio recording*/
-let elapsedTimeTimer
-
-/** Starts the audio recording*/
-function startAudioRecording() {
- console.log('Recording Audio...')
-
- //If a previous audio recording is playing, pause it
- let recorderAudioIsPlaying = !audioElement.paused // the paused property tells whether the media element is paused or not
- console.log('paused?', !recorderAudioIsPlaying)
- if (recorderAudioIsPlaying) {
- audioElement.pause()
- //also hide the audio playing indicator displayed on the screen
- hideTextIndicatorOfAudioPlaying()
- }
-
- //start recording using the audio recording API
- audioRecorder
- .start()
- .then(() => {
- //on success
-
- //store the recording start time to display the elapsed time according to it
- audioRecordStartTime = new Date()
-
- //display control buttons to offer the functionality of stop and cancel
- handleDisplayingRecordingControlButtons()
- })
- .catch((error) => {
- //on error
- //No Browser Support Error
- if (error.message.includes('mediaDevices API or getUserMedia method is not supported in this browser.')) {
- console.log('To record audio, use browsers like Chrome and Firefox.')
- displayBrowserNotSupportedOverlay()
- }
-
- //Error handling structure
- switch (error.name) {
- case 'AbortError': //error from navigator.mediaDevices.getUserMedia
- console.log('An AbortError has occurred.')
- break
- case 'NotAllowedError': //error from navigator.mediaDevices.getUserMedia
- console.log('A NotAllowedError has occurred. User might have denied permission.')
- break
- case 'NotFoundError': //error from navigator.mediaDevices.getUserMedia
- console.log('A NotFoundError has occurred.')
- break
- case 'NotReadableError': //error from navigator.mediaDevices.getUserMedia
- console.log('A NotReadableError has occurred.')
- break
- case 'SecurityError': //error from navigator.mediaDevices.getUserMedia or from the MediaRecorder.start
- console.log('A SecurityError has occurred.')
- break
- case 'TypeError': //error from navigator.mediaDevices.getUserMedia
- console.log('A TypeError has occurred.')
- break
- case 'InvalidStateError': //error from the MediaRecorder.start
- console.log('An InvalidStateError has occurred.')
- break
- case 'UnknownError': //error from the MediaRecorder.start
- console.log('An UnknownError has occurred.')
- break
- default:
- console.log('An error occurred with the error name ' + error.name)
- }
- })
-}
-/** Stop the currently started audio recording & sends it
- */
-function stopAudioRecording() {
- console.log('Stopping Audio Recording...')
-
- //stop the recording using the audio recording API
- audioRecorder
- .stop()
- .then((audioAsblob) => {
- //Play recorder audio
- playAudio(audioAsblob)
-
- //hide recording control button & return record icon
- handleHidingRecordingControlButtons()
- })
- .catch((error) => {
- //Error handling structure
- switch (error.name) {
- case 'InvalidStateError': //error from the MediaRecorder.stop
- console.log('An InvalidStateError has occurred.')
- break
- default:
- console.log('An error occurred with the error name ' + error.name)
- }
- })
-}
-
-/** Cancel the currently started audio recording */
-function cancelAudioRecording() {
- console.log('Canceling audio...')
-
- //cancel the recording using the audio recording API
- audioRecorder.cancel()
-
- //hide recording control button & return record icon
- handleHidingRecordingControlButtons()
-}
-
-/** Plays recorded audio using the audio element in the HTML document
- * @param {Blob} recorderAudioAsBlob - recorded audio as a Blob Object
- */
-function playAudio(recorderAudioAsBlob) {
- //read content of files (Blobs) asynchronously
- let reader = new FileReader()
-
- //once content has been read
- reader.onload = (e) => {
- //store the base64 URL that represents the URL of the recording audio
- let base64URL = e.target.result
-
- //If this is the first audio playing, create a source element
- //as pre-populating the HTML with a source of empty src causes error
- if (!audioElementSource)
- //if it is not defined create it (happens first time only)
- createSourceForAudioElement()
-
- //set the audio element's source using the base64 URL
- audioElementSource.src = base64URL
-
- //set the type of the audio element based on the recorded audio's Blob type
- let BlobType = recorderAudioAsBlob.type.includes(';')
- ? recorderAudioAsBlob.type.substr(0, recorderAudioAsBlob.type.indexOf(';'))
- : recorderAudioAsBlob.type
- audioElementSource.type = BlobType
-
- //call the load method as it is used to update the audio element after changing the source or other settings
- audioElement.load()
-
- //play the audio after successfully setting new src and type that corresponds to the recorded audio
- console.log('Playing audio...')
- audioElement.play()
-
- //Display text indicator of having the audio play in the background
- displayTextIndicatorOfAudioPlaying()
- }
-
- //read content and convert it to a URL (base64)
- reader.readAsDataURL(recorderAudioAsBlob)
-}
-
-/** Computes the elapsed recording time since the moment the function is called in the format h:m:s*/
-function handleElapsedRecordingTime() {
- //display initial time when recording begins
- displayElapsedTimeDuringAudioRecording('00:00')
-
- //create an interval that compute & displays elapsed time, as well as, animate red dot - every second
- elapsedTimeTimer = setInterval(() => {
- //compute the elapsed time every second
- let elapsedTime = computeElapsedTime(audioRecordStartTime) //pass the actual record start time
- //display the elapsed time
- displayElapsedTimeDuringAudioRecording(elapsedTime)
- }, 1000) //every second
-}
-
-/** Display elapsed time during audio recording
- * @param {String} elapsedTime - elapsed time in the format mm:ss or hh:mm:ss
- */
-function displayElapsedTimeDuringAudioRecording(elapsedTime) {
- //1. display the passed elapsed time as the elapsed time in the elapsedTime HTML element
- elapsedTimeTag.innerHTML = elapsedTime
-
- //2. Stop the recording when the max number of hours is reached
- if (elapsedTimeReachedMaximumNumberOfHours(elapsedTime)) {
- stopAudioRecording()
- }
-}
-
-/**
- * @param {String} elapsedTime - elapsed time in the format mm:ss or hh:mm:ss
- * @returns {Boolean} whether the elapsed time reached the maximum number of hours or not
- */
-function elapsedTimeReachedMaximumNumberOfHours(elapsedTime) {
- //Split the elapsed time by the symbol that separates the hours, minutes and seconds :
- let elapsedTimeSplit = elapsedTime.split(':')
-
- //Turn the maximum recording time in hours to a string and pad it with zero if less than 10
- let maximumRecordingTimeInHoursAsString =
- maximumRecordingTimeInHours < 10 ? '0' + maximumRecordingTimeInHours : maximumRecordingTimeInHours.toString()
-
- //if the elapsed time reach hours and also reach the maximum recording time in hours return true
- if (elapsedTimeSplit.length === 3 && elapsedTimeSplit[0] === maximumRecordingTimeInHoursAsString) return true
- //otherwise, return false
- else return false
-}
-
-/** Computes the elapsedTime since the moment the function is called in the format mm:ss or hh:mm:ss
- * @param {String} startTime - start time to compute the elapsed time since
- * @returns {String} elapsed time in mm:ss format or hh:mm:ss format, if elapsed hours are 0.
- */
-function computeElapsedTime(startTime) {
- //record end time
- let endTime = new Date()
-
- //time difference in ms
- let timeDiff = endTime - startTime
-
- //convert time difference from ms to seconds
- timeDiff = timeDiff / 1000
-
- //extract integer seconds that don't form a minute using %
- let seconds = Math.floor(timeDiff % 60) //ignoring incomplete seconds (floor)
-
- //pad seconds with a zero if necessary
- seconds = seconds < 10 ? '0' + seconds : seconds
-
- //convert time difference from seconds to minutes using %
- timeDiff = Math.floor(timeDiff / 60)
-
- //extract integer minutes that don't form an hour using %
- let minutes = timeDiff % 60 //no need to floor possible incomplete minutes, because they've been handled as seconds
- minutes = minutes < 10 ? '0' + minutes : minutes
-
- //convert time difference from minutes to hours
- timeDiff = Math.floor(timeDiff / 60)
-
- //extract integer hours that don't form a day using %
- let hours = timeDiff % 24 //no need to floor possible incomplete hours, because they've been handled as seconds
-
- //convert time difference from hours to days
- timeDiff = Math.floor(timeDiff / 24)
-
- // the rest of timeDiff is number of days
- let days = timeDiff //add days to hours
-
- let totalHours = hours + days * 24
- totalHours = totalHours < 10 ? '0' + totalHours : totalHours
-
- if (totalHours === '00') {
- return minutes + ':' + seconds
- } else {
- return totalHours + ':' + minutes + ':' + seconds
- }
-}
-
-//API to handle audio recording
-
-const audioRecorder = {
- /** Stores the recorded audio as Blob objects of audio data as the recording continues*/
- audioBlobs: [] /*of type Blob[]*/,
- /** Stores the reference of the MediaRecorder instance that handles the MediaStream when recording starts*/
- mediaRecorder: null /*of type MediaRecorder*/,
- /** Stores the reference to the stream currently capturing the audio*/
- streamBeingCaptured: null /*of type MediaStream*/,
- /** Start recording the audio
- * @returns {Promise} - returns a promise that resolves if audio recording successfully started
- */
- start: function () {
- //Feature Detection
- if (!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia)) {
- //Feature is not supported in browser
- //return a custom error
- return Promise.reject(new Error('mediaDevices API or getUserMedia method is not supported in this browser.'))
- } else {
- //Feature is supported in browser
-
- //create an audio stream
- return (
- navigator.mediaDevices
- .getUserMedia({ audio: true } /*of type MediaStreamConstraints*/)
- //returns a promise that resolves to the audio stream
- .then((stream) /*of type MediaStream*/ => {
- //save the reference of the stream to be able to stop it when necessary
- audioRecorder.streamBeingCaptured = stream
-
- //create a media recorder instance by passing that stream into the MediaRecorder constructor
- audioRecorder.mediaRecorder = new MediaRecorder(stream) /*the MediaRecorder interface of the MediaStream Recording
- API provides functionality to easily record media*/
-
- //clear previously saved audio Blobs, if any
- audioRecorder.audioBlobs = []
-
- //add a dataavailable event listener in order to store the audio data Blobs when recording
- audioRecorder.mediaRecorder.addEventListener('dataavailable', (event) => {
- //store audio Blob object
- audioRecorder.audioBlobs.push(event.data)
- })
-
- //start the recording by calling the start method on the media recorder
- audioRecorder.mediaRecorder.start()
- })
- )
-
- /* errors are not handled in the API because if its handled and the promise is chained, the .then after the catch will be executed*/
- }
- },
- /** Stop the started audio recording
- * @returns {Promise} - returns a promise that resolves to the audio as a blob file
- */
- stop: function () {
- //return a promise that would return the blob or URL of the recording
- return new Promise((resolve) => {
- //save audio type to pass to set the Blob type
- let mimeType = audioRecorder.mediaRecorder.mimeType
-
- //listen to the stop event in order to create & return a single Blob object
- audioRecorder.mediaRecorder.addEventListener('stop', () => {
- //create a single blob object, as we might have gathered a few Blob objects that needs to be joined as one
- let audioBlob = new Blob(audioRecorder.audioBlobs, { type: mimeType })
-
- //resolve promise with the single audio blob representing the recorded audio
- resolve(audioBlob)
- })
- audioRecorder.cancel()
- })
- },
- /** Cancel audio recording*/
- cancel: function () {
- //stop the recording feature
- audioRecorder.mediaRecorder.stop()
-
- //stop all the tracks on the active stream in order to stop the stream
- audioRecorder.stopStream()
-
- //reset API properties for next recording
- audioRecorder.resetRecordingProperties()
- },
- /** Stop all the tracks on the active stream in order to stop the stream and remove
- * the red flashing dot showing in the tab
- */
- stopStream: function () {
- //stopping the capturing request by stopping all the tracks on the active stream
- audioRecorder.streamBeingCaptured
- .getTracks() //get all tracks from the stream
- .forEach((track) /*of type MediaStreamTrack*/ => track.stop()) //stop each one
- },
- /** Reset all the recording properties including the media recorder and stream being captured*/
- resetRecordingProperties: function () {
- audioRecorder.mediaRecorder = null
- audioRecorder.streamBeingCaptured = null
-
- /*No need to remove event listeners attached to mediaRecorder as
- If a DOM element which is removed is reference-free (no references pointing to it), the element itself is picked
- up by the garbage collector as well as any event handlers/listeners associated with it.
- getEventListeners(audioRecorder.mediaRecorder) will return an empty array of events.*/
- }
-}
diff --git a/packages/ui/src/views/chatmessage/audio-recording.css b/packages/ui/src/views/chatmessage/audio-recording.css
index 5ba0fa50..fbca2f60 100644
--- a/packages/ui/src/views/chatmessage/audio-recording.css
+++ b/packages/ui/src/views/chatmessage/audio-recording.css
@@ -20,6 +20,7 @@
justify-content: center;
/*horizontal centering*/
align-items: center;
+ background-color: white;
}
.start-recording-button {
font-size: 70px;
@@ -40,6 +41,7 @@
align-items: center;
width: 334px;
margin-bottom: 30px;
+ background-color: white;
}
.cancel-recording-button,
.stop-recording-button {
@@ -61,6 +63,7 @@
color: #27a527;
}
.recording-elapsed-time {
+ font-size: 32px;
/*targeting Chrome & Safari*/
display: -webkit-flex;
/*targeting IE10*/
diff --git a/packages/ui/src/views/chatmessage/audio-recording.js b/packages/ui/src/views/chatmessage/audio-recording.js
index 395443fe..f5cba001 100644
--- a/packages/ui/src/views/chatmessage/audio-recording.js
+++ b/packages/ui/src/views/chatmessage/audio-recording.js
@@ -1,41 +1,21 @@
+/**
+ * @fileoverview This file contains the API to handle audio recording.
+ * Originally from 'https://ralzohairi.medium.com/audio-recording-in-javascript-96eed45b75ee'
+ */
+
// audio-recording.js ---------------
-//View
-let microphoneButton = document.getElementsByClassName('start-recording-button')[0]
-let recordingControlButtonsContainer = document.getElementsByClassName('recording-control-buttons-container')[0]
-let stopRecordingButton = document.getElementsByClassName('stop-recording-button')[0]
-let cancelRecordingButton = document.getElementsByClassName('cancel-recording-button')[0]
-let elapsedTimeTag = document.getElementsByClassName('elapsed-time')[0]
-let closeBrowserNotSupportedBoxButton = document.getElementsByClassName('close-browser-not-supported-box')[0]
-let overlay = document.getElementsByClassName('overlay')[0]
-let audioElement = document.getElementsByClassName('audio-element')[0]
-let audioElementSource = document.getElementsByClassName('audio-element')[0].getElementsByTagName('source')[0]
-let textIndicatorOfAudiPlaying = document.getElementsByClassName('text-indication-of-audio-playing')[0]
+let microphoneButton, elapsedTimeTag
-//Listeners
-
-//Listen to start recording button
-microphoneButton.onclick = startAudioRecording
-
-//Listen to stop recording button
-stopRecordingButton.onclick = stopAudioRecording
-
-//Listen to cancel recording button
-cancelRecordingButton.onclick = cancelAudioRecording
-
-//Listen to when the ok button is clicked in the browser not supporting audio recording box
-closeBrowserNotSupportedBoxButton.onclick = hideBrowserNotSupportedOverlay
-
-//Listen to when the audio being played ends
-audioElement.onended = hideTextIndicatorOfAudioPlaying
+/** Initialize controls */
+function initializeControls() {
+ microphoneButton = document.getElementsByClassName('start-recording-button')[0]
+}
/** Displays recording control buttons */
function handleDisplayingRecordingControlButtons() {
//Hide the microphone button that starts audio recording
microphoneButton.style.display = 'none'
- //Display the recording control buttons
- recordingControlButtonsContainer.classList.remove('hide')
-
//Handle the displaying of the elapsed recording time
handleElapsedRecordingTime()
}
@@ -45,43 +25,10 @@ function handleHidingRecordingControlButtons() {
//Display the microphone button that starts audio recording
microphoneButton.style.display = 'block'
- //Hide the recording control buttons
- recordingControlButtonsContainer.classList.add('hide')
-
//stop interval that handles both time elapsed and the red dot
clearInterval(elapsedTimeTimer)
}
-/** Displays browser not supported info box for the user*/
-function displayBrowserNotSupportedOverlay() {
- overlay.classList.remove('hide')
-}
-
-/** Displays browser not supported info box for the user*/
-function hideBrowserNotSupportedOverlay() {
- overlay.classList.add('hide')
-}
-
-/** Creates a source element for the audio element in the HTML document*/
-function createSourceForAudioElement() {
- let sourceElement = document.createElement('source')
- audioElement.appendChild(sourceElement)
-
- audioElementSource = sourceElement
-}
-
-/** Display the text indicator of the audio being playing in the background */
-function displayTextIndicatorOfAudioPlaying() {
- textIndicatorOfAudiPlaying.classList.remove('hide')
-}
-
-/** Hide the text indicator of the audio being playing in the background */
-function hideTextIndicatorOfAudioPlaying() {
- textIndicatorOfAudiPlaying.classList.add('hide')
-}
-
-//Controller
-
/** Stores the actual start time when an audio recording begins to take place to ensure elapsed time start time is accurate*/
let audioRecordStartTime
@@ -92,24 +39,17 @@ let maximumRecordingTimeInHours = 1
let elapsedTimeTimer
/** Starts the audio recording*/
-function startAudioRecording() {
- console.log('Recording Audio...')
-
- //If a previous audio recording is playing, pause it
- let recorderAudioIsPlaying = !audioElement.paused // the paused property tells whether the media element is paused or not
- console.log('paused?', !recorderAudioIsPlaying)
- if (recorderAudioIsPlaying) {
- audioElement.pause()
- //also hide the audio playing indicator displayed on the screen
- hideTextIndicatorOfAudioPlaying()
- }
+export function startAudioRecording(onRecordingStart, onUnsupportedBrowser) {
+ initializeControls()
//start recording using the audio recording API
audioRecorder
.start()
.then(() => {
- //on success
-
+ //on success show the controls to stop and cancel the recording
+ if (onRecordingStart) {
+ onRecordingStart(true)
+ }
//store the recording start time to display the elapsed time according to it
audioRecordStartTime = new Date()
@@ -120,8 +60,9 @@ function startAudioRecording() {
//on error
//No Browser Support Error
if (error.message.includes('mediaDevices API or getUserMedia method is not supported in this browser.')) {
- console.log('To record audio, use browsers like Chrome and Firefox.')
- displayBrowserNotSupportedOverlay()
+ if (onUnsupportedBrowser) {
+ onUnsupportedBrowser(true)
+ }
}
//Error handling structure
@@ -157,18 +98,16 @@ function startAudioRecording() {
}
/** Stop the currently started audio recording & sends it
*/
-function stopAudioRecording() {
- console.log('Stopping Audio Recording...')
-
+export function stopAudioRecording(addRecordingToPreviews) {
//stop the recording using the audio recording API
audioRecorder
.stop()
- .then((audioAsblob) => {
- //Play recorder audio
- playAudio(audioAsblob)
-
+ .then((audioBlob) => {
//hide recording control button & return record icon
handleHidingRecordingControlButtons()
+ if (addRecordingToPreviews) {
+ addRecordingToPreviews(audioBlob)
+ }
})
.catch((error) => {
//Error handling structure
@@ -183,9 +122,7 @@ function stopAudioRecording() {
}
/** Cancel the currently started audio recording */
-function cancelAudioRecording() {
- console.log('Canceling audio...')
-
+export function cancelAudioRecording() {
//cancel the recording using the audio recording API
audioRecorder.cancel()
@@ -193,50 +130,9 @@ function cancelAudioRecording() {
handleHidingRecordingControlButtons()
}
-/** Plays recorded audio using the audio element in the HTML document
- * @param {Blob} recorderAudioAsBlob - recorded audio as a Blob Object
- */
-function playAudio(recorderAudioAsBlob) {
- //read content of files (Blobs) asynchronously
- let reader = new FileReader()
-
- //once content has been read
- reader.onload = (e) => {
- //store the base64 URL that represents the URL of the recording audio
- let base64URL = e.target.result
-
- //If this is the first audio playing, create a source element
- //as pre-populating the HTML with a source of empty src causes error
- if (!audioElementSource)
- //if it is not defined create it (happens first time only)
- createSourceForAudioElement()
-
- //set the audio element's source using the base64 URL
- audioElementSource.src = base64URL
-
- //set the type of the audio element based on the recorded audio's Blob type
- let BlobType = recorderAudioAsBlob.type.includes(';')
- ? recorderAudioAsBlob.type.substr(0, recorderAudioAsBlob.type.indexOf(';'))
- : recorderAudioAsBlob.type
- audioElementSource.type = BlobType
-
- //call the load method as it is used to update the audio element after changing the source or other settings
- audioElement.load()
-
- //play the audio after successfully setting new src and type that corresponds to the recorded audio
- console.log('Playing audio...')
- audioElement.play()
-
- //Display text indicator of having the audio play in the background
- displayTextIndicatorOfAudioPlaying()
- }
-
- //read content and convert it to a URL (base64)
- reader.readAsDataURL(recorderAudioAsBlob)
-}
-
/** Computes the elapsed recording time since the moment the function is called in the format h:m:s*/
function handleElapsedRecordingTime() {
+ elapsedTimeTag = document.getElementById('elapsed-time')
//display initial time when recording begins
displayElapsedTimeDuringAudioRecording('00:00')
@@ -255,7 +151,6 @@ function handleElapsedRecordingTime() {
function displayElapsedTimeDuringAudioRecording(elapsedTime) {
//1. display the passed elapsed time as the elapsed time in the elapsedTime HTML element
elapsedTimeTag.innerHTML = elapsedTime
-
//2. Stop the recording when the max number of hours is reached
if (elapsedTimeReachedMaximumNumberOfHours(elapsedTime)) {
stopAudioRecording()
@@ -275,9 +170,7 @@ function elapsedTimeReachedMaximumNumberOfHours(elapsedTime) {
maximumRecordingTimeInHours < 10 ? '0' + maximumRecordingTimeInHours : maximumRecordingTimeInHours.toString()
//if the elapsed time reach hours and also reach the maximum recording time in hours return true
- if (elapsedTimeSplit.length === 3 && elapsedTimeSplit[0] === maximumRecordingTimeInHoursAsString) return true
- //otherwise, return false
- else return false
+ return elapsedTimeSplit.length === 3 && elapsedTimeSplit[0] === maximumRecordingTimeInHoursAsString
}
/** Computes the elapsedTime since the moment the function is called in the format mm:ss or hh:mm:ss
@@ -331,7 +224,7 @@ function computeElapsedTime(startTime) {
//API to handle audio recording
-const audioRecorder = {
+export const audioRecorder = {
/** Stores the recorded audio as Blob objects of audio data as the recording continues*/
audioBlobs: [] /*of type Blob[]*/,
/** Stores the reference of the MediaRecorder instance that handles the MediaStream when recording starts*/
@@ -360,8 +253,8 @@ const audioRecorder = {
audioRecorder.streamBeingCaptured = stream
//create a media recorder instance by passing that stream into the MediaRecorder constructor
- audioRecorder.mediaRecorder = new MediaRecorder(stream) /*the MediaRecorder interface of the MediaStream Recording
- API provides functionality to easily record media*/
+ audioRecorder.mediaRecorder = new MediaRecorder(stream)
+ /*the MediaRecorder interface of the MediaStream Recording API provides functionality to easily record media*/
//clear previously saved audio Blobs, if any
audioRecorder.audioBlobs = []