@azgaar/tone
Version:
A fork of Web Audio framework for making interactive music in the browser.
121 lines • 4.43 kB
JavaScript
import { Tone } from "../Tone";
import { optionsFromArguments } from "../util/Defaults";
import { noOp } from "../util/Interface";
/**
* MediaElement loading and storage. ToneMediaElement is used internally by MediaElementSampler
* @example
* const mediaElement = new Tone.ToneMediaElement("https://tonejs.github.io/audio/casio/A1.mp3", () => {
* console.log("loaded");
* });
* @category Core
*/
export class ToneMediaElement extends Tone {
constructor() {
super();
this.name = "ToneMediaElement";
/**
* Callback when the element is loaded
*/
this.onload = noOp;
const options = optionsFromArguments(ToneMediaElement.getDefaults(), arguments, ["url", "onload", "onerror"]);
this.onload = options.onload;
if (options.url) {
// initiate the download
const element = ToneMediaElement.load(options.url);
if (!element) {
options.onerror(new Error("Cannot create ToneMediaElement"));
return;
}
this._element = element;
}
}
static getDefaults() {
return {
onerror: noOp,
onload: noOp,
};
}
/**
* The media element stored in the object.
*/
get() {
return this._element;
}
/**
* clean up
*/
dispose() {
super.dispose();
this._element = undefined;
return this;
}
/**
* Creates HTMLAudioElement for provided url.
*/
static load(url) {
// test if the url contains multiple extensions
const matches = url.match(/\[([^\]\[]+\|.+)\]$/);
if (matches) {
const extensions = matches[1].split("|");
let extension = extensions[0];
for (const ext of extensions) {
if (ToneMediaElement.supportsType(ext)) {
extension = ext;
break;
}
}
url = url.replace(matches[0], extension);
}
// make sure there is a slash between the baseUrl and the url
const baseUrl = ToneMediaElement.baseUrl === "" ||
ToneMediaElement.baseUrl.endsWith("/")
? ToneMediaElement.baseUrl
: ToneMediaElement.baseUrl + "/";
let href = baseUrl + url;
if (!href.startsWith("file:/") && decodeURIComponent(href) === href) {
// if file:/ scheme, assume already encoded, otherwise use decodeURIComponent to check if already encoded
// encode special characters in file path
const anchorElement = document.createElement("a");
anchorElement.href = href;
// check if already encoded one more time since in many cases setting the .href automatically encodes the string
if (!anchorElement.href.startsWith("file:/") &&
decodeURIComponent(anchorElement.href) === anchorElement.href) {
anchorElement.pathname = (anchorElement.pathname + anchorElement.hash)
.split("/")
.map(encodeURIComponent)
.join("/");
}
href = anchorElement.href;
}
const element = new Audio(href);
if (!element) {
throw new Error(`could not create HTMLAudioElement for source: ${url}`);
}
return element;
}
/**
* Checks a url's extension to see if the current browser can play that file type.
* @param url The url/extension to test
* @return If the file extension can be played
* @static
* @example
* Tone.ToneAudioBuffer.supportsType("wav"); // returns true
* Tone.ToneAudioBuffer.supportsType("path/to/file.wav"); // returns true
*/
static supportsType(url) {
const extensions = url.split(".");
const extension = extensions[extensions.length - 1];
const response = document
.createElement("audio")
.canPlayType("audio/" + extension);
return response !== "";
}
}
//-------------------------------------
// STATIC METHODS
//-------------------------------------
/**
* A path which is prefixed before every url.
*/
ToneMediaElement.baseUrl = "";
//# sourceMappingURL=ToneMediaElement.js.map