It often desirable to have the Processing.js script interact with the audio player setup in the .html file. KISA 1 illustrates how to get information from the audio player and also specify the file to be played.
The following line
16 Audio audio = document.getElementById("audiotag");
shows how we can connect the script with the audio player. We declare an Audio object named "audio" that connects using the Id in the audio tag of the .html file. After this we can use "audio" variable just as if the Audio class was defined in the sketch. (Of course, you can use whatever variable name you want instead of "audio".)
Some information about the status of the audio player is available just by asking for it. Assuming the audio player variable is named "audio", this includes the following:
Code | Meaning |
---|---|
audio.src | the URL of the file loaded into the player. |
audio.currentTime | The current location in the file expressed in seconds |
audio.duration | The length of the audio file in seconds. |
audio.volume | The volume of the audio player on a scale from 0.0 to 1.0. |
44 text("Source file: " + audio.src, width/2, 60); 45 text("Status: " + audioStatus, width/2, 75); 46 text("Current time: " + round(audio.currentTime) 47 + " sec. Length: " + round(audio.duration)+ " sec.", width/2, 90); 48 text("Volume (0 to 1): " + round(10 * audio.volume)/10, width/2, 105);
The numeric variables were rounded primarily to avoid the possibility of having long decimal expansions. The control in the browser may truncate the decimals instead of rounding them so the value shown in the sketch might be 1 unit larger than shown in the html control. Because the volume values are in the range 0 to 1, these values are rounded to the nearest tenth. As an alternative, you might want to multiply them by 10 and display values from 0 to 10.
The audio player can send information about its status if it is requested to do so. This is done with the addEventListener function (see lines 26 to 30).
26 audio.addEventListener("loadstart", loadStart, false); 27 audio.addEventListener("playing", playing, false); 28 audio.addEventListener("pause", pause, false); 29 audio.addEventListener("ended", ended, false); 30 audio.addEventListener("error", error, false);
For example, line 26 asks audio to call the script's function "void function loadStart()", the second parameter, whenever the "loadstart" event, the first parameter, (that is, when the audio player starts to load the file) occurs. KISA uses the following events:
Event | Meaning |
---|---|
loadStart | when starting to load a file |
playing | when starting to play a file |
pause | when playing is paused |
ended | when the file has finished playing |
error | when an error occurs. (At least in Firefox, this only happens on selected errors) |
Many other events can be requested.
In KISA (remember "Keep It Simple"), the event handler functions (lines 62 - 91) just put status in the audioStatus variable which is displayed in the draw function in line 45.
The "stop" status within the pause function needs to be explained.
72 void pause() { 73 // Pause event processing. 74 // There is no stop event but a "stop" causes a pause. This 75 // method checks to see if the current time = 0. If so it assumes 76 // stopped 77 if (audio.currentTime == 0) 78 audioStatus = "Stopped"; 79 else 80 audioStatus = "Paused"; 81 }
Once the audio player starts playing a file, it wants to play it to completion unless the pause operation is used. What if the user want to actually stop the playback? Unfortunately there is no "stop" operation or event. Instead a stop can be achieved in two steps. One pauses the playback and then sets the currentTime to 0. (We will set up a function to do this in KISA 2) But note that carrying this out causes the "pause" event. Hence the pause() function checks the current time. If it is 0, it assumes the file has been stopped. Otherwise it assumes the playback has been paused.
Pausing and setting the current time to 0 stops the playback but not necessarily the download of the source file. The KISA 2 tutorial suggest a way to stop the download.
KISA 1 also illustrates how the sketch can specify the source file that will played. This is done in the setSource function.
51 void setSource(String url) { 52 // Called to set the source file. Do not include the file extension 53 // in the url. It will be added here. 54 if (audio.canPlayType && audio.canPlayType("audio/ogg")) { 55 audio.setAttribute("src", url + ".ogg"); 56 } else { 57 audio.setAttribute("src", url + ".mp3"); 58 } 59 audioStatus = "File selected"; 60 }
Recall that some browsers cannot play all the files types. Again it is assumed that both .ogg and .mp3 versions of the music file are available. In line 54 we ask if the audio.canPlayType function is available, and if so, can it play the mime type "audio/ogg". If so, it uses the "src" attribute to specify the URL of the desired file after adding the ".ogg" extension. If not, it requests the player use the file with the ".mp3" extension.
We need to discuss the setAttribute method used in lines 55 and 57. You might discover that line 55 can be replaced
55 audio.src = url + ".ogg"
in some browsers but this is not recommended because it does not work in all of them. and Safari 5.1 browsers.
The mime types for the files that work with the tested browsers are:
Mime type | file extension |
---|---|
audio/mpeg | mp3 |
audio/ogg | ogg |
audio/wav | wav |
Unfortunately, some servers may use different mime types that particular browsers do accept.
The .html file was simplified by removing the two <source ..> tags found between the <audio ..> and </audio> tags because the audio file is specified in sketch. It has been discovered that failure to remove these lines can cause problems with some browsers.
Information concerning additional audio events can be found at HTML5 Audio Demo. Just be aware that some other sources prefix event names with "on" but is not used in Javascript or Processing.js. For example, we used "ended" instead of "onended".
In the next part of the tutorial, the most basic ways Processing.js
can control the player are described.
< Previous
Next >
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>KISA 1 (Keep It Simple Audio)</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 6 <script type="text/javascript" src="processing.min.js"></script> 7 </head> 8 <body> 9 <h1>Keep It Simple Audio 1</h1> 10 <canvas id="KISA" data-processing-sources="KISA1.pde"></canvas> 11 <br> 12 <audio id="audiotag" preload="auto" controls="controls" autoplay = "autoplay"> 13 Your browser does not support HTML 5 audio. You may want to update your 14 browser to a current version. 15 </audio> 16 </body> 17 </html>
1 // KISA 2 // Keep It Simple Audio version 1 3 // James Brink brinkje@plu.edu 4 // 3/7/12 4/12/12 5 6 // The constants can be modified. 7 int width = 500; // Width of canvas 8 int height = 290; // Height of canvas 9 // It is assumed that both .ogg and .mp3 versions of the files are available 10 // in the same folder. The file names must be complete URLs except for the 11 // ending .ogg or .mp3 which must be omitted. It will be added as needed for 12 // the browser. Use the prefix "file:///" or "http:// as appropriate. 13 String file1 = "http://brinkje.com/KISA_Sounds/groove"; 14 15 // Global variables 16 Audio audio = document.getElementById("audiotag"); 17 18 int time; 19 String audioStatus; 20 21 void setup() { 22 // Setup the sketch 23 size(width, height); 24 smooth(); 25 frameRate(20); 26 audio.addEventListener("loadstart", loadStart, false); 27 audio.addEventListener("playing", playing, false); 28 audio.addEventListener("pause", pause, false); 29 audio.addEventListener("ended", ended, false); 30 audio.addEventListener("error", error, false); 31 32 audioStatus = ""; 33 34 setSource(file1); 35 } // setup 36 37 void draw() { 38 // Draws the sketch on the canvas 39 background(#FFFFAA); 40 41 fill(#000000); 42 textAlign(CENTER); 43 text("KISA 1", width/2, 30); 44 text("Source file: " + audio.src, width/2, 60); 45 text("Status: " + audioStatus, width/2, 75); 46 text("Current time: " + round(audio.currentTime) 47 + " sec. Length: " + round(audio.duration)+ " sec.", width/2, 90); 48 text("Volume (0 to 1): " + round(10 * audio.volume)/10, width/2, 105); 49 } 50 51 void setSource(String url) { 52 // Called to set the source file. Do not include the file extension 53 // in the url. It will be added here. 54 if (audio.canPlayType && audio.canPlayType("audio/ogg")) { 55 audio.setAttribute("src", url + ".ogg"); 56 } else { 57 audio.setAttribute("src", url + ".mp3"); 58 } 59 audioStatus = "File selected"; 60 } 61 62 void loadStart() { 63 // LoadStart event processing 64 audioStatus = "Loading"; 65 } 66 67 void playing() { 68 // Playing event processing 69 audioStatus = "Playing"; 70 } 71 72 void pause() { 73 // Pause event processing. 74 // There is no stop event but a "stop" causes a pause. This 75 // method checks to see if the current time = 0. If so it assumes 76 // stopped 77 if (audio.currentTime == 0) 78 audioStatus = "Stopped"; 79 else 80 audioStatus = "Paused"; 81 } 82 83 void ended() { 84 // Ending event processing 85 audioStatus = "Finished playing"; 86 } 87 88 void error() { 89 // error event processing 90 audioStatus = "Error"; 91 }
Updated 11/6/14