Audio Player JavaScript - javascript

I am trying to build an audio player. I can't seem to get to get the on load function to work. My songs are in E:\Music Player\Songs file directory path.
<script type=text/javascript>
var songs = ["Nobody Compares To You - Gryffin.mp3", "Crawl Outta Love - Illenium.mp3",
"Higher Ground - Odesza.mp3"
];
var poster = ["Nobody Compares to You - Gryffin.png", "Awake - Illenium.jpg",
"A Moment Apart - Odesza.jpg"
];
var songTitle = document.getElementById("songTitle");
var fillBar = document.getElementById("fill");
var song = new Audio();
var currentSong = 0; // it points to the current song
window.onload = playSong; // it will call the function playSong when window is load
function playSong() {
song.src = "./Songs/" + songs[currentSong]; //set the source of 0th song
songTitle.textContent = songs[currentSong]; // set the title of song
song.play(); // play the song
}
</script>

According to my knowledge, window.onload = playSong; is incorrectly calling playSong function.
window.onload = playSong(); // Brackets after a function name is mandatory.
Try this one.

Related

Problem streaming video using media source extensions

I seem to have a very strange problem. I am trying to play a video which is being streamed live using a web browser. For this, I am looking at the MediaSource object. I have got it in a way so that the video is taken from a server in chunks to be played. The problem is that the first chunk plays correctly then playback stops.
To make this even more strange, if I put the computer to sleep after starting streaming, then wake it up andthe video will play as expected.
Some Notes:
I am currently using chrome.
I have tried both of them ,with and without calling MediaSource's endOfStream.
var VF = 'video/webm; codecs="vp8,opus"';
var FC = 0;
alert(MediaSource.isTypeSupported(VF));
var url = window.URL || window.webkitURL;
var VSRC = new MediaSource();
var VURL = URL.createObjectURL(VSRC);
var bgi, idx = 1;
var str, rec, dat = [], datb, brl;
var sbx;
//connect the mediasource to the <video> elment first.
vid2.src = VURL;
VSRC.addEventListener("sourceopen", function () {
// alert(VSRC.readyState);
//Setup the source only once.
if (VSRC.sourceBuffers.length == 0) {
var sb = VSRC.addSourceBuffer(VF);
sb.mode = 'sequence';
sb.addEventListener("updateend", function () {
VSRC.endOfStream();
});
sbx = sb;
}
});
//This function will be called each time we get more chunks from the stream.
dataavailable = function (e) {
//video is appended to the sourcebuffer, but does not play in video element
//Unless the computer is put to sleep then awaken!?
sbx.appendBuffer(e.result);
FC += 1;
//These checks behave as expected.
len.innerHTML = "" + sbx.buffered.length + "|" + VSRC.duration;
CTS.innerHTML = FC;
};
You are making two big mistakes:
You can only call sbx.appendBuffer when sbx.updating property is false, otherwise appendBuffer will fail. So what you need to do in reality is have a queue of chunks, and add a chunk to the queue if sbx.updating is true:
if (sbx.updating || segmentsQueue.length > 0)
segmentsQueue.push(e.result);
else
sbx.appendBuffer(e.result);
Your code explicitly says to stop playing after the very first chunk:
sb.addEventListener("updateend", function () {
VSRC.endOfStream();
});
Here is what you really need to do:
sb.addEventListener("updateend", function () {
if (!sbx.updating && segmentsQueue.length > 0) {
sbx.appendBuffer(segmentsQueue.shift());
}
});

Video dosen't play at all. [JavaScript]

