Reputation: 25
So here is a fiddle of what my problem is. As you can see, streaming the song through SoundCloud works with an HTML5 audio player using the built-in controls. However, if I try to use it on an HTML5 audio player using custom controls, this does not work.
My custom controls do work if playing a song that is not streamed via the SoundCloud API, like if I use a song that I have the actual file for (proof). So it has something to do with streaming it, and I'm not sure what.
And advice/pointing in the proper direction would be greatly appreciated!!! I suspect it has something to do with the actual play button because the length of the song in the custom HTML5 audio player is being saved and you can move the song's player around. I'm just don't know JS well enough to figure this one out on my own.
HTML for custom audio player:
<div class="posts">
<div class="music-block">
<div class="album-cover-wrapper">
<img src="http://payload74.cargocollective.com/1/0/5464/3780629/Tame-Impala_Lonersim_800.jpg" width="200px"/>
</div>
<audio id="music" preload="true">
</audio>
<div class="player">
<div id="timeline">
<div id="playhead"></div>
</div>
</div>
<div class="review"><button id="pButton" class="play" onclick="play()"></button></div>
<div class="song-info"></div>
</div>
</div>
Javascript for custom audio player:
var music = document.getElementById('music'); // id for audio element
var duration; // Duration of audio clip
var pButton = document.getElementById('pButton'); // play button
var playhead = document.getElementById('playhead'); // playhead
var timeline = document.getElementById('timeline'); // timeline
// timeline width adjusted for playhead
var timelineWidth = 225;
// timeupdate event listener
music.addEventListener("timeupdate", timeUpdate, false);
//Makes timeline clickable
timeline.addEventListener("click", function (event) {
moveplayhead(event);
music.currentTime = duration * clickPercent(event);
}, false);
// returns click as decimal of the total timelineWidth
function clickPercent(e) {
return (e.pageX - timeline.offsetLeft) / timelineWidth;
}
// Makes playhead draggable
playhead.addEventListener('mousedown', mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);
// Boolean value so that mouse is moved on mouseUp only when the playhead is released
var onplayhead = false;
function mouseDown() {
onplayhead = true;
window.addEventListener('mousemove', moveplayhead, true);
music.removeEventListener('timeupdate', timeUpdate, false);
}
// getting input from all mouse clicks
function mouseUp(e) {
if (onplayhead == true) {
moveplayhead(e);
window.removeEventListener('mousemove', moveplayhead, true);
music.currentTime = duration * clickPercent(e);
music.addEventListener('timeupdate', timeUpdate, false);
}
onplayhead = false;
}
// Moves playhead as user drags
function moveplayhead(e) {
var newWidth = e.pageX - timeline.offsetLeft;
if (newWidth >= 0 && newWidth <= timelineWidth) {
playhead.style.width = newWidth + "px";
}
if (newWidth < 0) {
playhead.style.width= "0px";
}
if (newWidth > timelineWidth) {
playhead.style.width = timelineWidth + "px";
}
}
// timeUpdate
// Synchronizes playhead position with current point in audio
function timeUpdate() {
var playPercent = timelineWidth * (music.currentTime / duration);
playhead.style.width = playPercent + "px";
if (music.currentTime == duration) {
pButton.className = "";
pButton.className = "play";
}
}
//Play and Pause
function play() {
// start music
if (music.paused) {
music.play();
// remove play, add pause
pButton.className = "";
pButton.className = "pause";
} else { // pause music
music.pause();
// remove pause, add play
pButton.className = "";
pButton.className = "play";
}
}
// Gets audio file duration
music.addEventListener("canplaythrough", function () {
duration = music.duration;
}, false);
Upvotes: 1
Views: 519
Reputation: 2071
It appears the issue you are having is that you are creating the javascript objects "music", "pButton" etc. before the elements that are used to create them have loaded into the document.
var music = document.getElementById('music'); // id for audio element
When music is created the dom element doesn't exist and therefore music is null.
Simply change the "Frameworks & Extensions" setting in JSFiddle to "No wrap - in body" and your code will work.
Please refer to this jsFiddle
The simplest solution to this issue when serving the HTML file is to include the script tag that contains this code after all the other dom elements.
<div>
//all dom elements that make up the page
</div>
//Then add the script
<script src="/js"></script>
I have tested this and your code will run without any modification if you include the script tag at the end of the HTML file.
Upvotes: 1