diff options
Diffstat (limited to 'ext/bg/js')
-rw-r--r-- | ext/bg/js/anki-note-builder.js | 47 | ||||
-rw-r--r-- | ext/bg/js/backend.js | 2 | ||||
-rw-r--r-- | ext/bg/js/options.js | 19 |
3 files changed, 43 insertions, 25 deletions
diff --git a/ext/bg/js/anki-note-builder.js b/ext/bg/js/anki-note-builder.js index dc1e9427..1f9c6ed2 100644 --- a/ext/bg/js/anki-note-builder.js +++ b/ext/bg/js/anki-note-builder.js @@ -42,25 +42,6 @@ class AnkiNoteBuilder { note.fields[fieldName] = await this.formatField(fieldValue, definition, mode, context, options, templates, null); } - if (!isKanji && definition.audio) { - const audioFields = []; - - for (const [fieldName, fieldValue] of modeOptionsFieldEntries) { - if (fieldValue.includes('{audio}')) { - audioFields.push(fieldName); - } - } - - if (audioFields.length > 0) { - note.audio = { - url: definition.audio.url, - filename: definition.audio.filename, - skipHash: '7e2c2f954ef6051373ba916f000168dc', // hash of audio data that should be skipped - fields: audioFields - }; - } - } - return note; } @@ -88,18 +69,31 @@ class AnkiNoteBuilder { }); } - async injectAudio(definition, fields, sources, details) { + async injectAudio(definition, fields, sources, customSourceUrl) { if (!this._containsMarker(fields, 'audio')) { return; } try { const expressions = definition.expressions; const audioSourceDefinition = Array.isArray(expressions) ? expressions[0] : definition; - const {uri} = await this._audioSystem.getDefinitionAudio(audioSourceDefinition, sources, details); const filename = this._createInjectedAudioFileName(audioSourceDefinition); - if (filename !== null) { - definition.audio = {url: uri, filename}; - } + if (filename === null) { return; } + + const {audio} = await this._audioSystem.getDefinitionAudio( + audioSourceDefinition, + sources, + { + textToSpeechVoice: null, + customSourceUrl, + binary: true, + disableCache: true + } + ); + + const data = AnkiNoteBuilder.arrayBufferToBase64(audio); + await this._anki.storeMediaFile(filename, data); + + definition.audioFileName = filename; } catch (e) { // NOP } @@ -129,6 +123,7 @@ class AnkiNoteBuilder { if (reading) { filename += `_${reading}`; } if (expression) { filename += `_${expression}`; } filename += '.mp3'; + filename = filename.replace(/\]/g, ''); return filename; } @@ -152,6 +147,10 @@ class AnkiNoteBuilder { return false; } + static arrayBufferToBase64(arrayBuffer) { + return window.btoa(String.fromCharCode(...new Uint8Array(arrayBuffer))); + } + static stringReplaceAsync(str, regex, replacer) { let match; let index = 0; diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index dd1fd8e9..8a8f00eb 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -507,7 +507,7 @@ class Backend { definition, options.anki.terms.fields, options.audio.sources, - {textToSpeechVoice: null, customSourceUrl} + customSourceUrl ); } diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index 8e1814ed..47101b49 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -108,6 +108,25 @@ const profileOptionsVersionUpdates = [ fieldTemplates += '\n\n{{#*inline "document-title"}}\n {{~context.document.title~}}\n{{/inline}}'; options.anki.fieldTemplates = fieldTemplates; } + }, + (options) => { + // Version 14 changes: + // Changed template for Anki audio. + let fieldTemplates = options.anki.fieldTemplates; + if (typeof fieldTemplates !== 'string') { return; } + + const replacement = '{{#*inline "audio"~}}\n [sound:{{definition.audioFileName}}]\n{{~/inline}}'; + let replaced = false; + fieldTemplates = fieldTemplates.replace(/\{\{#\*inline "audio"\}\}\{\{\/inline\}\}/g, () => { + replaced = true; + return replacement; + }); + + if (!replaced) { + fieldTemplates += '\n\n' + replacement; + } + + options.anki.fieldTemplates = fieldTemplates; } ]; |