-
Notifications
You must be signed in to change notification settings - Fork 0
/
content_script.js
117 lines (101 loc) · 3.35 KB
/
content_script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
let isDubbingActive = false;
let lastSubtitle = null;
let lastSubtitleTime = null;
let previousSubtitleTime = null;
let defaultSpeechRate = 1.0;
let currentTimeVideo = 0;
let currentRateVideo = 0;
let selectedVoice = null;
let selectedLanguage = "pt-BR";
let subtitles;
let nextSubtitleIndex = 0;
function stopDubbing() {
isDubbingActive = false;
}
function startDubbing() {
isDubbingActive = true;
}
function calculateSpeechRate(duration, text, videoRate) {
const minSpeechRate = 0.5;
const maxSpeechRate = 10.0;
const k = 56.185 * (videoRate ?? 1);
const c = 27.215;
let speechRate;
if (duration && text?.length) {
const t = ((duration / 3) / text?.length)
if (t < c) {
speechRate = 10
} else {
speechRate = k / (t - c);
}
} else {
speechRate = 10
}
return Math.min(Math.max(speechRate, minSpeechRate), maxSpeechRate);
}
function dub(text, voiceRate) {
if (isDubbingActive) {
const utterance = new SpeechSynthesisUtterance(text);
if (selectedVoice) {
utterance.voice = selectedVoice;
}
utterance.lang = selectedLanguage;
utterance.rate = voiceRate;
speechSynthesis.speak(utterance);
}
}
function loadOptions(selectedVoiceLocal) {
if (selectedVoiceLocal) {
const voices = speechSynthesis.getVoices();
const findSelectedVoice = voices.find(voice => voice.voiceURI === selectedVoiceLocal);
if (findSelectedVoice) {
selectedVoice = findSelectedVoice;
}
}
}
function processVideoSubtitles(videoPlayer) {
currentTimeVideo = videoPlayer.currentTime * 1000;
currentRateVideo = videoPlayer?.playbackRate || 1
for (let i = nextSubtitleIndex; i < subtitles?.events?.length; i++) {
const event = subtitles.events[i];
if (event.segs && currentRateVideo < 3) {
const text = event.segs.map(seg => seg.utf8).join(' ');
const subtitleStartTime = event.tStartMs;
const subtitleDuration = event.dDurationMs;
const totalStartTime = subtitleStartTime;
const totalEndTime = subtitleStartTime + subtitleDuration;
if (currentTimeVideo >= totalStartTime && currentTimeVideo <= totalEndTime && text.trim().length) {
const startDelayTime = totalStartTime - currentTimeVideo;
const rate = calculateSpeechRate(subtitleDuration, text, currentRateVideo);
setTimeout(() => {
dub(text, rate);
}, startDelayTime);
nextSubtitleIndex = i + 1;
break;
}
}
}
}
function initVideoPlayer() {
const videoPlayer = document.querySelector("video.video-stream.html5-main-video");
if (videoPlayer) {
videoPlayer.addEventListener("timeupdate", () => processVideoSubtitles(videoPlayer));
}
}
window.onload = function () {
setTimeout(() => {
initVideoPlayer();
}, 1000);
};
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === "startDubbing") {
subtitles = message.content;
nextSubtitleIndex = 0;
}
if (message.type === 'updateVoice') {
loadOptions(message.content)
}
if (message.type === 'dubState') {
message.content ? startDubbing() : stopDubbing();
}
});