diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2021-01-18 22:01:08 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-18 22:01:08 -0500 | 
| commit | 21fce9f3d98e4381f8813cf9c63410ca1dbd7f91 (patch) | |
| tree | 124a510e4f208bbd7516b2eae98454400e9b4c54 | |
| parent | 85c723b85f47ff3048ba7aca46a532aa1bc44064 (diff) | |
Audio system refactoring (#1275)
* Simplify details
* Simplify audio creation
* Return an array of sources instead of a single item
* Use sourceIndex instead of index
* Rename APIs
* Return more info about the source
* Return source instead of sourceIndex
| -rw-r--r-- | ext/bg/js/audio-downloader.js | 41 | ||||
| -rw-r--r-- | ext/bg/js/backend.js | 8 | ||||
| -rw-r--r-- | ext/mixed/js/api.js | 4 | ||||
| -rw-r--r-- | ext/mixed/js/audio-system.js | 60 | ||||
| -rw-r--r-- | ext/mixed/js/display-audio.js | 7 | 
5 files changed, 55 insertions, 65 deletions
| diff --git a/ext/bg/js/audio-downloader.js b/ext/bg/js/audio-downloader.js index 19e9c368..171f5944 100644 --- a/ext/bg/js/audio-downloader.js +++ b/ext/bg/js/audio-downloader.js @@ -34,7 +34,7 @@ class AudioDownloader {          ]);      } -    async getInfo(source, expression, reading, details) { +    async getExpressionAudioInfoList(source, expression, reading, details) {          const handler = this._getInfoHandlers.get(source);          if (typeof handler === 'function') {              try { @@ -43,23 +43,22 @@ class AudioDownloader {                  // NOP              }          } -        return null; +        return [];      } -    async downloadAudio(sources, expression, reading, details) { +    async downloadExpressionAudio(sources, expression, reading, details) {          for (const source of sources) { -            const info = await this.getInfo(source, expression, reading, details); -            if (info === null) { continue; } - -            switch (info.type) { -                case 'url': -                    try { -                        const {details: {url}} = info; -                        return await this._downloadAudioFromUrl(url); -                    } catch (e) { -                        // NOP -                    } -                    break; +            const infoList = await this.getExpressionAudioInfoList(source, expression, reading, details); +            for (const info of infoList) { +                switch (info.type) { +                    case 'url': +                        try { +                            return await this._downloadAudioFromUrl(info.url); +                        } catch (e) { +                            // NOP +                        } +                        break; +                }              }          } @@ -90,7 +89,7 @@ class AudioDownloader {          }          const url = `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`; -        return {type: 'url', details: {url}}; +        return [{type: 'url', url}];      }      async _getInfoJpod101Alternate(expression, reading) { @@ -128,7 +127,7 @@ class AudioDownloader {                  const htmlReading = dom.getTextContent(htmlReadings[0]);                  if (htmlReading && (!reading || reading === htmlReading)) {                      url = this._normalizeUrl(url, response.url); -                    return {type: 'url', details: {url}}; +                    return [{type: 'url', url}];                  }              } catch (e) {                  // NOP @@ -159,7 +158,7 @@ class AudioDownloader {                      let url = dom.getAttribute(source, 'src');                      if (url !== null) {                          url = this._normalizeUrl(url, response.url); -                        return {type: 'url', details: {url}}; +                        return [{type: 'url', url}];                      }                  }              } @@ -174,14 +173,14 @@ class AudioDownloader {          if (!textToSpeechVoice) {              throw new Error('No voice');          } -        return {type: 'tts', details: {text: expression, voice: textToSpeechVoice}}; +        return [{type: 'tts', text: expression, voice: textToSpeechVoice}];      }      async _getInfoTextToSpeechReading(expression, reading, {textToSpeechVoice}) {          if (!textToSpeechVoice) {              throw new Error('No voice');          } -        return {type: 'tts', details: {text: reading || expression, voice: textToSpeechVoice}}; +        return [{type: 'tts', text: reading || expression, voice: textToSpeechVoice}];      }      async _getInfoCustom(expression, reading, {customSourceUrl}) { @@ -190,7 +189,7 @@ class AudioDownloader {          }          const data = {expression, reading};          const url = customSourceUrl.replace(/\{([^}]*)\}/g, (m0, m1) => (Object.prototype.hasOwnProperty.call(data, m1) ? `${data[m1]}` : m0)); -        return {type: 'url', details: {url}}; +        return [{type: 'url', url}];      }      async _downloadAudioFromUrl(url) { diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 433f5a93..2949cbed 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -99,7 +99,7 @@ class Backend {              ['noteView',                     {async: true,  contentScript: true,  handler: this._onApiNoteView.bind(this)}],              ['suspendAnkiCardsForNote',      {async: true,  contentScript: true,  handler: this._onApiSuspendAnkiCardsForNote.bind(this)}],              ['commandExec',                  {async: false, contentScript: true,  handler: this._onApiCommandExec.bind(this)}], -            ['getDefinitionAudioInfo',       {async: true,  contentScript: true,  handler: this._onApiGetDefinitionAudioInfo.bind(this)}], +            ['getExpressionAudioInfoList',   {async: true,  contentScript: true,  handler: this._onApiGetExpressionAudioInfoList.bind(this)}],              ['downloadDefinitionAudio',      {async: true,  contentScript: true,  handler: this._onApiDownloadDefinitionAudio.bind(this)}],              ['screenshotGet',                {async: true,  contentScript: true,  handler: this._onApiScreenshotGet.bind(this)}],              ['sendMessageToFrame',           {async: false, contentScript: true,  handler: this._onApiSendMessageToFrame.bind(this)}], @@ -500,8 +500,8 @@ class Backend {          return this._runCommand(command, params);      } -    async _onApiGetDefinitionAudioInfo({source, expression, reading, details}) { -        return await this._audioDownloader.getInfo(source, expression, reading, details); +    async _onApiGetExpressionAudioInfoList({source, expression, reading, details}) { +        return await this._audioDownloader.getExpressionAudioInfoList(source, expression, reading, details);      }      async _onApiDownloadDefinitionAudio({sources, expression, reading, details}) { @@ -1528,7 +1528,7 @@ class Backend {      }      async _downloadDefinitionAudio(sources, expression, reading, details) { -        return await this._audioDownloader.downloadAudio(sources, expression, reading, details); +        return await this._audioDownloader.downloadExpressionAudio(sources, expression, reading, details);      }      async _injectAnkNoteMedia(ankiConnect, timestamp, definitionDetails, audioDetails, screenshotDetails, clipboardDetails) { diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js index 433a52e2..03e58f5e 100644 --- a/ext/mixed/js/api.js +++ b/ext/mixed/js/api.js @@ -97,8 +97,8 @@ const api = (() => {              return this._invoke('suspendAnkiCardsForNote', {noteId});          } -        getDefinitionAudioInfo(source, expression, reading, details) { -            return this._invoke('getDefinitionAudioInfo', {source, expression, reading, details}); +        getExpressionAudioInfoList(source, expression, reading, details) { +            return this._invoke('getExpressionAudioInfoList', {source, expression, reading, details});          }          downloadDefinitionAudio(sources, expression, reading, details) { diff --git a/ext/mixed/js/audio-system.js b/ext/mixed/js/audio-system.js index 19c85690..f42fd657 100644 --- a/ext/mixed/js/audio-system.js +++ b/ext/mixed/js/audio-system.js @@ -36,47 +36,30 @@ class AudioSystem {          eventListeners.addEventListener(speechSynthesis, 'voiceschanged', onVoicesChanged, false);      } -    async createDefinitionAudio(sources, expression, reading, details) { +    async createExpressionAudio(sources, expression, reading, details) {          const key = [expression, reading];          const cacheValue = this._cache.get(key);          if (typeof cacheValue !== 'undefined') { -            const {audio, source} = cacheValue; -            const index = sources.indexOf(source); -            if (index >= 0) { -                return {audio, index}; -            } +            return cacheValue;          }          for (let i = 0, ii = sources.length; i < ii; ++i) {              const source = sources[i]; -            const info = await this._getAudioInfo(source, expression, reading, details); -            if (info === null) { continue; } - -            let audio; -            try { -                switch (info.type) { -                    case 'url': -                        { -                            const {details: {url}} = info; -                            audio = await this.createAudio(url); -                        } -                        break; -                    case 'tts': -                        { -                            const {details: {text, voice}} = info; -                            audio = this.createTextToSpeechAudio(text, voice); -                        } -                        break; -                    default: -                        throw new Error(`Unsupported type: ${info.type}`); +            const infoList = await await api.getExpressionAudioInfoList(source, expression, reading, details); +            for (let j = 0, jj = infoList.length; j < jj; ++j) { +                const info = infoList[j]; +                let audio; +                try { +                    audio = await this.createAudioFromInfo(info); +                } catch (e) { +                    continue;                  } -            } catch (e) { -                continue; -            } -            this._cache.set(key, {audio, source}); -            return {audio, index: i}; +                const result = {audio, source, infoList, infoListIndex: j}; +                this._cache.set(key, result); +                return result; +            }          }          throw new Error('Could not create audio'); @@ -111,12 +94,19 @@ class AudioSystem {          return new TextToSpeechAudio(text, voice);      } -    // Private - -    async _getAudioInfo(source, expression, reading, details) { -        return await api.getDefinitionAudioInfo(source, expression, reading, details); +    async createAudioFromInfo(info) { +        switch (info.type) { +            case 'url': +                return await this.createAudio(info.url); +            case 'tts': +                return this.createTextToSpeechAudio(info.text, info.voice); +            default: +                throw new Error(`Unsupported type: ${info.type}`); +        }      } +    // Private +      _isAudioValid(audio) {          const duration = audio.duration;          return ( diff --git a/ext/mixed/js/display-audio.js b/ext/mixed/js/display-audio.js index c423446e..0cd8a625 100644 --- a/ext/mixed/js/display-audio.js +++ b/ext/mixed/js/display-audio.js @@ -117,9 +117,10 @@ class DisplayAudio {              let audio;              let info;              try { -                let index; -                ({audio, index} = await this._audioSystem.createDefinitionAudio(sources, expression, reading, {textToSpeechVoice, customSourceUrl})); -                info = `From source ${1 + index}: ${sources[index]}`; +                let source; +                ({audio, source} = await this._audioSystem.createExpressionAudio(sources, expression, reading, {textToSpeechVoice, customSourceUrl})); +                const sourceIndex = sources.indexOf(source); +                info = `From source ${1 + sourceIndex}: ${source}`;              } catch (e) {                  audio = this._audioSystem.getFallbackAudio();                  info = 'Could not find audio'; |