Im trying to read a local file with videos. Here is the code. I used array to add the videos and play it in sequence but it didn't play any video.
var videos = new Array(); //("BigBuck.m4v","Video.mp4","BigBuck.m4v","Video2.mp4");
var currentVideo = 0;
function nextVideo() {
// get the element
videoElement = document.getElementById("play-video");
// remove the event listener, if there is one
videoElement.removeEventListener('ended', nextVideo, false);
// update the source with the currentVideo from the videos array
videoElement.src = videos[currentVideo];
// play the video
videoElement.play()
// increment the currentVideo, looping at the end of the array
currentVideo = (currentVideo + 1) % videos.length
// add an event listener so when the video ends it will call the nextVideo function again
videoElement.addEventListener('ended', nextVideo, false);
}
function yesnoCheck() {
document.getElementById("filepicker").style.display = 'none';
}
// add change event to pick up selected files
document.getElementById("filepicker").addEventListener("change", function (event) {
var files = event.target.files;
// loop through files
for (var i = 0; i < files.length; i++) {
// select the filename for any videos
if (files[i].type == "video/mp4") {
// add the filename to the array of videos
videos.push(files[i].name); // work from webkitRelativePath;
}
};
// once videos are loaded initialize and play the first one
nextVideo();
}, false);
Any suggestions? Thank you.
You're going to have to read the contents of the video, not just set the src to it's name. You can do so by using the FileReader.
I've adjusted your code, but I haven't tested it. Here's a working example on JsFiddle, though.
var videos = new Array(); //("BigBuck.m4v","Video.mp4","BigBuck.m4v","Video2.mp4");
var currentVideo = 0;
var reader = new FileReader();
// get th eelement
var videoElement = document.getElementById("play-video");
function nextVideo() {
// remove the event listener, if there is one
videoElement.removeEventListener('ended', nextVideo, false);
// read the file contents as a data URL
reader.readAsDataURL(videos[currentVideo]);
// increment the currentVideo, looping at the end of the array
currentVideo = (currentVideo + 1) % videos.length
// add an event listener so when the video ends it will call the nextVideo function again
videoElement.addEventListener('ended', nextVideo, false);
}
function yesnoCheck() {
document.getElementById("filepicker").style.display = 'none';
}
// add change event to pick up selected files
document.getElementById("filepicker").addEventListener("change", function (event) {
var files = event.target.files;
// loop through files
for (var i = 0; i < files.length; i++) {
// select the filename for any videos
if (files[i].type == "video/mp4") {
// add the whole file to the array
videos.push(files[i]);
}
};
// once videos are loaded initialize and play the first one
nextVideo();
}, false);
// once the file is fully read
reader.addEventListener('load', function() {
// you have the data URL in reader.result
videoElement.src = reader.result;
// play the video
videoElement.play()
});

how to get audio.duration value by a function

Im my audio player I need to get the duration of my audio track. I need a function that gets src of the audio and returns its duration. Here is what I am trying to do but does not work:
function getDuration(src){
var audio = new Audio();
audio.src = "./audio/2.mp3";
var due;
return getVal(audio);
}
function getVal(audio){
$(audio).on("loadedmetadata", function(){
var val = audio.duration;
console.log(">>>" + val);
return val;
});
}
I tried to split into two functions but it does not work. It would be great if it was as on working function.
Any idea?
because you're relying on an event to fire, you can't return a value in getDuration or getVal
instead, you want to use a callback function, like this (callbacks)
The example assume you want to put the duration into a span written like this
<span id="duration"></span>
function getDuration(src, cb) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
cb(audio.duration);
});
audio.src = src;
}
getDuration("./audio/2.mp3", function(length) {
console.log('I got length ' + length);
document.getElementById("duration").textContent = length;
});
Any code that needs to "know" the length should be inside the callback function (where console.log is)
using Promises
function getDuration(src) {
return new Promise(function(resolve) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
resolve(audio.duration);
});
audio.src = src;
});
}
getDuration("./audio/2.mp3")
.then(function(length) {
console.log('I got length ' + length);
document.getElementById("duration").textContent = length;
});
using Events - note 'myAudioDurationEvent' can obviously be (almost) anything you want
function getDuration(src, obj) {
return new Promise(function(resolve) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
var event = new CustomEvent("myAudioDurationEvent", {
detail: {
duration: audio.duration,
}
});
obj.dispatchEvent(event);
});
audio.src = src;
});
}
var span = document.getElementById('xyz'); // you'll need to provide better logic here
span.addEventListener('myAudioDurationEvent', function(e) {
span.textContent = e.detail.duration;
});
getDuration("./audio/2.mp3", span);
although, this can be done similarly with callback or promise by passing in a destination to a modified getDuration function in those solutions as well - my point about using event listeners was more appropriate if one span for example was updated with duration multiple times - this solution still only does each span only once, so can be achieved with the other methods just as easily
given the new information in the comments for this answer, I believe this to be the better solution
function getDuration(src, destination) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
destination.textContent = audio.duration;
});
audio.src = src;
}
and then invoke getDuration as needed like this
var span = createOrGetSomeSpanElement();
getDuration("./audio/2.mp3", span);
createOrGetSomeSpanElement returns the destination element to use in the getDuration function - how this is done is up to you, seeing as you create a playlist in a loop, I'm guessing you have some element created to receive the audio length already created - it's hard to answer a half asked question sometimes

