diff --git a/ext/bg/js/audio-downloader.js b/ext/bg/js/audio-downloader.js index 62abda8f..25c25250 100644 --- a/ext/bg/js/audio-downloader.js +++ b/ext/bg/js/audio-downloader.js @@ -252,7 +252,9 @@ class AudioDownloader { throw new Error('Could not retrieve audio'); } - return this._arrayBufferToBase64(arrayBuffer); + const data = this._arrayBufferToBase64(arrayBuffer); + const contentType = response.headers.get('Content-Type'); + return {data, contentType}; } async _isAudioBinaryValid(arrayBuffer, source) { diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 465c8137..e5f8466e 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -1604,8 +1604,9 @@ class Backend { const {sources, customSourceUrl, customSourceType} = details; let data; + let contentType; try { - data = await this._downloadDefinitionAudio( + ({data, contentType} = await this._downloadDefinitionAudio( sources, expression, reading, @@ -1616,13 +1617,15 @@ class Backend { binary: true, disableCache: true } - ); + )); } catch (e) { // No audio return null; } - let fileName = this._generateAnkiNoteMediaFileName('yomichan_audio', '.mp3', timestamp, definitionDetails); + let extension = this._mediaUtility.getFileExtensionFromAudioMediaType(contentType); + if (extension === null) { extension = '.mp3'; } + let fileName = this._generateAnkiNoteMediaFileName('yomichan_audio', extension, timestamp, definitionDetails); fileName = fileName.replace(/\]/g, ''); await ankiConnect.storeMediaFile(fileName, data); diff --git a/ext/bg/js/media-utility.js b/ext/bg/js/media-utility.js index b50b2481..b4fbe04d 100644 --- a/ext/bg/js/media-utility.js +++ b/ext/bg/js/media-utility.js @@ -98,4 +98,35 @@ class MediaUtility { return null; } } + + /** + * Gets the file extension for a corresponding media type. + * @param mediaType The media type to use. + * @returns A file extension including the dot for the media type, + * otherwise null. + */ + getFileExtensionFromAudioMediaType(mediaType) { + switch (mediaType) { + case 'audio/mpeg': + case 'audio/mp3': + return '.mp3'; + case 'audio/mp4': + return '.mp4'; + case 'audio/ogg': + case 'audio/vorbis': + return '.ogg'; + case 'audio/vnd.wav': + case 'audio/wave': + case 'audio/wav': + case 'audio/x-wav': + case 'audio/x-pn-wav': + return '.wav'; + case 'audio/flac': + return '.flac'; + case 'audio/webm': + return '.webm'; + default: + return null; + } + } }