From e072b35854448c14d7d3b938e05c699385081c68 Mon Sep 17 00:00:00 2001 From: Jeff Schiller Date: Sat, 30 Sep 2023 11:17:16 -0700 Subject: [PATCH] Fix for m4a files as audio/mp4. Up-rev to 1.1.2. --- CHANGELOG.md | 4 ++++ codecs/codecs.js | 5 +++++ package-lock.json | 4 ++-- package.json | 2 +- tests/codecs.spec.js | 41 ++++++++++++++++++++++++++++------------- 5 files changed, 40 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38098ad..2f6eef3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## [1.1.2] - 2023-09-30 + +- codecs: Handle m4a files as audio/mp4. + ## [1.1.1] - 2023-06-21 - Fix missing RarVM import in unrar.js. diff --git a/codecs/codecs.js b/codecs/codecs.js index 7329860..fef8d5f 100644 --- a/codecs/codecs.js +++ b/codecs/codecs.js @@ -58,6 +58,11 @@ export function getShortMIMEString(info) { return 'audio/flac'; } + // M4A files are specifically audio/mp4. + if (info?.format?.filename?.toLowerCase().endsWith('.m4a')) { + return 'audio/mp4'; + } + // Otherwise, any file with at least 1 video stream is considered video/. // Otherwise, any file with at least 1 audio stream is considered audio/. const type = info.streams.some(s => s.codec_type === 'video') ? diff --git a/package-lock.json b/package-lock.json index 4b457c8..cb8a985 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@codedread/bitjs", - "version": "1.0.11", + "version": "1.1.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@codedread/bitjs", - "version": "1.0.11", + "version": "1.1.2", "license": "MIT", "devDependencies": { "c8": "^7.12.0", diff --git a/package.json b/package.json index db5e085..62889db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@codedread/bitjs", - "version": "1.1.1", + "version": "1.1.2", "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 c84fa58..b5f493f 100644 --- a/tests/codecs.spec.js +++ b/tests/codecs.spec.js @@ -75,6 +75,13 @@ describe('codecs test suite', () => { })).equals('audio/mpeg'); }); + it('detects M4A audio', () => { + expect(getShortMIMEString({ + format: { filename: 'sample.m4a', format_name: 'mov,mp4,m4a,3gp,3g2,mj2' }, + streams: [ { codec_type: 'video', }, { codec_type: 'audio' } ], + })).equals('audio/mp4'); + }); + it('detects MP4 video', () => { expect(getShortMIMEString({ format: { format_name: 'mov,mp4,m4a,3gp,3g2,mj2' }, @@ -306,24 +313,21 @@ describe('codecs test suite', () => { describe('MP4A / AAC', () => { /** @type {ProbeInfo} */ - let info; - - beforeEach(() => { - info = { - format: { format_name: 'mov,mp4,m4a,3gp,3g2,mj2' }, - streams: [{ - codec_type: 'audio', - codec_tag_string: 'mp4a', - }], - }; - }); + let baseInfo = { + format: { format_name: 'mov,mp4,m4a,3gp,3g2,mj2' }, + streams: [{ + codec_type: 'audio', + codec_tag_string: 'mp4a', + }], + }; it('throws when unknown', () => { - expect(() => getFullMIMEString(info)).to.throw(); + expect(() => getFullMIMEString(baseInfo)).to.throw(); }); describe('Profile tests', () => { it('recognizes AAC-LC', () => { + const info = structuredClone(baseInfo); info.streams[0].profile = 'LC'; expect(getFullMIMEString(info)) .to.be.a('string') @@ -332,6 +336,7 @@ describe('codecs test suite', () => { }); it('handles codec_name=aac but no codec_tag_string', () => { + const info = structuredClone(baseInfo); info.streams[0].profile = 'LC'; info.streams[0].codec_tag_string = '[0][0][0][0]'; info.streams[0].codec_name = 'aac'; @@ -339,6 +344,16 @@ describe('codecs test suite', () => { .to.be.a('string') .and.equals('audio/mp4; codecs="mp4a.40.2"'); }); + + it('handles m4a file with MJPEG stream', () => { + const info = structuredClone(baseInfo); + info.format.filename = 'sample.m4a'; + info.streams[0].profile = 'LC'; + info.streams.push({codec_name: 'mjpeg', codec_type: 'video', profile: 'Baseline'}); + expect(getFullMIMEString(info)) + .to.be.a('string') + .and.equals('audio/mp4; codecs="mp4a.40.2"'); + }) }); describe('MP4 / FLAC', () => { @@ -374,7 +389,7 @@ describe('codecs test suite', () => { expect(getFullMIMEString(vInfo)) .to.be.a('string') .and.equals('video/mp4; codecs="flac"'); - + }); });