@mfcc64/ytms 16.0.0 → 18.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/script.mjs +85 -34
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mfcc64/ytms",
3
- "version": "16.0.0",
3
+ "version": "18.0.0",
4
4
  "description": "YouTube Musical Spectrum",
5
5
  "main": "script.mjs",
6
6
  "scripts": {
package/script.mjs CHANGED
@@ -34,23 +34,24 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
34
34
  speed: { def: 2, min: 1, max: 12 },
35
35
  mic: { def: 0, min: 0, max: 30 },
36
36
  mic_pan: { def: 0, min:-10, max: 10 },
37
+ interval: { def: 1, min: 1, max: 4 },
37
38
  scale_x: { def:100, min: 30, max:100 },
38
39
  scale_y: { def:100, min: 30, max:100 },
40
+ bar_scale: { def: 0, min: 0, max: 4 },
39
41
  base_note: { def: 16, min: 16, max:100 },
40
42
  semitones: { def:120, min: 36, max:120 },
41
- peak_color: { def:0xffffff, min:0, max:0xffffff },
43
+ scroll: { def: 0, min: 0, max: 1 },
42
44
  left_color: { def:0xdcb900, min:0, max:0xffffff },
43
- right_color:{ def:0x00b9dc, min:0, max:0xffffff },
44
45
  mid_color: { def:0xdcdcdc, min:0, max:0xffffff },
46
+ right_color:{ def:0x00b9dc, min:0, max:0xffffff },
45
47
  saturation: { def: 0, min: 0, max: 30 },
46
48
  hue: { def: 0, min:-18, max: 19 },
47
49
  hue_range: { def: 18, min:-36, max: 36 },
48
- interval: { def: 1, min: 1, max: 4 },
49
- bar_scale: { def: 0, min: 0, max: 4 },
50
50
  line_mode: { def: 0, min: 0, max: 4 },
51
51
  line_width: { def: 1, min: 1, max: 3 },
52
52
  line_color: { def:0xffffff, min:0, max:0xffffff },
53
- scroll: { def: 0, min: 0, max: 1 },
53
+ peak_range: { def: 72, min: 0, max:120 },
54
+ peak_color: { def:0xffffff, min:0, max:0xffffff },
54
55
  coord_color:{ def:0x000000, min:0, max:0xffffff },
55
56
  transparent:{ def: 1, min: 0, max: 1 },
56
57
  visible: { def: document.location.hostname != "www.youtube.com" ? 1 : 0,
@@ -99,7 +100,7 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
99
100
  af_links.style.color = "#FFFFFF";
100
101
  af_links.style.fontSize = "10pt";
101
102
  af_links.style.right = "8px";
102
- af_links.style.bottom = "8px";
103
+ af_links.style.bottom = "calc(var(--ytms-cqt-bottom, 0px) + 8px)";
103
104
  af_links.style.opacity = 1;
104
105
  {
105
106
  const e = (name, ...args) => {
@@ -119,14 +120,14 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
119
120
  e("div", {id: "message"},
120
121
  e("h3", "YouTube Musical Spectrum"),
121
122
  e("ul",
122
- e("li", "By default, the visualization is visible on YT Music page but hidden on YouTube page."),
123
+ e("li", "By default, the visualization is visible on YT Music, Spotify, and SoundCloud but hidden on YouTube page."),
123
124
  e("li", "Press ", e("b", "Ctrl+Alt+G"), " as a shortcut to show/hide visualization. This is equivalent to check/uncheck ", e("b", "Visible"), " setting."),
124
125
  e("li", "Click the ", e("img", {alt: "YTMS"}, {src: icon_16}), " icon at the top left corner to open/close settings."),
125
126
  e("li", "Press ", e("b", "Ctrl+Alt+H"), " to open/close settings and show/hide the ", e("img", {alt: "YTMS"}, {src: icon_16}), " icon."),
126
127
  e("li", "If you want to change the axis, click it."),
127
128
  e("li", "If you want to make your change persistent, click ", e("b", "Set as Default Settings"), " button."),
128
129
  e("li", e("b", "New Features:"), " Custom color, custom range," +
129
- " peak color, bar scale, line visualizer, hue rotation, more color presets, horizontal scroll, coordinate line."),
130
+ " peak color, bar scale, line visualizer, hue rotation, more color presets, horizontal scroll, coordinate line, peak range."),
130
131
  e("li", e("a", {href: "https://github.com/mfcc64/youtube-musical-spectrum#settings"}, {target: "_blank"}, "Read more..."))
131
132
  ),
132
133
  e("p",
@@ -138,7 +139,6 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
138
139
  e("img", {alt: "YTMS"}, {src: icon_16}, {style: "curson: pointer;"}, {id: "open_message"}),
139
140
  " Support me on ",
140
141
  e("a", {href: "https://www.youtube.com/@mfcc64"}, {target: "_blank"}, "Youtube"), " ",
141
- e("a", {href: "https://www.patreon.com/mfcc64"}, {target: "_blank"}, "Patreon"), " ",
142
142
  e("a", {href: "https://github.com/mfcc64"}, {target: "_blank"}, "GitHub"), " ",
143
143
  e("a", {href: "https://paypal.me/mfcc64"}, {target: "_blank"}, "PayPal"), " ",
144
144
  e("a", {href: "https://saweria.co/mfcc64"}, {target: "_blank"}, "Saweria")
@@ -157,7 +157,7 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
157
157
  af_links.style.display = !af_links_timeout || (child_menu.visible?.checked ?? true) ? "block" : "none";
158
158
  }
159
159
 
160
- const message_version = 12;
160
+ const message_version = 14;
161
161
  af_links.shadowRoot.getElementById("message").style.display = get_opt("message_version") == message_version ? "none" : "block";
162
162
  af_links.shadowRoot.getElementById("close_message").addEventListener("click", function() {
163
163
  set_opt("message_version", message_version);
@@ -167,18 +167,36 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
167
167
  af_links.shadowRoot.getElementById("message").style.display = "block";
168
168
  });
169
169
 
170
+ const media_symbol = Symbol("media_symbol");
171
+ let svideos = [];
172
+ if (document.location.hostname == "soundcloud.com") {
173
+ await new Promise((res, rej) => {
174
+ const old = AudioContext.prototype.createMediaElementSource;
175
+ AudioContext.prototype.createMediaElementSource = function(media) {
176
+ const retval = old.call(this, media);
177
+ ShowCQTElement.global_audio_context = this;
178
+ svideos.push(media);
179
+ media[media_symbol] = retval;
180
+ res();
181
+ return retval;
182
+ };
183
+ });
184
+ }
185
+
170
186
  const cqt = new ShowCQTElement();
171
187
  set_fixed_style(cqt, 9999999);
172
188
  let stop_count = 0;
173
189
  const videos = document.getElementsByTagName("video");
174
- let svideos = [];
190
+ const require_refresh = ["open.spotify.com", "soundcloud.com"].indexOf(document.location.hostname) < 0;
175
191
  cqt.render_callback = function() {
176
- let need_refresh = (videos.length != svideos.length);
177
- for (let k = 0; k < videos.length && !need_refresh; k++)
178
- need_refresh = (videos[k] != svideos[k]);
179
- if (need_refresh) {
180
- this.dataset.inputs = "video";
181
- svideos = Array.from(videos);
192
+ if (require_refresh) {
193
+ let need_refresh = (videos.length != svideos.length);
194
+ for (let k = 0; k < videos.length && !need_refresh; k++)
195
+ need_refresh = (videos[k] != svideos[k]);
196
+ if (need_refresh) {
197
+ this.dataset.inputs = "video";
198
+ svideos = Array.from(videos);
199
+ }
182
200
  }
183
201
 
184
202
  let state = 0;
@@ -197,7 +215,6 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
197
215
  #player { margin-top: 0 !important; }`;
198
216
  document.head.appendChild(style);
199
217
  af_links.style.zIndex = 11;
200
- af_links.style.bottom = "calc(var(--ytmusic-player-bar-height, 0) + 8px)";
201
218
  cqt.style.zIndex = 10;
202
219
 
203
220
  function update_cqt_bottom() {
@@ -214,8 +231,39 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
214
231
  update_cqt_bottom();
215
232
  }
216
233
 
217
- if (document.location.hostname == "music.youtube.com")
218
- ytmusic_layout();
234
+ function spotify_layout() {
235
+ cqt.style.zIndex = 4;
236
+ af_links.style.zIndex = 5;
237
+ document.body.style.setProperty("--ytms-cqt-bottom", "88px"); // FIXME
238
+ const old_play = HTMLMediaElement.prototype.play;
239
+ HTMLMediaElement.prototype.play = async function() {
240
+ const ret = old_play.call(this);
241
+ if (this.isConnected || this instanceof HTMLAudioElement)
242
+ return ret;
243
+ for (const video of svideos)
244
+ if (this == video)
245
+ return ret;
246
+
247
+ svideos.push(this);
248
+ const source = cqt.audio_context.createMediaElementSource(this);
249
+ source.connect(cqt.audio_input);
250
+ source.connect(cqt.audio_context.destination);
251
+ return ret;
252
+ };
253
+ }
254
+
255
+ function soundcloud_layout() {
256
+ cqt.style.zIndex = 1000;
257
+ af_links.style.zIndex = 1001;
258
+ svideos[0][media_symbol].connect(cqt.audio_input);
259
+ document.body.style.setProperty("--ytms-cqt-bottom", "var(--play-controls-height, 0px)");
260
+ }
261
+
262
+ switch (document.location.hostname) {
263
+ case "music.youtube.com": ytmusic_layout(); break;
264
+ case "open.spotify.com": spotify_layout(); break;
265
+ case "soundcloud.com": soundcloud_layout(); break;
266
+ }
219
267
 
220
268
  const coord_line_h = document.createElement("div");
221
269
  const coord_line_v = document.createElement("div");
@@ -304,6 +352,7 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
304
352
  menu_div.style.visibility = "hidden";
305
353
  menu_div.style.cursor = "default";
306
354
  menu_table.style.width = "860px";
355
+ menu_div.style.display = "block";
307
356
 
308
357
  var current_tr = null;
309
358
  var current_tr_count = 0;
@@ -566,19 +615,18 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
566
615
  child.onchange();
567
616
  }
568
617
 
569
- create_child_color_menu("Peak Color", "peak_color", child => color_int[3] = color2number(child.value));
618
+ create_child_select_menu("Scroll", "scroll", [ "Vertical", "Horizontal" ], update_cqt_layout);
570
619
 
571
620
  function detect_peak(color) {
572
621
  if (color_int[3] == 0xffffff)
573
622
  return;
574
623
 
575
- for (let k = 4; k < color.length - 4; k += 4) {
624
+ const range = child_menu.peak_range.value / 120 * color.length;
625
+ for (let k = 4; k + 2 < range && k < color.length - 4; k += 4) {
576
626
  if (color[k+3] <= color[k-1] || color[k+3] < color[k+7])
577
627
  continue;
578
628
 
579
- const alpha = (1 - (k+2) / color.length) ** 2 - 0.16;
580
- if (alpha <= 0)
581
- break;
629
+ const alpha = Math.cos(0.5 * Math.PI * (k+2) / range) ** 2;
582
630
 
583
631
  for (let m = 0; m < 3; m++)
584
632
  color[k+m] = Math.min(color[k+m], 1) * (1 - alpha + peak_color[m] * alpha);
@@ -746,14 +794,8 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
746
794
  tr.appendChild(td);
747
795
  }
748
796
 
749
- create_child_select_menu("Scroll", "scroll", [ "Vertical", "Horizontal" ], update_cqt_layout);
750
- create_child_checkbox_menu("Transparent", "transparent", (child) => cqt.dataset.opacity = child.checked ? "transparent" : "opaque");
751
- create_child_checkbox_menu("Visible", "visible", (child) => {
752
- cqt.style.display = child.checked ? "block" : "none";
753
- if (!child.checked)
754
- coord_line_h.style.display = coord_line_v.style.display = "none";
755
- update_af_links();
756
- });
797
+ create_child_range_menu("Peak Range", "peak_range");
798
+ create_child_color_menu("Peak Color", "peak_color", child => color_int[3] = color2number(child.value));
757
799
 
758
800
  function cqt_coord_line_leave(ev) {
759
801
  coord_line_h.style.display = coord_line_v.style.display = "none";
@@ -777,6 +819,14 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
777
819
  }
778
820
  });
779
821
 
822
+ create_child_checkbox_menu("Transparent", "transparent", (child) => cqt.dataset.opacity = child.checked ? "transparent" : "opaque");
823
+ create_child_checkbox_menu("Visible", "visible", (child) => {
824
+ cqt.style.display = child.checked ? "block" : "none";
825
+ if (!child.checked)
826
+ coord_line_h.style.display = coord_line_v.style.display = "none";
827
+ update_af_links();
828
+ });
829
+
780
830
  function create_child_select_presets() {
781
831
  const presets = [
782
832
  { title: "-- Choose Preset --" },
@@ -907,7 +957,8 @@ import {ShowCQTElement} from "../../showcqt-element@2/showcqt-element.mjs";
907
957
  setTimeout(function(){ child.value = "Reset Default Settings"; }, 300);
908
958
  });
909
959
 
910
- menu_div.appendChild(menu_table);
960
+ menu_div.attachShadow({mode: "open"});
961
+ menu_div.shadowRoot.appendChild(menu_table);
911
962
  menu.onclick = function() {
912
963
  menu_is_hidden = !menu_is_hidden;
913
964
  if (menu_is_hidden)