Skip to content

Commit a461b6d

Browse files
committed
WIP visualize music
1 parent 9964e00 commit a461b6d

File tree

5 files changed

+47
-141
lines changed

5 files changed

+47
-141
lines changed

manifest.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"storage",
2020
"cookies",
2121
"debugger",
22+
"activeTab",
2223
"downloads",
2324
"bookmarks",
2425
"scripting",
@@ -29,7 +30,8 @@
2930
"unlimitedStorage",
3031
"declarativeNetRequest",
3132
"declarativeNetRequestFeedback",
32-
"declarativeNetRequestWithHostAccess"
33+
"declarativeNetRequestWithHostAccess",
34+
"*://*/*"
3335
],
3436
"host_permissions": ["<all_urls>"],
3537
"options_page": "./pages/options/options.html",

scripts/_test.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
77
<title>Document</title>
88

9-
<script src="_test_main.js"></script>
9+
<script src="./_test_main.js"></script>
1010
</head>
1111

1212
<body>

scripts/_test.js

Lines changed: 30 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getCurrentTabId, runScriptInTab } from "./helpers/utils.js";
1+
import { getCurrentTabId } from "./helpers/utils.js";
22

33
export default {
44
icon: "",
@@ -13,33 +13,40 @@ export default {
1313

1414
// whiteList: ["https://www.google.com/*"],
1515

16-
onClickExtension: async () => {
16+
onClickContentScript: async () => {
1717
// https://developer.chrome.com/docs/extensions/reference/api/tabCapture#preserving-system-audio
18-
try {
19-
const currentTabID = await getCurrentTabId();
20-
const newTab = await chrome.windows.create({
21-
url: "/scripts/_test.html",
22-
type: "popup",
23-
width: 800,
24-
height: 600,
25-
});
26-
27-
const streamId = await chrome.tabCapture.getMediaStreamId({
28-
consumerTabId: newTab.id,
29-
targetTabId: currentTabID,
30-
});
18+
// https://github.com/Douile/Chrome-Audio-Visualizer/tree/master
3119

32-
alert(streamId);
33-
34-
runScriptInTab({
35-
func: (streamId) => {
36-
window.setStreamId?.(streamId);
20+
try {
21+
const currentTab = await UfsGlobal.Extension.runInBackground(
22+
"utils.getCurrentTabId"
23+
);
24+
25+
const streamId = await UfsGlobal.Extension.runInBackground(
26+
"chrome.tabCapture.getMediaStreamId",
27+
[
28+
{
29+
consumerTabId: currentTab,
30+
targetTabId: currentTab,
31+
},
32+
]
33+
);
34+
35+
const stream = await navigator.mediaDevices.getUserMedia({
36+
audio: {
37+
mandatory: {
38+
chromeMediaSource: "tab",
39+
chromeMediaSourceId: streamId,
40+
},
3741
},
38-
args: [streamId],
39-
tabId: newTab.id,
4042
});
43+
44+
const output = new AudioContext();
45+
const source = output.createMediaStreamSource(stream);
46+
source.connect(output.destination);
47+
console.log(output);
4148
} catch (e) {
42-
console.error(e);
49+
alert(e);
4350
}
4451
},
4552

@@ -105,8 +112,6 @@ export default {
105112
);
106113
}
107114

108-
function applyLog(fftArray) {}
109-
110115
function smoothFFT(fftArray, smoothingFactor = 0.8) {
111116
let smoothedFFT = [];
112117
smoothedFFT[0] = fftArray[0];
@@ -182,48 +187,6 @@ export default {
182187
canvasCtx.stroke();
183188
}
184189

185-
function drawLinearScale(canvasCtx) {
186-
canvasCtx.save();
187-
canvasCtx.fillStyle = "black";
188-
189-
for (var x = 0; x < width; x += 100) {
190-
canvasCtx.beginPath();
191-
canvasCtx.moveTo(x, fftHeight);
192-
canvasCtx.lineTo(x, fftHeight + 4);
193-
canvasCtx.stroke();
194-
canvasCtx.fillText(
195-
Math.floor(((ctx.sampleRate / 2) * x) / width),
196-
x,
197-
height
198-
);
199-
}
200-
201-
canvasCtx.restore();
202-
}
203-
204-
function drawLogarithmicScale(canvasCtx) {
205-
canvasCtx.save();
206-
canvasCtx.fillStyle = "black";
207-
208-
var scale = Math.log(frequencyBins - 1) / width;
209-
var binWidthInHz = ctx.sampleRate / (frequencyBins * 2);
210-
var firstBinWidthInPx = Math.log(2) / scale;
211-
212-
for (
213-
var x = 0, freq = binWidthInHz;
214-
x < width;
215-
x += firstBinWidthInPx, freq *= 2
216-
) {
217-
canvasCtx.beginPath();
218-
canvasCtx.moveTo(x, fftHeight);
219-
canvasCtx.lineTo(x, fftHeight + 4);
220-
canvasCtx.stroke();
221-
canvasCtx.fillText(Math.floor(freq), Math.floor(x), height);
222-
}
223-
224-
canvasCtx.restore();
225-
}
226-
227190
function createAudioContext() {
228191
const audioContext = new (window.AudioContext ||
229192
window.webkitAudioContext)();
@@ -322,74 +285,3 @@ export default {
322285
};
323286

324287
// record audio when have stream: https://stackoverflow.com/a/34919194/23648002
325-
326-
const backup = () => {
327-
javascript: (function () {
328-
// Create a canvas element
329-
var canvas = document.createElement("canvas");
330-
canvas.style.cssText =
331-
"position: fixed; top: 0; left: 0; z-index: 2147483647;";
332-
updateSize();
333-
var ctx = canvas.getContext("2d");
334-
335-
function updateSize() {
336-
let w = window.innerWidth;
337-
let h = window.innerHeight;
338-
let ratio = w / h;
339-
340-
canvas.width = 600;
341-
canvas.height = canvas.width / ratio;
342-
}
343-
344-
window.addEventListener("resize", updateSize);
345-
346-
// Add the canvas element to the DOM
347-
document.body.appendChild(canvas);
348-
349-
// Variables to store the position of the canvas
350-
var offsetX, offsetY;
351-
var isDragging = false;
352-
353-
// Function to handle mouse down event
354-
canvas.addEventListener("mousedown", function (event) {
355-
isDragging = true;
356-
offsetX = event.clientX - canvas.offsetLeft;
357-
offsetY = event.clientY - canvas.offsetTop;
358-
});
359-
360-
// Function to handle mouse move event
361-
canvas.addEventListener("mousemove", function (event) {
362-
if (!isDragging) return;
363-
var x = event.clientX - offsetX;
364-
var y = event.clientY - offsetY;
365-
canvas.style.left = x + "px";
366-
canvas.style.top = y + "px";
367-
});
368-
369-
// Function to handle mouse up event
370-
canvas.addEventListener("mouseup", function () {
371-
isDragging = false;
372-
});
373-
374-
// Function to capture the visible tab and draw it onto the canvas
375-
function captureAndDraw() {
376-
console.log("captureAndDraw");
377-
// Capture the visible tab
378-
UfsGlobal.Extension.runInBackground("chrome.tabs.captureVisibleTab", [
379-
null,
380-
{ format: "png" },
381-
]).then(function (dataUrl) {
382-
var img = new Image();
383-
img.src = dataUrl;
384-
img.onload = function () {
385-
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
386-
setTimeout(() => {
387-
captureAndDraw();
388-
}, 500);
389-
};
390-
});
391-
}
392-
393-
captureAndDraw();
394-
})();
395-
};

scripts/_test_main.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1+
window.onload = () => {
2+
let streamId;
3+
let interval = setInterval(() => {
4+
streamId = localStorage.getItem("streamId");
5+
if (streamId) {
6+
clearInterval(interval);
7+
setStreamId(streamId);
8+
}
9+
}, 500);
10+
};
11+
112
function setStreamId(streamId) {
2-
alert(streamId);
313
navigator.mediaDevices
414
.getUserMedia({
515
audio: {

working_note.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@
6666
- [ ] chụp ảnh website bằng chrome.tabs.captureVisibleTab
6767

6868
- [ ] chrome.tabCapture [link](https://developer.chrome.com/docs/extensions/reference/api/tabCapture) => access MediaStream of current tab
69+
70+
- [ ] screen capture [here](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSupportedConstraints/suppressLocalAudioPlayback)

0 commit comments

Comments
 (0)