您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A simple audio visualizer for Youtube.
- // ==UserScript==
- // @name Audio Visualizer For Youtube
- // @namespace https://github.com/MrAnyone/YouTube-Audio-Visualizer
- // @version 0.6 BETA
- // @description A simple audio visualizer for Youtube.
- // @author MrAnyone
- // @match https://www.youtube.com/watch?v=*
- // @require http://code.jquery.com/jquery-latest.js
- // @require https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.10/pixi.min.js
- // @grant Thank you very much for the inspiration! https://www.youtube.com/watch?v=okMfwg15lz0
- // ==/UserScript==
- /* jshint -W097 */
- 'use strict';
- /****************
- SETUP VARS
- ****************/
- //Do debug
- var doDebug = true;
- //Used to remove some "dead bars"
- var excludeRatio = 33;
- //Version
- var version = "0.6 BETA";
- /**********************
- VISUALIZER VARS
- **********************/
- //Audio handler variables
- var audioCtx = null;
- var analyser = null;
- var dataArray = null;
- var source = null;
- var $video = null;
- //Pixi vars
- var container = null;
- var renderer = null;
- var g = null;
- //Visualization variables
- var barWidth = null;
- var sizeControl = null;
- var i = null;
- var playerAPIDiv = null;
- var widthConstant = null;
- var smoothInput = null;
- var smoothPelmt = null;
- var smoothCountText = null;
- /****************
- FUNCTIONS
- ****************/
- $(document).ready(function() {
- init();
- setElementSource("video");
- setupView();
- requestAnimationFrame(animate);
- });
- //Init function
- function init() {
- try {
- //Get audio apis from different browsers
- if (!(navigator.getUserMedia)) {
- navigator.getUserMedia = (navigator.getUserMedia ||
- navigator.webkitGetUserMedia ||
- navigator.mozGetUserMedia ||
- navigator.msGetUserMedia);
- }
- if (!(window.AudioContext)) {
- window.AudioContext = window.AudioContext || window.webkitAudioContext;
- }
- //Create the audio context
- if (!(audioCtx)) {
- audioCtx = new AudioContext();
- }
- //Setup the analyser node
- if (!(analyser)) {
- analyser = audioCtx.createAnalyser();
- analyser.fftSize = 256;
- analyser.minDecibels = -80;
- analyser.maxDecibels = 0;
- analyser.smoothingTimeConstant = 0.8;
- }
- //Generate the dataArray
- if (!(dataArray)) {
- dataArray = new Uint8Array(analyser.fftSize / 2);
- }
- //Simple function to map values from one range to another
- Number.prototype.map = function(in_min, in_max, out_min, out_max) {
- return (this - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
- };
- debug("Init successfull!", "INFO");
- } catch (e) {
- alert("Error! Probably your browser doesn't support the Web Audio API!");
- debug(e, "ERROR");
- }
- }
- //Try to find the video DOM with given ID and create an audio source
- function setElementSource(id) {
- //Try to find the video
- $video = $(id);
- if ($video) {
- //Create audio element
- source = audioCtx.createMediaElementSource($video[0]);
- //Route source to analyser & speakers
- source.connect(analyser);
- source.connect(audioCtx.destination);
- debug("setElementSource successfull!", "INFO");
- } else {
- debug("The video element was not found!", "WARNING");
- }
- }
- //Setup the visualizer
- function setupView() {
- try {
- //A div to get the video size
- playerAPIDiv = $("#player-api");
- //Generate "PIXI stuff"
- if (!(container || renderer || g)) {
- //The container
- container = new PIXI.Container(0x66FF99);
- //The renderer
- renderer = PIXI.autoDetectRenderer(playerAPIDiv.width(), playerAPIDiv.height());
- //Setup the ytav div
- $("#player").prepend($("<div>", {
- id: "ytav"
- }));
- //Add the view (canvas) of the renderer
- $("#ytav").prepend(renderer.view);
- //Setup ytav-controls
- $("#ytav").append($("<div>", {
- id: "ytav-controls"
- }).css({
- float: "right",
- width: ($("#ytav").width() - renderer.width) * 0.9 + "px",
- margin: "0px"
- }));
- $("#ytav-controls").append($("<div>", {
- id: "ytav-title"
- }).css({
- width: "70%",
- margin: "0 0 5% 0"
- }));
- $("#ytav-title").append($("<h1>").text("Youtube Audio Visualizer").css("color", "black"));
- $("#ytav-title").append($("<p>").text("v. " + version + " By MrAnyone").css({
- color: "red",
- float: "right",
- fontSize: "0.8em"
- }));
- $("#ytav-controls").append($("<div>", {
- id: "ytav-controls-input"
- }));
- smoothPelmt = $("<p>").css({
- color: "black"
- }).text("Smoothness: ");
- smoothCountText = $("<b>", {
- id: "smoothCount"
- }).text("80");
- smoothPelmt.append(smoothCountText);
- $("#ytav-controls-input").append(smoothPelmt);
- smoothInput = $("<input>", {
- type: "range",
- min: "0",
- max: "99",
- value: "80"
- }).css({
- display: "block"
- });
- $("#ytav-controls-input > p").append(smoothInput);
- //Generate PIXI graphics for bar draw
- g = new PIXI.Graphics();
- }
- //A constant to calcule the bar width responsively
- widthConstant = (100 / (dataArray.length - excludeRatio));
- debug("Setup view successfull!", "INFO");
- } catch (e) {
- debug("Failed to setup the view!\n" + e, "ERROR");
- }
- }
- //The animate loop
- function animate() {
- //Animate loop
- requestAnimationFrame(animate);
- //Get the audio data
- passByteFrequencyData(dataArray);
- //Removes the "older bars" from graphics
- g.clear();
- //Starts drawing with a color & oppacity
- g.beginFill(0x5CE6FF, 1);
- //Resize the view when necessary
- if (playerAPIDiv.width() != renderer.width || playerAPIDiv.height() != renderer.height) {
- renderer.resize(playerAPIDiv.width(), playerAPIDiv.height());
- $("#ytav-controls").css("width", ($("#ytav").width() - renderer.width) * 0.9);
- }
- //Update the smoothness when necessary
- if (smoothInput.val() / 100 != analyser.smoothingTimeConstant) {
- analyser.smoothingTimeConstant = smoothInput.val() / 100;
- smoothCountText.text(smoothInput.val());
- }
- //Generate the bars based on i dataArray audio size
- for (i = 0; i < dataArray.length - excludeRatio; i++) {
- //The barWidth based on a percent of the view based on the dataArray
- barWidth = widthConstant * (renderer.width / 100);
- sizeControl = dataArray[i].map(0, 255, 0, renderer.height);
- g.drawRect(barWidth * i, renderer.height - sizeControl, barWidth, sizeControl);
- }
- //Finally, add the generated stuff to container
- container.addChild(g);
- //Render the Container
- renderer.render(container);
- }
- /************
- UTILS
- ************/
- //A debug function
- function debug(msg, type) {
- if (doDebug) {
- switch (type) {
- case "ERROR":
- console.log("[ERROR] YTMV > " + msg);
- break;
- case "INFO":
- console.log("[INFO] YTMV > " + msg);
- break;
- case "WARNING":
- console.log("[WARNING] YTMV > " + msg);
- break;
- default:
- console.log("[DEBUG] YTMV > " + msg);
- break;
- }
- }
- }
- //Get the data from the running analyser
- function passByteFrequencyData(array) {
- try {
- analyser.getByteFrequencyData(array);
- } catch (e) {
- debug("Error passing the ByteFrequencyData!", "ERROR");
- }
- }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址