Skip to content

Commit

Permalink
fix: determine audio recording format with MediaRecorder.isTypeSuppor…
Browse files Browse the repository at this point in the history
…ted not userAgent (#2639)
  • Loading branch information
MartinCupela authored Feb 11, 2025
1 parent 881e4b8 commit 1c445de
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 20 deletions.
15 changes: 6 additions & 9 deletions src/components/MediaRecorder/classes/MediaRecorderController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,18 @@ import {
} from '../../ReactFileUtilities';
import { TranslationContextValue } from '../../../context';
import { defaultTranslatorFunction } from '../../../i18n';
import { isSafari } from '../../../utils/browsers';
import { mergeDeepUndefined } from '../../../utils/mergeDeep';

import type { LocalVoiceRecordingAttachment } from '../../MessageInput';
import type { DefaultStreamChatGenerics } from '../../../types';

const RECORDED_MIME_TYPE_BY_BROWSER = {
export const RECORDED_MIME_TYPE_BY_BROWSER = {
audio: {
others: 'audio/webm',
safari: 'audio/mp4;codecs=mp4a.40.2',
},
} as const;

export const DEFAULT_MEDIA_RECORDER_CONFIG: MediaRecorderConfig = {
mimeType: isSafari()
? RECORDED_MIME_TYPE_BY_BROWSER.audio.safari
: RECORDED_MIME_TYPE_BY_BROWSER.audio.others,
} as const;

export const DEFAULT_AUDIO_TRANSCODER_CONFIG: TranscoderConfig = {
sampleRate: 16000,
} as const;
Expand Down Expand Up @@ -120,7 +113,11 @@ export class MediaRecorderController<

this.mediaRecorderConfig = mergeDeepUndefined(
{ ...config?.mediaRecorderConfig },
DEFAULT_MEDIA_RECORDER_CONFIG,
{
mimeType: MediaRecorder.isTypeSupported('audio/webm')
? RECORDED_MIME_TYPE_BY_BROWSER.audio.others
: RECORDED_MIME_TYPE_BY_BROWSER.audio.safari,
},
);

this.transcoderConfig = mergeDeepUndefined(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import * as transcoder from '../../transcode';
import * as wavTranscoder from '../../transcode/wav';
import {
DEFAULT_AUDIO_TRANSCODER_CONFIG,
DEFAULT_MEDIA_RECORDER_CONFIG,
MediaRecorderController,
MediaRecordingState,
RECORDED_MIME_TYPE_BY_BROWSER,
RecordingAttachmentType,
} from '../MediaRecorderController';
import {
Expand Down Expand Up @@ -92,10 +92,27 @@ describe('MediaRecorderController', () => {
});
afterEach(jest.clearAllMocks);

it('provides defaults on initiation', () => {
it('provides defaults on initiation (non-Safari)', () => {
const controller = new MediaRecorderController();
expect(controller.mediaRecorderConfig).toStrictEqual(
expect.objectContaining(DEFAULT_MEDIA_RECORDER_CONFIG),
expect.objectContaining({ mimeType: RECORDED_MIME_TYPE_BY_BROWSER.audio.others }),
);
expect(controller.transcoderConfig).toStrictEqual(
expect.objectContaining(DEFAULT_AUDIO_TRANSCODER_CONFIG),
);
expect(controller.amplitudeRecorderConfig).toStrictEqual(
expect.objectContaining(DEFAULT_AMPLITUDE_RECORDER_CONFIG),
);
expect(controller.t).toStrictEqual(defaultTranslatorFunction);
expect(controller.mediaType).toStrictEqual('audio');
expect(controller.customGenerateRecordingTitle).toBeUndefined();
});

it('provides defaults on initiation (Safari)', () => {
MediaRecorder.isTypeSupported.mockReturnValueOnce(false);
const controller = new MediaRecorderController();
expect(controller.mediaRecorderConfig).toStrictEqual(
expect.objectContaining({ mimeType: RECORDED_MIME_TYPE_BY_BROWSER.audio.safari }),
);
expect(controller.transcoderConfig).toStrictEqual(
expect.objectContaining(DEFAULT_AUDIO_TRANSCODER_CONFIG),
Expand Down Expand Up @@ -151,7 +168,7 @@ describe('MediaRecorderController', () => {
const controller = new MediaRecorderController({ generateRecordingTitle });
expect(controller.customGenerateRecordingTitle).toStrictEqual(generateRecordingTitle);
expect(controller.mediaRecorderConfig).toStrictEqual(
expect.objectContaining(DEFAULT_MEDIA_RECORDER_CONFIG),
expect.objectContaining({ mimeType: RECORDED_MIME_TYPE_BY_BROWSER.audio.others }),
);
expect(controller.transcoderConfig).toStrictEqual(
expect.objectContaining(DEFAULT_AUDIO_TRANSCODER_CONFIG),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { TranslationProvider } from '../../../../context';
import { renderHook } from '@testing-library/react';
import React from 'react';
import { useMediaRecorder } from '../useMediaRecorder';
import { EventEmitterMock } from '../../../../mock-builders/browser';
import { EventEmitterMock, MediaRecorderMock } from '../../../../mock-builders/browser';
import { act } from '@testing-library/react';
import { DEFAULT_AMPLITUDE_RECORDER_CONFIG } from '../../classes/AmplitudeRecorder';
import { DEFAULT_AUDIO_TRANSCODER_CONFIG } from '../../classes';
import { generateVoiceRecordingAttachment } from '../../../../mock-builders';

window.MediaRecorder = MediaRecorderMock;

const handleSubmit = jest.fn();
const uploadAttachment = jest.fn();

Expand All @@ -27,8 +29,8 @@ const render = async (params = {}) => {
<TranslationProvider value={translationContext}>{children}</TranslationProvider>
);
let result;
await act(() => {
result = renderHook(() => useMediaRecorder({ enabled: true, ...params }), {
await act(async () => {
result = await renderHook(() => useMediaRecorder({ enabled: true, ...params }), {
wrapper,
});
});
Expand Down
9 changes: 5 additions & 4 deletions src/mock-builders/browser/MediaRecorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { EventEmitterMock } from './EventEmitter';
export class MediaRecorderMock extends EventEmitterMock {
constructor() {
super();
this.start = jest.fn();
this.pause = jest.fn();
this.resume = jest.fn();
this.stop = jest.fn();
}

start = jest.fn();
pause = jest.fn();
resume = jest.fn();
stop = jest.fn();
static isTypeSupported = jest.fn().mockReturnValue(true);
}

0 comments on commit 1c445de

Please sign in to comment.