LocalStorage Save Javascript

My localstorage save and load won't work
I can't load or save. Can you please help me out?
I don't know whether it is the variables or functions that has been put up incorrectly
The functions are being called by HTML buttons that goes "onclick" and has ID's
var faze = 0;
function fazeClick(number){
faze = faze + number;
document.getElementById('faze').innerHTML = faze;
}
var mntDew = 0;
function buyDew(){
var mntDewCost = Math.floor(10 * Math.pow(1.1,mntDew));
if(faze >= mntDewCost){
mntDew = mntDew +1;
faze = faze - mntDewCost;
document.getElementById('mntDew').innerHTML = mntDew;
document.getElementById('faze').innerHTML = faze;
};
var nextCost = Math.floor(10 * Math.pow(1.2,mntDew));
document.getElementById('mntDewCost').innerHTML = nextCost;
};
window.setInterval(function(){
fazeClick(mntDew);
}, 1000);
function save(){
localstorage.setItem.faze;
};
function load(){
document.getElementById("faze").innerHTML = localstorage.getItem.faze;
};
document.write(faze);
// <button type="button" onClick="buyDew()">Buy Mountain Dew</button> #buyCursor
//Mountain Dew: <span id="mntDew">0</span><br/> #cursors
//cost: <span id="mntDewCost">10</span> #cursorCost
You got one letter wrong, it is spelled localStorage:
http://diveintohtml5.info/storage.html
var foo = localStorage.getItem("bar");
// ...
localStorage.setItem("bar", foo);
I would mostly advise to wrap your storage in a class, so that you would create a bridge pattern. And separate place of storage from your code logic, it will be easyer to change it so other type of storage in the future.
Check out the syntax for loading/saving values in localStorage
http://www.w3schools.com/html/html5_webstorage.asp
You can either use:
localStorage.setItem('faze', newFazeValue); // save
var newFazeValue = localStorage.getItem('faze'); // load
or
localStorage.faze = newFazeValue; // save
var newFazeValue = localStorage.faze; // load

condition and loop: how can i don't resume the music when calling the function several times?

i have this function to play music with web audio API:
function playMusic(){
if(countPre<count ){
audio0.play();
audio0.src = '0.mp3';
audio0.controls = true;
audio0.autoplay = true;
audio0.loop = true;
source = context.createBufferSource();
source.connect(analyser);
analyser.connect(context.destination);
}
else{audio0.pause();}
}
However, the value of count and countPre are generated in a loop that runs 10 times per second.
I have to put the function playMusic inside that loop in order to update the values.
And here comes the problem:
I call playMusic 10 times per second! Every time, the music resumes.
I don't want it resumes, i want it plays continuously as long as the play condition is matched.
So is there any solution?
You have to check that music is not already playing in your condition.
Don't think there's an audio method for that.
You can do it by many ways, example :
function playMusic(){
if(countPre<count && !this.is_playing ){
this.is_playing = true;
audio0.play();
audio0.src = '0.mp3';
audio0.controls = true;
audio0.autoplay = true;
audio0.loop = true;
source = context.createBufferSource();
source.connect(analyser);
analyser.connect(context.destination);
}
else{audio0.pause();
this.is_playing = false}
}

Categories