diff --git a/CHANGELOG.md b/CHANGELOG.md index b212c19..8b70f9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## [1.1.3] - 2023-10-15 + +### Changed + +- codecs: Add support for WAV files to getShortMIMEString() and getFullMIMEString(). +- codecs: Fix support for AVI files in getFullMIMEString(). + ## [1.1.2] - 2023-09-30 ### Changed diff --git a/codecs/codecs.js b/codecs/codecs.js index fef8d5f..9d978fa 100644 --- a/codecs/codecs.js +++ b/codecs/codecs.js @@ -42,6 +42,17 @@ * @property {ProbeFormat} format */ +/** + * Maps the ffprobe format.format_name string to a short MIME type. + * @type {Object} + */ +const FORMAT_NAME_TO_SHORT_TYPE = { + 'avi': 'video/x-msvideo', + 'flac': 'audio/flac', + 'mp3': 'audio/mpeg', + 'wav': 'audio/wav', +} + /** * TODO: Reconcile this with file/sniffer.js findMimeType() which does signature matching. * @param {ProbeInfo} info @@ -51,11 +62,9 @@ export function getShortMIMEString(info) { if (!info) throw `Invalid ProbeInfo`; if (!info.streams || info.streams.length === 0) throw `No streams in ProbeInfo`; - // mp3/flac files are always considered audio/ (even with mjpeg video streams). - if (info.format.format_name === 'mp3') { - return 'audio/mpeg'; - } else if (info.format.format_name === 'flac') { - return 'audio/flac'; + const formatName = info?.format?.format_name; + if (formatName && Object.keys(FORMAT_NAME_TO_SHORT_TYPE).includes(formatName)) { + return FORMAT_NAME_TO_SHORT_TYPE[formatName]; } // M4A files are specifically audio/mp4. @@ -75,10 +84,7 @@ export function getShortMIMEString(info) { /** @type {string} */ let subType; - switch (info.format.format_name) { - case 'avi': - subType = 'x-msvideo'; - break; + switch (formatName) { case 'mpeg': subType = 'mpeg'; break; @@ -93,7 +99,7 @@ export function getShortMIMEString(info) { subType = 'webm'; break; default: - throw `Cannot handle format ${info.format.format_name} yet. ` + + throw `Cannot handle format ${formatName} yet. ` + `Please file a bug https://github.com/codedread/bitjs/issues/new`; } @@ -113,9 +119,7 @@ export function getShortMIMEString(info) { export function getFullMIMEString(info) { /** A string like 'video/mp4' */ let contentType = `${getShortMIMEString(info)}`; - // If MP3/FLAC, just send back the type. - if (contentType === 'audio/mpeg' - || contentType === 'audio/flac') { + if (Object.values(FORMAT_NAME_TO_SHORT_TYPE).includes(contentType)) { return contentType; } diff --git a/package.json b/package.json index 62889db..e818f25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@codedread/bitjs", - "version": "1.1.2", + "version": "1.1.3", "description": "Binary Tools for JavaScript", "homepage": "https://github.com/codedread/bitjs", "author": "Jeff Schiller", diff --git a/tests/codecs.spec.js b/tests/codecs.spec.js index b5f493f..6b783c2 100644 --- a/tests/codecs.spec.js +++ b/tests/codecs.spec.js @@ -455,4 +455,40 @@ describe('codecs test suite', () => { .and.equals('audio/webm; codecs="ac-3"'); }); }); + + describe('AVI', () => { + it('detects AVI', () => { + /** @type {ProbeInfo} */ + let info = { + format: { format_name: 'avi' }, + streams: [ + { codec_type: 'video', codec_name: 'mpeg4', codec_tag_string: 'XVID' }, + { codec_type: 'audio', codec_name: 'mp3' }, + { codec_type: 'audio', codec_name: 'mp3' }, + ], + }; + expect(getShortMIMEString(info)) + .to.be.a('string') + .and.equals('video/x-msvideo'); + expect(getFullMIMEString(info)) + .to.be.a('string') + .and.equals('video/x-msvideo'); + }); + }); + + describe('WAV', () => { + it('detects WAV', () => { + /** @type {ProbeInfo} */ + let info = { + format: { format_name: 'wav' }, + streams: [ { codec_type: 'audio', codec_name: 'pcm_s16le' } ], + }; + expect(getShortMIMEString(info)) + .to.be.a('string') + .and.equals('audio/wav'); + expect(getFullMIMEString(info)) + .to.be.a('string') + .and.equals('audio/wav'); + }); + }); });