Skip to content

Commit

Permalink
fix: AAC audio type not playing on web (#32763)
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigok committed Jul 15, 2024
1 parent 3b4b19c commit 48ea8fc
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 7 deletions.
4 changes: 2 additions & 2 deletions apps/meteor/app/api/server/lib/getUploadFormData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export async function getUploadFormData<
function onFile(
fieldname: string,
file: Readable & { truncated: boolean },
{ filename, encoding }: { filename: string; encoding: string },
{ filename, encoding, mimeType: mimetype }: { filename: string; encoding: string; mimeType: string },
) {
if (options.field && fieldname !== options.field) {
file.resume();
Expand All @@ -85,7 +85,7 @@ export async function getUploadFormData<
file,
filename,
encoding,
mimetype: getMimeType(filename),
mimetype: getMimeType(mimetype, filename),
fieldname,
fields,
fileBuffer: Buffer.concat(fileChunks),
Expand Down
89 changes: 89 additions & 0 deletions apps/meteor/app/utils/lib/mimeTypes.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { expect } from 'chai';

import { getExtension, getMimeType } from './mimeTypes';

const mimeTypeToExtension = {
'text/plain': 'txt',
'image/x-icon': 'ico',
'image/vnd.microsoft.icon': 'ico',
'image/png': 'png',
'image/jpeg': 'jpeg',
'image/gif': 'gif',
'image/webp': 'webp',
'image/svg+xml': 'svg',
'image/bmp': 'bmp',
'image/tiff': 'tif',
'audio/wav': 'wav',
'audio/wave': 'wav',
'audio/aac': 'aac',
'audio/x-aac': 'aac',
'audio/mp4': 'm4a',
'audio/mpeg': 'mpga',
'audio/ogg': 'oga',
'application/octet-stream': 'bin',
};

const extensionToMimeType = {
lst: 'text/plain',
txt: 'text/plain',
ico: 'image/x-icon',
png: 'image/png',
jpeg: 'image/jpeg',
gif: 'image/gif',
webp: 'image/webp',
svg: 'image/svg+xml',
bmp: 'image/bmp',
tiff: 'image/tiff',
tif: 'image/tiff',
wav: 'audio/wav',
aac: 'audio/aac',
mp3: 'audio/mpeg',
ogg: 'audio/ogg',
oga: 'audio/ogg',
m4a: 'audio/mp4',
mpga: 'audio/mpeg',
mp4: 'video/mp4',
bin: 'application/octet-stream',
};

describe('mimeTypes', () => {
describe('getExtension', () => {
for (const [mimeType, extension] of Object.entries(mimeTypeToExtension)) {
it(`should return the correct extension ${extension} for the given mimeType ${mimeType}`, async () => {
expect(getExtension(mimeType)).to.be.eql(extension);
});
}

it('should return an empty string if the mimeType is not found', async () => {
expect(getExtension('application/unknown')).to.be.eql('');
});
});

describe('getMimeType', () => {
for (const [extension, mimeType] of Object.entries(extensionToMimeType)) {
it(`should return the correct mimeType ${mimeType} for the given fileName file.${extension} passing the correct mimeType`, async () => {
expect(getMimeType(mimeType, `file.${extension}`)).to.be.eql(mimeType);
});
}

it('should return the correct mimeType for the given fileName', async () => {
for (const [extension, mimeType] of Object.entries(extensionToMimeType)) {
expect(getMimeType('application/unknown', `file.${extension}`)).to.be.eql(mimeType);
}
});

it('should return the correct mimeType for the given fileName when informed mimeType is application/octet-stream', async () => {
for (const [extension, mimeType] of Object.entries(extensionToMimeType)) {
expect(getMimeType('application/octet-stream', `file.${extension}`)).to.be.eql(mimeType);
}
});

it('should return the mimeType if it is not application/octet-stream', async () => {
expect(getMimeType('audio/wav', 'file.wav')).to.be.eql('audio/wav');
});

it('should return application/octet-stream if the mimeType is not found', async () => {
expect(getMimeType('application/octet-stream', 'file.unknown')).to.be.eql('application/octet-stream');
});
});
});
13 changes: 10 additions & 3 deletions apps/meteor/app/utils/lib/mimeTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,23 @@ import mime from 'mime-type/with-db';
mime.types.wav = 'audio/wav';
mime.types.lst = 'text/plain';
mime.define('image/vnd.microsoft.icon', { source: '', extensions: ['ico'] }, mime.dupAppend);
mime.define('image/x-icon', { source: '', extensions: ['ico'] }, mime.dupAppend);
mime.types.ico = 'image/x-icon';
mime.define('image/x-icon', { source: '', extensions: ['ico'] }, mime.dupOverwrite);
mime.define('audio/aac', { source: '', extensions: ['aac'] }, mime.dupOverwrite);

const getExtension = (param: string): string => {
const extension = mime.extension(param);

return !extension || typeof extension === 'boolean' ? '' : extension;
};

const getMimeType = (fileName: string): string => {
const getMimeType = (mimetype: string, fileName: string): string => {
// If the extension from the mimetype is different from the file extension, the file
// extension may be wrong so use the informed mimetype
const extension = mime.extension(mimetype);
if (mimetype !== 'application/octet-stream' && extension && extension !== fileName.split('.').pop()) {
return mimetype;
}

const fileMimeType = mime.lookup(fileName);
return typeof fileMimeType === 'string' ? fileMimeType : 'application/octet-stream';
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const useFileUploadDropTarget = (): readonly [
const uniqueFiles = getUniqueFiles();

const uploads = Array.from(uniqueFiles).map((file) => {
Object.defineProperty(file, 'type', { value: getMimeType(file.name) });
Object.defineProperty(file, 'type', { value: getMimeType(file.type, file.name) });
return file;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const useFileUploadAction = (disabled: boolean): GenericMenuItemProps =>
const { getMimeType } = await import('../../../../../../../app/utils/lib/mimeTypes');
const filesToUpload = Array.from(fileInputRef?.current?.files ?? []).map((file) => {
Object.defineProperty(file, 'type', {
value: getMimeType(file.name),
value: getMimeType(file.type, file.name),
});
return file;
});
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const config: Config = {
'<rootDir>/app/livechat/server/api/**/*.spec.ts',
'<rootDir>/ee/app/authorization/server/validateUserRoles.spec.ts',
'<rootDir>/app/cloud/server/functions/supportedVersionsToken/**.spec.ts',
'<rootDir>/app/utils/lib/**.spec.ts',
],
transformIgnorePatterns: ['!/node_modules/jose'],
errorOnDeprecated: true,
Expand Down

0 comments on commit 48ea8fc

Please sign in to comment.