Skip to content

Commit d194336

Browse files
author
hoang.tran12
committed
audio visiualize - WIP
1 parent 6b708b6 commit d194336

File tree

5 files changed

+195
-7
lines changed

5 files changed

+195
-7
lines changed

scripts/_test.js

Lines changed: 185 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,189 @@ export default {
99
vi: "",
1010
},
1111

12-
onDocumentEnd: async () => {},
12+
// whiteList: ["https://www.google.com/*"],
13+
14+
onClick: async () => {
15+
//https://www.youtube.com/watch?v=uk96O7N1Yo0
16+
javascript: (function () {
17+
function draggable(ele) {
18+
// Variables to store the position of the canvas
19+
var offsetX, offsetY;
20+
var isDragging = false;
21+
22+
// Function to handle mouse down event
23+
ele.addEventListener("mousedown", function (event) {
24+
isDragging = true;
25+
offsetX = event.clientX - ele.offsetLeft;
26+
offsetY = event.clientY - ele.offsetTop;
27+
});
28+
29+
// Function to handle mouse move event
30+
ele.addEventListener("mousemove", function (event) {
31+
if (!isDragging) return;
32+
var x = event.clientX - offsetX;
33+
var y = event.clientY - offsetY;
34+
ele.style.left = x + "px";
35+
ele.style.top = y + "px";
36+
});
37+
38+
// Function to handle mouse up event
39+
ele.addEventListener("mouseup", function () {
40+
isDragging = false;
41+
});
42+
}
43+
44+
function map(x, in_min, in_max, out_min, out_max) {
45+
return (
46+
((x - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min
47+
);
48+
}
49+
50+
function createAudioContext() {
51+
const audioContext = new (window.AudioContext ||
52+
window.webkitAudioContext)();
53+
const analyser = audioContext.createAnalyser();
54+
analyser.fftSize = 2048;
55+
const bufferLength = analyser.frequencyBinCount;
56+
const dataArray = new Uint8Array(bufferLength);
57+
58+
const canvas = document.createElement("canvas");
59+
canvas.style.cssText =
60+
"position: fixed; top: 0; left: 0; width: 600px; height: 400px; z-index: 2147483647;";
61+
document.body.appendChild(canvas);
62+
const ctx = canvas.getContext("2d");
63+
draggable(canvas);
64+
65+
function draw() {
66+
analyser.getByteFrequencyData(dataArray);
67+
ctx.clearRect(0, 0, canvas.width, canvas.height);
68+
const barWidth = ~~(bufferLength / canvas.width);
69+
for (let x = 0; x < canvas.width; x++) {
70+
let i = x * barWidth;
71+
let item = dataArray[i];
72+
const barHeight = map(item, 0, 255, 0, canvas.height);
73+
ctx.fillStyle = `rgba(255, 255, 255, ${map(item, 0, 255, 0, 1)})`;
74+
ctx.fillRect(x, canvas.height - barHeight, 1, barHeight);
75+
}
76+
requestAnimationFrame(draw);
77+
}
78+
79+
draw();
80+
81+
function handleVideoAudio(videoElement) {
82+
const source = audioContext.createMediaElementSource(videoElement);
83+
source.connect(analyser);
84+
analyser.connect(audioContext.destination);
85+
}
86+
87+
return { handleVideoAudio, canvas };
88+
}
89+
90+
function startAudioAnalysis() {
91+
if (!window.AudioContext) {
92+
alert("Your browser doesn't support Web Audio API");
93+
return;
94+
}
95+
96+
const videoElements = document.querySelectorAll("video");
97+
const contexts = [];
98+
99+
videoElements.forEach((videoElement) => {
100+
const { handleVideoAudio, canvas } = createAudioContext();
101+
handleVideoAudio(videoElement);
102+
contexts.push({ canvas, videoElement });
103+
});
104+
105+
// Keep checking for new videos on the page
106+
setInterval(() => {
107+
const newVideos = document.querySelectorAll("video");
108+
newVideos.forEach((videoElement) => {
109+
const exists = contexts.some(
110+
(context) => context.videoElement === videoElement
111+
);
112+
if (!exists) {
113+
const { handleVideoAudio, canvas } = createAudioContext();
114+
handleVideoAudio(videoElement);
115+
contexts.push({ canvas, videoElement });
116+
}
117+
});
118+
}, 2000);
119+
}
120+
121+
startAudioAnalysis();
122+
})();
123+
},
124+
};
125+
126+
// record audio when have stream: https://stackoverflow.com/a/34919194/23648002
127+
128+
const backup = () => {
129+
javascript: (function () {
130+
// Create a canvas element
131+
var canvas = document.createElement("canvas");
132+
canvas.style.cssText =
133+
"position: fixed; top: 0; left: 0; z-index: 2147483647;";
134+
updateSize();
135+
var ctx = canvas.getContext("2d");
136+
137+
function updateSize() {
138+
let w = window.innerWidth;
139+
let h = window.innerHeight;
140+
let ratio = w / h;
141+
142+
canvas.width = 600;
143+
canvas.height = canvas.width / ratio;
144+
}
145+
146+
window.addEventListener("resize", updateSize);
147+
148+
// Add the canvas element to the DOM
149+
document.body.appendChild(canvas);
150+
151+
// Variables to store the position of the canvas
152+
var offsetX, offsetY;
153+
var isDragging = false;
154+
155+
// Function to handle mouse down event
156+
canvas.addEventListener("mousedown", function (event) {
157+
isDragging = true;
158+
offsetX = event.clientX - canvas.offsetLeft;
159+
offsetY = event.clientY - canvas.offsetTop;
160+
});
161+
162+
// Function to handle mouse move event
163+
canvas.addEventListener("mousemove", function (event) {
164+
if (!isDragging) return;
165+
var x = event.clientX - offsetX;
166+
var y = event.clientY - offsetY;
167+
canvas.style.left = x + "px";
168+
canvas.style.top = y + "px";
169+
});
170+
171+
// Function to handle mouse up event
172+
canvas.addEventListener("mouseup", function () {
173+
isDragging = false;
174+
});
175+
176+
// Function to capture the visible tab and draw it onto the canvas
177+
function captureAndDraw() {
178+
console.log("captureAndDraw");
179+
// Capture the visible tab
180+
UfsGlobal.Extension.runInBackground("chrome.tabs.captureVisibleTab", [
181+
null,
182+
{ format: "png" },
183+
]).then(function (dataUrl) {
184+
var img = new Image();
185+
img.src = dataUrl;
186+
img.onload = function () {
187+
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
188+
setTimeout(() => {
189+
captureAndDraw();
190+
}, 500);
191+
};
192+
});
193+
}
194+
195+
captureAndDraw();
196+
})();
13197
};

scripts/background-scripts/background-script.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ function main() {
122122
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
123123
console.log("request", request);
124124
try {
125-
if (request.action === "runInBackground") {
125+
if (request.action === "ufs-runInBackground") {
126126
const { params = [], fnPath = "" } = request.data || {};
127127
let fn = fnPath?.startsWith("chrome") ? chrome : GLOBAL;
128128
fnPath.split(".").forEach((part) => {

scripts/content-scripts/content_script.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ async function runScript(scriptId, event) {
4949
let { event, data, uuid } = e?.detail || {};
5050
try {
5151
switch (event) {
52-
case "runInContentScript":
52+
case "ufs-runInContentScript":
5353
const { params = [], fnPath = "" } = data || {};
5454
let fn = fnPath?.startsWith?.("chrome") ? chrome : window;
5555
fnPath.split(".").forEach((part) => {
@@ -58,9 +58,9 @@ async function runScript(scriptId, event) {
5858
console.log("runInContentScript", fnPath, params);
5959
sendToPageScript(event, uuid, await fn?.(...params));
6060
break;
61-
case "runInBackground":
61+
case "ufs-runInBackground":
6262
chrome.runtime.sendMessage(
63-
{ action: "runInBackground", data },
63+
{ action: "ufs-runInBackground", data },
6464
function (response) {
6565
console.log("Response from background script:", response);
6666
sendToPageScript(event, uuid, response);

scripts/content-scripts/ufs_global.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ UfsGlobal.Extension = {
2222
},
2323
// WARNING: can only transfer serializable data
2424
runInContentScript(fnPath, params) {
25-
return UfsGlobal.Extension.sendToContentScript("runInContentScript", {
25+
return UfsGlobal.Extension.sendToContentScript("ufs-runInContentScript", {
2626
fnPath,
2727
params,
2828
});
2929
},
3030
runInBackground(fnPath, params) {
31-
return UfsGlobal.Extension.sendToContentScript("runInBackground", {
31+
return UfsGlobal.Extension.sendToContentScript("ufs-runInBackground", {
3232
fnPath,
3333
params,
3434
});

working_note.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,7 @@
6262
- [ ] webSocket => do something great?
6363

6464
- [ ] Thêm change logs cho từng scripts
65+
66+
- [ ] chụp ảnh website bằng chrome.tabs.captureVisibleTab
67+
68+
- [ ] chrome.tabCapture [link](https://developer.chrome.com/docs/extensions/reference/api/tabCapture) => access MediaStream of current tab

0 commit comments

Comments
 (0)