diff --git a/lib/media/media_source_engine.js b/lib/media/media_source_engine.js index b638b964e3..f2c8a84aa3 100644 --- a/lib/media/media_source_engine.js +++ b/lib/media/media_source_engine.js @@ -280,7 +280,7 @@ shaka.media.MediaSourceEngine = class { if (contentType == ContentType.VIDEO) { codecs = StreamUtils.getCorrectVideoCodecs(codecs); } else if (contentType == ContentType.AUDIO) { - codecs = StreamUtils.getCorrectAudioCodecs(codecs); + codecs = StreamUtils.getCorrectAudioCodecs(codecs, mimeType); } const extendedMimeType = MimeUtils.getExtendedType( stream, mimeType, codecs); diff --git a/lib/transmuxer/ts_transmuxer.js b/lib/transmuxer/ts_transmuxer.js index 1fb418c8d0..c8a65c4b9e 100644 --- a/lib/transmuxer/ts_transmuxer.js +++ b/lib/transmuxer/ts_transmuxer.js @@ -144,13 +144,17 @@ shaka.transmuxer.TsTransmuxer = class { convertCodecs(contentType, mimeType) { if (this.isTsContainer_(mimeType)) { const ContentType = shaka.util.ManifestParserUtils.ContentType; + const StreamUtils = shaka.util.StreamUtils; // The replace it's necessary because Firefox(the only browser that // supports MP3 in MP4) only support the MP3 codec with the mp3 string. // MediaSource.isTypeSupported('audio/mp4; codecs="mp4a.40.34"') -> false // MediaSource.isTypeSupported('audio/mp4; codecs="mp3"') -> true const codecs = shaka.util.MimeUtils.getCodecs(mimeType) .replace('mp4a.40.34', 'mp3').split(',') - .map(shaka.util.StreamUtils.getCorrectVideoCodecs).join(','); + .map((codecs) => { + return StreamUtils.getCorrectAudioCodecs(codecs, 'audio/mp4'); + }) + .map(StreamUtils.getCorrectVideoCodecs).join(','); if (contentType == ContentType.AUDIO) { return `audio/mp4; codecs="${codecs}"`; } diff --git a/lib/util/stream_utils.js b/lib/util/stream_utils.js index 5e48afd5bd..98eaf7845d 100644 --- a/lib/util/stream_utils.js +++ b/lib/util/stream_utils.js @@ -439,7 +439,8 @@ shaka.util.StreamUtils = class { videoCodecs = StreamUtils.getCorrectVideoCodecs(videoCodecs); let audioCodecs = ManifestParserUtils.guessCodecs( ContentType.AUDIO, allCodecs); - audioCodecs = StreamUtils.getCorrectAudioCodecs(audioCodecs); + audioCodecs = StreamUtils.getCorrectAudioCodecs( + audioCodecs, video.mimeType); const audioFullType = MimeUtils.getFullOrConvertedType( video.mimeType, audioCodecs, ContentType.AUDIO); @@ -475,7 +476,8 @@ shaka.util.StreamUtils = class { } if (audio) { - const codecs = StreamUtils.getCorrectAudioCodecs(audio.codecs); + const codecs = StreamUtils.getCorrectAudioCodecs( + audio.codecs, audio.mimeType); const fullType = MimeUtils.getFullOrConvertedType( audio.mimeType, codecs, ContentType.AUDIO); @@ -764,17 +766,18 @@ shaka.util.StreamUtils = class { // We ignore the multiplexed audio when there is normal audio also. if (videoCodecs.includes(',') && !audio) { const allCodecs = videoCodecs.split(','); + const baseMimeType = MimeUtils.getBasicType(fullMimeType); videoCodecs = ManifestParserUtils.guessCodecs( ContentType.VIDEO, allCodecs); let audioCodecs = ManifestParserUtils.guessCodecs( ContentType.AUDIO, allCodecs); - audioCodecs = StreamUtils.getCorrectAudioCodecs(audioCodecs); + audioCodecs = StreamUtils.getCorrectAudioCodecs( + audioCodecs, baseMimeType); const audioFullType = MimeUtils.getFullOrConvertedType( - MimeUtils.getBasicType(fullMimeType), audioCodecs, - ContentType.AUDIO); + baseMimeType, audioCodecs, ContentType.AUDIO); audioConfigs.push({ contentType: audioFullType, @@ -825,10 +828,11 @@ shaka.util.StreamUtils = class { } if (audio) { for (const fullMimeType of audio.fullMimeTypes) { - const codecs = StreamUtils.getCorrectAudioCodecs(MimeUtils.getCodecs( - fullMimeType)); + const baseMimeType = MimeUtils.getBasicType(fullMimeType); + const codecs = StreamUtils.getCorrectAudioCodecs( + MimeUtils.getCodecs(fullMimeType), baseMimeType); const fullType = MimeUtils.getFullOrConvertedType( - MimeUtils.getBasicType(fullMimeType), codecs, ContentType.AUDIO); + baseMimeType, codecs, ContentType.AUDIO); // AudioConfiguration audioConfigs.push({ @@ -991,9 +995,10 @@ shaka.util.StreamUtils = class { * Generates the correct audio codec for MediaDecodingConfiguration and * for MediaSource.isTypeSupported. * @param {string} codecs + * @param {string} mimeType * @return {string} */ - static getCorrectAudioCodecs(codecs) { + static getCorrectAudioCodecs(codecs, mimeType) { // According to RFC 6381 section 3.3, 'fLaC' is actually the correct // codec string. We still need to map it to 'flac', as some browsers // currently don't support 'fLaC', while 'flac' is supported by most @@ -1008,8 +1013,16 @@ shaka.util.StreamUtils = class { } // The same is true for 'Opus'. - if (codecs === 'Opus') { - return 'opus'; + if (codecs.toLowerCase() === 'opus') { + if (!shaka.util.Platform.isSafari()) { + return 'opus'; + } else { + if (shaka.util.MimeUtils.getContainerType(mimeType) == 'mp4') { + return 'Opus'; + } else { + return 'opus'; + } + } } return codecs; diff --git a/test/test/util/util.js b/test/test/util/util.js index 87927d3c04..35bfe30ca8 100644 --- a/test/test/util/util.js +++ b/test/test/util/util.js @@ -319,6 +319,7 @@ shaka.test.Util = class { */ static async isTypeSupported(mimetype, width, height) { const MimeUtils = shaka.util.MimeUtils; + const ContentType = shaka.util.ManifestParserUtils.ContentType; const StreamUtils = shaka.util.StreamUtils; /** @type {!MediaDecodingConfiguration} */ @@ -326,8 +327,9 @@ shaka.test.Util = class { type: 'media-source', }; if (mimetype.startsWith('audio')) { + const baseMimeType = MimeUtils.getBasicType(mimetype); const codecs = StreamUtils.getCorrectAudioCodecs( - MimeUtils.getCodecs(mimetype)); + MimeUtils.getCodecs(mimetype), baseMimeType); if (codecs == 'ac-3' && shaka.util.Platform.isTizen()) { // AC3 is flaky in some Tizen devices, so we need omit it for now. return false; @@ -341,10 +343,10 @@ shaka.test.Util = class { // https://bugs.chromium.org/p/chromium/issues/detail?id=1450313 return false; } - const baseMimeType = MimeUtils.getBasicType(mimetype); // AudioConfiguration mediaDecodingConfig.audio = { - contentType: MimeUtils.getFullType(baseMimeType, codecs), + contentType: MimeUtils.getFullOrConvertedType( + baseMimeType, codecs, ContentType.AUDIO), }; } else { const codecs = StreamUtils.getCorrectVideoCodecs( @@ -352,7 +354,8 @@ shaka.test.Util = class { const baseMimeType = MimeUtils.getBasicType(mimetype); // VideoConfiguration mediaDecodingConfig.video = { - contentType: MimeUtils.getFullType(baseMimeType, codecs), + contentType: MimeUtils.getFullOrConvertedType( + baseMimeType, codecs, ContentType.VIDEO), // NOTE: Some decoders strictly check the width and height fields and // won't decode smaller than 64x64. So if we don't have this info (as