Skip to content
This repository has been archived by the owner on Jan 16, 2023. It is now read-only.

Commit

Permalink
fix text speetch in v3
Browse files Browse the repository at this point in the history
  • Loading branch information
theowenyoung committed Nov 8, 2022
1 parent a7beb30 commit 4a34f52
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 88 deletions.
70 changes: 16 additions & 54 deletions src/background/textToSpeech.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@ const textToSpeech = (function () {
*/
async makeRequest(text, targetLanguage) {
return await new Promise(async (resolve, reject) => {




const response = await fetch(this.baseURL + this.cbGetExtraParameters(text, targetLanguage), {
method: this.xhrMethod,
});
Expand All @@ -111,14 +107,17 @@ const textToSpeech = (function () {
const requests = this.getRequests(fullText);
const promises = [];

const resultObj = {};

for (const requestText of requests) {
const audioKey = [targetLanguage, requestText].join(", ");
if (!this.audios.get(audioKey)) {
promises.push(
this.makeRequest(requestText, targetLanguage)
.then(
/** @type {string} */ (response) => {
this.audios.set(audioKey, new Audio(response));
resultObj[audioKey] = response;
this.audios.set(audioKey,response);
return response;
}
)
Expand All @@ -127,53 +126,14 @@ const textToSpeech = (function () {
return null;
})
);
}else{
resultObj[audioKey] = this.audios.get(audioKey);
}
}

await Promise.all(promises);
return await this.play(
requests.map((text) =>
this.audios.get([targetLanguage, text].join(", "))
)
);
return resultObj;
}

/**
* Play the audio or all the audio in the array.
* @param {HTMLAudioElement | HTMLAudioElement[]} audios
*/
async play(audios) {
this.stopAll();
return await new Promise((resolve) => {
try {
if (audios instanceof Array) {
const playAll = (/** @type {number} */ currentIndex) => {
this.stopAll();
const audio = audios[currentIndex];
if (audio) {
audio.playbackRate = this.audioSpeed;
audio.play();
audio.onended = () => {
playAll(currentIndex + 1);
};
} else {
resolve();
}
};
playAll(0);
} else if (audios instanceof HTMLAudioElement) {
audios.playbackRate = this.audioSpeed;
audios.play();
audios.onended = () => {
resolve();
};
}
} catch (e) {
console.error(e);
resolve();
}
});
}

/**
* Sets the audio speed
Expand Down Expand Up @@ -211,18 +171,20 @@ const textToSpeech = (function () {

// Listen for messages coming from contentScript or other scripts.
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === "textToSpeech") {
if (request.action === "getAudioURLs") {
googleService
.textToSpeech(request.text, request.targetLanguage)
.finally(() => {
sendResponse();
.then((response) => {
sendResponse(response);
}).catch(e=>{
console.warn('fetch audios error',e)
sendResponse({})

});


return true;
} else if (request.action === "stopAudio") {
googleService.stopAll();
}
});
} });

// Listen for changes to the audio speed setting and apply it immediately.
twpConfig.onReady(async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/chrome_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
"run_at": "document_end",
"all_frames": true,
"match_about_blank": true,
"js": ["/lib/i18n.js", "/contentScript/showOriginal.js", "/contentScript/enhance.js", "/contentScript/pageTranslator.js", "/contentScript/translateSelected.js", "/contentScript/showTranslated.js"]
"js": ["/lib/i18n.js", "/contentScript/showOriginal.js", "/contentScript/enhance.js", "/contentScript/pageTranslator.js","/contentScript/play.js", "/contentScript/translateSelected.js", "/contentScript/showTranslated.js"]
},
{
"matches": ["<all_urls>"],
Expand Down
103 changes: 103 additions & 0 deletions src/contentScript/play.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
class AudioPlayer {
/**
* Defines the Service class for the text-to-speech service.
*/
constructor() {
this.audios = new Map();
this.audioSpeed = 1.0;
}

/**
* Transform text into audio and play then.
* @param {string} fullText
* @param {string} targetLanguage
* @returns {Promise<void>} Promise\<void\>
*/
async textToSpeech(fullText, targetLanguage) {
const response = await getAudioURLs(fullText, targetLanguage);
const keys = Object.keys(response);
for (const key of keys) {
this.audios.set(key, new Audio(response[key]));
}

return await this.play(
keys.map((key) =>
this.audios.get(key)
)
);
}

/**
* Play the audio or all the audio in the array.
* @param {HTMLAudioElement | HTMLAudioElement[]} audios
*/
async play(audios) {
this.stopAll();
return await new Promise((resolve) => {
try {
if (audios instanceof Array) {
const playAll = (/** @type {number} */ currentIndex) => {
this.stopAll();
const audio = audios[currentIndex];
if (audio) {
audio.playbackRate = this.audioSpeed;
audio.play();
audio.onended = () => {
playAll(currentIndex + 1);
};
} else {
resolve();
}
};
playAll(0);
} else if (audios instanceof HTMLAudioElement) {
audios.playbackRate = this.audioSpeed;
audios.play();
audios.onended = () => {
resolve();
};
}
} catch (e) {
console.error(e);
resolve();
}
});
}

/**
* Sets the audio speed
* @param {number} speed
*/
setAudioSpeed(speed) {
this.audioSpeed = speed;
this.audios.forEach((audio) => {
audio.playbackRate = this.audioSpeed;
});
}

/**
* Pause all audio and reset audio time to start
*/
stopAll() {
this.audios.forEach((audio) => {
audio.pause();
audio.currentTime = 0;
});
}
}

const audioPlayer = new AudioPlayer();


function getAudioURLs(text, targetLanguage) {

return new Promise((resolve,reject) => {
chrome.runtime.sendMessage({
action: "getAudioURLs",
text,
targetLanguage
}, (response) => {
resolve(response)
})
})
}
15 changes: 5 additions & 10 deletions src/contentScript/showTranslated.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,22 +116,17 @@ Promise.all([twpConfig.onReady(), getTabHostName()])

function playAudio(text, targetLanguage, cbOnEnded=() => {}) {
isPlayingAudio = true
chrome.runtime.sendMessage({
action: "textToSpeech",
text,
targetLanguage
}, () => {
isPlayingAudio = false
cbOnEnded()

audioPlayer.textToSpeech(text, targetLanguage).then(()=>{
isPlayingAudio = false
cbOnEnded()
})
}

function stopAudio() {
if (!isPlayingAudio) return;
isPlayingAudio = false
chrome.runtime.sendMessage({
action: "stopAudio"
})
audioPlayer.stopAll()
}

window.addEventListener("beforeunload", e => {
Expand Down
19 changes: 8 additions & 11 deletions src/contentScript/translateSelected.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,19 @@ Promise.all([ twpConfig.onReady(), getTabHostName() ]).then(function (_) {

function playAudio(text, targetLanguage, cbOnEnded=() => {}) {
isPlayingAudio = true
chrome.runtime.sendMessage({
action: "textToSpeech",
text,
targetLanguage
}, () => {
isPlayingAudio = false
cbOnEnded()
})
audioPlayer.textToSpeech(text, targetLanguage).then(()=>{
isPlayingAudio = false
cbOnEnded()
})
}

function stopAudio() {
if (!isPlayingAudio) return;
isPlayingAudio = false
chrome.runtime.sendMessage({
action: "stopAudio"
})
// chrome.runtime.sendMessage({
// action: "stopAudio"
// })
audioPlayer.stopAll()
}

function dragElement(elmnt, elmnt2) {
Expand Down
2 changes: 1 addition & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
"run_at": "document_end",
"all_frames": true,
"match_about_blank": true,
"js": ["/lib/i18n.js", "/contentScript/showOriginal.js", "/contentScript/enhance.js", "/contentScript/pageTranslator.js", "/contentScript/translateSelected.js", "/contentScript/showTranslated.js"]
"js": ["/lib/i18n.js", "/contentScript/showOriginal.js", "/contentScript/enhance.js", "/contentScript/pageTranslator.js", "/contentScript/play.js","/contentScript/translateSelected.js", "/contentScript/showTranslated.js"]
},
{
"matches": ["<all_urls>"],
Expand Down
1 change: 1 addition & 0 deletions src/popup/popup-translate-text.html
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
<script src="/lib/languages.js"></script>
<script src="/lib/config.js"></script>
<script src="/lib/i18n.js"></script>
<script src="/contentScript/play.js"></script>
<script src="popup-translate-text.js"></script>
</body>

Expand Down
27 changes: 16 additions & 11 deletions src/popup/popup-translate-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,18 @@ twpConfig.onReady(function () {

function playAudio(text, targetLanguage, cbOnEnded=() => {}) {
isPlayingAudio = true
chrome.runtime.sendMessage({
action: "textToSpeech",
text,
targetLanguage
}, () => {
isPlayingAudio = false
cbOnEnded()
})
audioPlayer.textToSpeech(text, targetLanguage).then(()=>{
isPlayingAudio = false
cbOnEnded()
})
// chrome.runtime.sendMessage({
// action: "textToSpeech",
// text,
// targetLanguage
// }, () => {
// isPlayingAudio = false
// cbOnEnded()
// })
}

function stopAudio() {
Expand All @@ -93,9 +97,10 @@ twpConfig.onReady(function () {

function stopAudio() {
if (isPlayingAudio) {
chrome.runtime.sendMessage({
action: "stopAudio"
})
audioPlayer.stopAll()
// chrome.runtime.sendMessage({
// action: "stopAudio"
// })
}
isPlayingAudio = false
}
Expand Down

0 comments on commit 4a34f52

Please sign in to comment.