我使用p5.js库用JavaScript制作了自己的音频播放器。该脚本使用循环浏览网页的所有元素,并向class的所有html元素onload()
添加canvas
(显示图形的东西)对象audioPlayer
。使用Firefox,一切正常,并且可以播放指定文件路径中的音频文件。当我在Chrome或Edge中加载网站时,在控制台中收到以下错误消息:
Not allowed to load local resource: blob:null/59e0d5f9-cf73-4135-9595-3214e6cc964e
多次发生此错误消息,每次在blop:null/
。之后都有另一个字符串。还有错误消息:
The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on
the page. https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio
我认为问题在于JavaScript出于安全性和原因而不喜欢加载本地文件。但是如果是这样,为什么它可以在Firefox上运行?这是不安全的浏览器吗?另外,如果必须在用户交互的帮助下加载音频,是否有解决方法?就像我说的那样,在Firefox上没问题。
我可能应该补充一点,该网站不是在线的,它是在本地运行的,并且我使用的是Firefox Developer Edition。
另外,如果有p5.js用户,我使用function windowResized()
来使画布的大小适应浏览器窗口。再次,它在Firefox上可以正常工作,但是在Chrome和Edge中,它会引发错误,因为我使用的是我之前未创建的类的变量(即使我在function setup()
其中创建了变量也应在此之前windowResized()
和之后运行)在Firefox上运行良好。
这是JavaScript文件的代码:
$(document).ready(function () {
let audioPanel = function (p) {
let track;
let isPlaying;
let width;
let height;
let margin;
let x;
let y;
let dim;
let volumeSlider;
let timeSlider;
let parentTag;
let filename;
let playMeta;
p.windowResized = function () {
width = innerWidth * 0.6;
height = innerWidth * 9 / 16 * 0.18;
p.resizeCanvas(width, height);
margin = 20;
x = margin;
y = margin;
dim = height - 2 * margin;
volumeSlider = new slider(this, margin * 3 + dim, height * 0.8, width * 0.5 - margin * 4 - dim, volumeSlider.min, volumeSlider.max, volumeSlider.actualValue, volumeSlider.decimalPrecision, width, height);
timeSlider = new slider(this, margin * 3 + dim, height * 0.5, width - margin * 12 - dim, timeSlider.min, timeSlider.max, timeSlider.actualValue, timeSlider.decimalPrecision, width, height);
};
p.setup = function () {
p.soundFormats('mp3', 'ogg');
width = innerWidth * 0.6;
height = innerWidth * 9 / 16 * 0.18;
var window = p.createCanvas(width, height);
//window.parent(parentTag.id);
parentTag = p.canvas.parentElement;
filename = parentTag.getElementsByTagName('meta')[0].getAttribute('content');
track = new Audio(filename);
let element = p.createElement('h1', parentTag.id);
element.parent(parentTag.id);
track.addEventListener('ended', p.finished);
isPlaying = false;
margin = 20;
x = margin;
y = margin;
dim = height - 2 * margin;
track.volume = 0.1;
volumeSlider = new slider(this, margin * 3 + dim, height * 0.8, width * 0.5 - margin * 4 - dim, 0, 100, 20, 0, width, height);
timeSlider = new slider(this, margin * 3 + dim, height * 0.5, width - margin * 12 - dim, 0, track.duration, 0, 2, width, height);
track.addEventListener('loadeddata', function () {
timeSlider.max = track.duration;
timeSlider.Update();
});
playMeta = p.createElement('meta');
playMeta.attribute('name', 'isPlaying');
playMeta.attribute('content', 'false');
};
p.draw = function () {
p.clear();
p.background(0, 0, 0, 50);
p.noStroke();
p.fill(0, 20);
p.rectMode(p.CORNER);
p.rect(0, 0, dim + 2 * margin, dim + 2 * margin);
p.ellipseMode(p.CORNER);
let alpha = 100;
if (p.insideButton()) {
alpha = 200;
}
p.fill(255, 255, 255, alpha);
p.ellipse(x, y, dim, dim);
p.fill(0, 150);
p.noStroke();
if (isPlaying) {
let dist = dim * 0.15;
p.rectMode(p.CENTER);
let w = dim * 0.15;
let h = dim * 0.5;
p.rect(x + dim / 2 - dist, y + dim / 2, w, h);
p.rect(x + dim / 2 + dist, y + dim / 2, w, h);
} else {
p.beginShape();
let r = dim * 0.35;
let angle = 0;
let da = p.TWO_PI / 3;
for (let i = 0; i < 3; i++) {
angle = da * i;
p.vertex(Math.cos(angle) * r + x + dim / 2, Math.sin(angle) * r + y + dim / 2);
}
p.endShape(p.CLOSE);
}
timeSlider.Update();
timeSlider.showText(p.SecondsToTime(track.currentTime) + ' / ' + p.SecondsToTime(track.duration));
timeSlider.actualValue = track.currentTime;
timeSlider.onChange = function () {
track.currentTime = timeSlider.actualValue;
}
timeSlider.Render();
volumeSlider.Update();
volumeSlider.showText('Volume: ' + volumeSlider.value + '%');
track.volume = volumeSlider.value / 100;
volumeSlider.Render();
if (playMeta.elt.getAttribute('content') == 'false' && isPlaying) {
p.PauseTrack();
} else if (playMeta.elt.getAttribute('content') == 'true' && !isPlaying) {
p.PlayTrack();
}
};
p.PlayTrack = function () {
track.play();
isPlaying = true;
playMeta.attribute('content', 'true');
let audioPlayers = document.getElementsByClassName('audioPlayer');
let otherPlayers = [];
for (let i = 0; i < audioPlayers.length; i++) {
if (audioPlayers[i].id != parentTag.id) {
otherPlayers.push(audioPlayers[i]);
}
}
for (let i = 0; i < otherPlayers.length; i++) {
let metas = otherPlayers[i].getElementsByTagName('meta');
let others = [];
for (let j = 0; j < metas.length; j++) {
if (metas[j].getAttribute('content') != filename && metas[j].getAttribute('name') == 'isPlaying') {
others.push(metas[j]);
}
}
for (let j = 0; j < others.length; j++) {
let otherPlayMeta = others[j];
otherPlayMeta.setAttribute('content', false);
}
}
}
p.PauseTrack = function () {
track.pause();
isPlaying = false;
playMeta.attribute('content', 'false');
}
p.SecondsToTime = function (secs) {
let minutes = p.nf(p.floor(secs / 60), 2);
let seconds = p.nf(p.floor(secs % 60), 2, 0);
let time = minutes + ':' + seconds;
return time;
};
p.mousePressed = function () {
if (p.insideButton() && p.mouseButton == p.LEFT) {
if (isPlaying) {
p.PauseTrack();
} else {
p.PlayTrack();
}
}
if (volumeSlider.insideSlider() && p.mouseButton == p.LEFT) {
volumeSlider.followMouse();
} else if (timeSlider.insideSlider() && p.mouseButton == p.LEFT) {
timeSlider.followMouse();
}
};
p.mouseReleased = function () {
volumeSlider.letGo();
timeSlider.letGo();
};
p.finished = function () {
p.PauseTrack();
track.currentTime = 0;
timeSlider.actualValue = track.currentTime;
};
p.insideButton = function () {
return (p.dist(p.mouseX, p.mouseY, x + dim / 2, y + dim / 2) <= dim / 2);
};
sketchhandleFile = function (file) {
track = createAudio(file.data, '');
track.hide();
};
};
let audioPlayers = document.getElementsByClassName('audioPlayer');
for (let i = 0; i < audioPlayers.length; i++) {
let newP5 = new p5(audioPanel, audioPlayers[i].id);
}
class slider {
constructor(p, x, y, w, min, max, startVal, decPris) {
this.width = p.width;
this.height = p.height;
this.decimalPrecision = decPris;
this.x = x;
this.y = y;
this.w = w;
this.stickToMouse = false;
this.margin = this.width * 0.08;
this.offset = 0;
this.min = min;
this.max = max;
this.actualValue = startVal;
this.onChange = function () { };
this.p = p;
this.dotR = p.height * 0.05;
// this.dotX = map(startVal, min, max, this.x, this.x + w);
this.value = startVal;
this.Update();
}
Update() {
if (this.stickToMouse) {
this.actualValue = this.p.constrain(this.p.map(this.p.mouseX - this.offset, this.x, this.x + this.w, this.min, this.max), this.min, this.max);
this.onChange();
}
// console.log(this.actualValue);
// console.log(this.min);
// console.log(this.max);
// console.log(this.x);
this.dotX = this.p.map(this.actualValue, this.min, this.max, this.x, this.x + this.w);
this.value = Math.round(this.actualValue * 10 ^ this.decimalPrecision) / 10 ^ this.decimalPrecision;
}
Render() {
this.p.strokeWeight(this.height * 0.05);
this.p.stroke(255, 255, 255, 100);
this.p.strokeCap(this.p.SQUARE);
this.p.line(this.x, this.y, this.x + this.w, this.y);
this.p.noStroke();
let alpha = 150;
let magnifier = 0;
if (this.insideSlider() || this.stickToMouse) {
alpha = 255;
}
if (this.stickToMouse) {
magnifier = this.dotR;
}
this.p.fill(0, 0, 0, alpha);
this.p.rectMode(this.p.CENTER);
this.p.rect(this.dotX, this.y, this.dotR * 2 + magnifier, this.dotR * 2 + magnifier);
}
showText(txt) {
this.p.fill(0, 0, 0, 100);
//textFont(font);
this.p.textAlign(this.p.LEFT, this.p.CENTER);
this.p.textSize(20);
this.p.text(txt, this.x + this.w + this.margin / 3, this.y);
}
followMouse() {
this.stickToMouse = true;
this.offset = this.p.mouseX - this.dotX;
}
letGo() {
this.stickToMouse = false;
}
insideSlider() {
return (this.p.dist(this.p.mouseX, this.p.mouseY, this.dotX, this.y) <= this.dotR);
}
}
});
这是html文件的一部分:
<div id="Interstellar - Piano Version" class="audioPlayer">
<meta name="file" content="audioTracks/interstellar.mp3">
</div>
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句