I'd like to know how could I achieve a video playlist without any buttons or control that would simply play an array of videos and would start again when the last is over.
I found this piece of code about a clickable playlist : http://jsfiddle.net/e8CbF/
but I really don't know how to make it automatic. Also, the array is coming from a PHP variable, how I can I use it inside this code ?
function loadVids(vidsArray){
for(var a=0,b,f=document.createDocumentFragment();b=vidsArray[a];++a){
var c=document.createElement('div');
c.textContent=b;
f.appendChild(c);
}
d.appendChild(f);
}
var video=document.createElement('video'),vids=['http://screen.alifts.com/screenfiles/video1.mp4','http://screen.alifts.com/screenfiles/video2.mp4'], /* Is it there that I should put the php array ? */
d=document.createElement('div');
d.onclick=function(e){if(e.target.parentNode==this){
video.src=e.target.textContent;
video.play();
}}
document.body.appendChild(video);
document.body.appendChild(d);
loadVids(vids);
Your code is a total mess. So i completely rewrite it.
<video src="" id="player"/>
<script>
var video=counter=0;
videos=['<?php echo join("';'",$array);?>'];
window.onload=()=>{
//get the video frame
video=document.getElementById("player");
//if the video ended, play next.
video.addEventListener("ended",play,false);
//start
play();
}
var play=()=>{
//add the video src
video.src=videos[counter];
//play next video next time
counter++;
if(counter==videos.length){
counter=0;
}
};
</script>
Related
I have designed an i-phone-like screen on a web browser where I am testing this application I am in the process of building. It works great up until the point where I want to call out another set of videos.
What works
The application is structured so that when the user sees the screen she is directed to a channel that has a vertical video.
The buttons on the top left and top right advance to the next and the previous video.
<div id="topVid" class="videoContainer">
<div class="topHorizontalButtonRow">
</div>
<video class="topVid" loop onclick="this.paused? this.play() : this.pause()" >
<source src="videos/ParisisBurning_660x370_I_went_to_a_ball.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
There is a "channel" button that shows the user a smaller window if pressed, where the user can view other channels by clicking on a second set of buttons next and previous buttons.
<div id="bottomVid" class="videoContainerTwo hiddenElement">
<div class="topHorizontalButtonRow">
<div class="buttonLeftTriangleBlue"></div>
<div class="buttonRightTriangleBlue"></div>
</div>
<video loop onclick="this.paused? this.play() : this.pause()" >
<source src="videos/Politics_Refugee_Sign.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
jquery show/hide smaller window:
$(".buttonTeardropChannelBlue").click( function (){
if( $("#bottomVid").is(':visible') ) {
$("#bottomVid").hide();
} else {
$("#bottomVid").show();
}
});
If the user wants to watch this specific channel, she can click on the smaller window, which hides the current window and advances to the other channel. The video can be clicked on, and once that happens, the user will be directed to the next channel.
Below is the code that works perfectly to advance the video of the current selection, and it contains the videos in arranged in an array.
var Vids = (function() {
var _currentId = -1;
var _urls =
["videos/ParisisBurning_370x660_Get_Into_The_Suits_Vert.mp4","videos/ParisisBurning_370x660_School_Vert.mp4","videos/ParisisBurning_660x370_I_came_I_saw_Vert.mp4", "videos/ParisisBurning_660x370_I_went_to_a_ball.mp4"]; // literal array
return {
next: function() {
if (++_currentId >= _urls.length)
_currentId = 0;
return this.play(_currentId);
},
prev: function() {
if (--_currentId < 0)
_currentId = _urls.length - 1;
return this.play(_currentId);
},
play: function(id) {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = _urls[id];
myVideo.load();
myVideo.play();
return false;
}
}
})();
What does not work
The issue: showing and hiding multiple video lists
However, the problem starts when I want to select a different class of videos, which has the exact same code except for different videos. I have changed the name of the function to say, VidsTwo but the problem remains.
var VidsTwo = (function() {
var _currentId = -1;
var _urls = ["videos/Politics_Atl_We_are_the_people.mp4","videos/Politics_Atlanta_Whose_Streets.mp4", "videos/Politics_Womens_March_Washington_CBS_VERT.mp4",
"videos/Politics_No_bans_no_walls_America_is_home_to_all_VERT.mp4",
"videos/Politics_Let_them_in_VERT.mp4",
"videos/Politics_Tear it Down_JFK_VERT.mp4",
"videos/Politics_This_is_What_America_Looks_Like_embrace.mp4",
"videos/Politics_This_land_was_made_VERT.mp4", "videos/Politics_We_need_an_independent_investigation_town_hall.mp4",
"videos/Politics_Just say no_town_hall_VERT.mp4", ]; // literal array
return {
next: function() {
if (++_currentId >= _urls.length)
_currentId = 0;
return this.play(_currentId);
},
prev: function() {
if (--_currentId < 0)
_currentId = _urls.length - 1;
return this.play(_currentId);
},
play: function(id) {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = _urls[id];
myVideo.load();
myVideo.play();
return false;
}
}
})();
The issue remains: the buttons will continue to play the videos of the current channel in addition to the ones of the new channel, and it will not hide the current video. I understand it happens because in the javascript code, it uses the select element by tag which is "video". and all the array lists have "video" so it is playing all of them.
What is the best solution to this problem, given that I want to be able to separate the videos into categories "channels" that will have similar thematic content, and that this categories will be called by users as they look at a second smaller window of videos?
Core questions
Is there a way to have it NOT play a selection of arrays? What can I change in the Javascript code that will indicate that these separate video arrays do not belong to the same class? How can I make it clear in the code that these videos, although they are all videos, belong to different categories and therefore can only be played if their specific category is called?
Brainstorming solutions:
I am thinking I would probably need a second div that will have a
second row of buttons that call out the second function, since the
prev and next indicate a separate variable that was declared for each
class of videos...but this is getting a bit complicated for my newbie
skills:)
Or perhaps each video on a parent class should be saved on the
html itself as a hidden div and should be called by using "show
next child of parent div", as opposed to being saved as an array on
the javascript code?
The next step is adding marquee text to each video so maybe having
separate hidden divs on the html itself is a better solution than
having the videos stored as javascript arrays?
This is basically a prototype/beta for something that will become an
app so there is no database yet, (which will make it easier to
store this info eventually once I begin more in-depth user tests).
This complication is for testing only:)
UPDATE: I am still curious as to what the best solution would be, however I have decided, in this case, to add divs directly to the html and use jquery's next sibling selectors. Because I will have some text specific to some videos, they won't be properly connected to the javascript arrays anyway. I find the javascript array solution "cooler" but it is perhaps not the best in the end.
make Vids like this:
var Vids = function(vidArray=[]) {
var _currentId = -1;
var _urls = vidArray;
return {
next: function() {
if (++_currentId >= _urls.length)
_currentId = 0;
return this.play(_currentId);
},
prev: function() {
if (--_currentId < 0)
_currentId = _urls.length - 1;
return this.play(_currentId);
},
play: function(id) {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = _urls[id];
myVideo.load();
myVideo.play();
return false;
}
}
};
then prepare your url array and call Vids:
var urls =["videos/ParisisBurning_370x660_Get_Into_The_Suits_Vert.mp4","videos/ParisisBurning_370x660_School_Vert.mp4","videos/ParisisBurning_660x370_I_came_I_saw_Vert.mp4", "videos/ParisisBurning_660x370_I_went_to_a_ball.mp4"];
Vids(urlf).play(3); //Replace 3 with any id
I am trying to use a intro sound for the mp3 files. After playing the intro the original track should start to play. i mean the original mp3 plays right after the intro ends. Here i have this:
<script type="text/javascript" src="js/jquery.min.js"></script>
<audio id='top' onended="playOrg();" preload='none' src='http://www.sounddogs.com/previews/59/mp3/607322_SOUNDDOGS__th.mp3' type='audio/mpeg'> </audio>
<a href='#' class='btn' id='audioControl'> START </a>
And here the javascript part:
<script type="text/javascript">
var yourAudio = document.getElementById('top');
var ctrl = document.getElementById('audioControl');
ctrl.onclick = function () {
var pause = ctrl.innerHTML === 'STOP';
$('.btn').html('START');
$('audio').trigger('pause');
ctrl.innerHTML = pause ? 'START' : 'STOP';
var method = pause ? 'pause' : 'play';
yourAudio [method]();
return false; };
function playOrg(){
yourAudio.setAttribute('onended','orgPlayed()');
yourAudio.src='http://www.sounddogs.com/sound-effects/59/mp3/606540_SOUNDDOGS__sf.mp3';
yourAudio.play();
console.log('playOrg()');
}
function orgPlayed(){
yourAudio.setAttribute('onended','playOrg()');
yourAudio.src='http://www.sounddogs.com/previews/59/mp3/607322_SOUNDDOGS__th.mp3';
yourAudio.pause();
yourAudio.currentTime = 0;
console.log('orgPlayed()');
}
</script>
When i press start the file plays and on the end it calls the playOrg() function witch should change some attributes and should play the original track. Then the second file should play and on its end this time the orgPlayed() function should be called and set back the attributes so that it is ready for the other play.
So i want to use intro track for all my track on the site. But i can't accomplish that. i appreciate any upcoming help.
PS: Actually there is a loop for all tracks in my original code but i summarised it here. Please don't ask why i couldn't find better mp3 test files :).
I found the my problem. Instead of reloading the new track with "currentTime=0" i tried to reload with "load()" , and now it works. I guess sometime we need to sleep over such problems :). Thanks to everyone ;).
<audio id='top' onended="playOrg();" preload='none' src='top10/intro/1.mp3' type='audio/mpeg'> </audio>
<a href='#' class='btn' id='audioControl'>START</a>
<script type="text/javascript">
var yourAudio = document.getElementById('top');
var ctrl = document.getElementById('audioControl');
ctrl.onclick = function () {
if (ctrl.innerHTML=='START') {
ctrl.innerHTML='STOP';
yourAudio.play();
}else if (ctrl.innerHTML=='STOP'){
ctrl.innerHTML='START';
yourAudio.pause();
}
}
function playOrg(){
var myPlayer= document.getElementById('top');
myPlayer.setAttribute('onended','orgPlayed()');
myPlayer.src='top10/tarkan.mp3';
myPlayer.pause();
myPlayer.load();
myPlayer.play();
}
function orgPlayed(){
var myPlayer= document.getElementById('top');
myPlayer.setAttribute('onended','playOrg()');
myPlayer.src='top10/intro/1.mp3';
myPlayer.pause();
myPlayer.load();
ctrl.innerHTML='START';
}
</script>
now i realised another way to solve this. i could use two audio tags with one intro source and the other the original source. and then after the first one ends i could play the second using either a function or directly onended="document.getElementById('top2').play();"
i mean something like this:
<audio id='top1' onended="play second(with a function or directly)" preload='none' src='intro' type='audio/mpeg'> </audio>
<audio id='top2' onended="make ready for another play (with a function or directly)" preload='none' src='original' type='audio/mpeg'> </audio>
<a href='#' class='btn' id='audioControl'>START</a>
I'm trying to build an MP3 player. Here I want to perform a switch to the next song once the current tack ends.
Here is a part of my code:
function clicki(ID, norrnd) {
if (norrnd == 'nor') {
$('.liActive').removeClass('liActive');
$('#' + ID).next().addClass('liActive');
// Set track Data
$('audio').attr('id', 'audioNor');
$('audio').attr('src', $('.liActive').attr('rel'));
// Play
var player = $('.tbd').get(0);
player.play();
$('#pause').removeClass('hi');
$(player).bind('ended', clicki(ID++, 'nor')); //as well as .onfinish result in TOO MUCH RECURSION error.
}
}
<audio controls id="" class="tbd" type="audio/mpeg" src="Ella Fitzgerald - It Don't Mean a Thing.mp3"></audio>
So when I just initiate clicki() first time the page instantly freezes:
Too Much Recursion.
How do I make the track be automatically switched with no Recursion flood?
You're calling the function immediately -- you need to create a function around it:
function clicki(ID, norrnd) {
if (norrnd === 'nor') {
$('.liActive').removeClass('liActive');
$('#' + ID).next().addClass('liActive');
// Set track Data
$('audio').attr('id', 'audioNor');
$('audio').attr('src', $('.liActive').attr('rel'));
// Play
var $player = $('.tbd');;
$player.get(0).play();
$('#pause').removeClass('hi');
// if you call it now, it's going to keep calling itself
$player.bind('ended', function () {
clicki(ID++, 'nor');
});
}
}
function EvalSound(soundobj) {
var thissound=document.getElementById(soundobj);
thissound.currentTime = 0;
thissound.Play();
}
function StopSound(soundobj) {
var thissound=document.getElementById(soundobj);
thissound.Stop();
}
This is my code to play a audio file,
onmouseover="EvalSound('sound1')" onmouseout="StopSound('sound1')"
It is currently working on hover, however when i go back to the image that it plays under it doesnt go back to the beginning, it continues playing
The <embed> tag is the old way to embed multimedia. You really ought to be using the new HTML5 <audio> or <video> tags as they are the preferred and standardized way to embed multimedia objects. You can use the HTMLMediaElement interface to play, pause, and seek through the media (and lots more).
Here is a simple example that plays an audio file on mouseover and stops it on mouseout.
HTML:
<p onmouseover="PlaySound('mySound')"
onmouseout="StopSound('mySound')">Hover Over Me To Play</p>
<audio id='mySound' src='http://upload.wikimedia.org/wikipedia/commons/6/6f/Cello_Live_Performance_John_Michel_Tchaikovsky_Violin_Concerto_3rd_MVT_applaused_cut.ogg'/>
Javascript:
function PlaySound(soundobj) {
var thissound=document.getElementById(soundobj);
thissound.play();
}
function StopSound(soundobj) {
var thissound=document.getElementById(soundobj);
thissound.pause();
thissound.currentTime = 0;
}
For more information, check out the MDN guide for embedding audio and video
I had the same question, about starting and stopping audio. I use jQuery without any other plugins. My code is for mousedown and mouseup, but could be changed to other actions.
HTML
<div class="soundbutton">
cool wind sound
</div>
<audio id="wind-sound" src="wind-sound/wind.mp3">
Javascript
$('.soundbutton').on('mousedown', function () {
playWind(); //start wind sound
})
.on('mouseup', function () {
stopWind(); //stops the wind sound
});
// my full functions to start and stop
function playWind () { //start wind audio
$('#wind-sound')[0].volume = 0.7;
$('#wind-sound')[0].load();
$('#wind-sound')[0].play();
}
function stopWind () { //stop the wind audio
$('#wind-sound')[0].pause();
$('#wind-sound')[0].currentTime = 0; //resets wind to zero/beginning
}
<html>
<script>
function stopAudio() {
player.pause();
player.currentTime = 0;
}
</script>
<body>
<audio id="player" src="(place audio here)"></audio>
<div>
<button onclick=" stopAudio()">Stop</button>
</div>
</body>
</html>
//End Note: you must look at your audio id as mine is named "player"
this is the reason it is not working look at your css and your html
very closely in your lines. The other thing you must be careful about
is your call function as mine is stated as stopAudio() yours could be
named different. The function only works with css if you use your call
method properly.
I have a little html5 application where you can play a sound by clicking a button.
I have a function that adds an <audio> tag to a <div> with an id "playing." The sound removes itself when it is done.
function sound(track){
$("#playing").append("<audio src=\"" + track + "\" autoplay onended=\"$(this).remove()\"></audio>");
}
For the button I have:
<button onclick="sound('sounds/tada.mp3')">Tada</button>
When I click the button, an <audio> briefly appears in the element inspector and disappears when it is finished, just the way I want it, but after triggering it two times, it just stops working in Chrome, at least. There are no errors in the console either.
What is going on?
Get rid of the onclick/onend in your HTML and reference the button in your js:
HTML
<button id='tada' sound_url='sounds/tada.mp3'>Tada</button>
And the JS
var sound = function(track){
$("#playing").append("<audio id='played_audio' src='\" + track + \"' autoplay='true'></audio>");
}
$('#tada').on('click', function () {
var sound_url = $(this).attr('sound_url');
sound(sound_url);
});
$('#playing').on('end', 'played_audio', function() {
$(this).remove();
});
Okay, lets see..
var audioURL = "http://soundbible.com/mp3/Canadian Geese-SoundBible.com-56609871.mp3";
var audioEl = null;
function removeAudio() {
if (audioEl && audioEl.parentNode)
audioEl.parentNode.removeChild(audioEl);
}
function sound() {
removeAudio();
audioEl = document.createElement("audio");
audioEl.src = audioURL;
audioEl.controls = true;
audioEl.addEventListener("ended", removeAudio); // <-- Note it's ended, not end!
document.getElementById("playing").appendChild(audioEl);
audioEl.play();
}
document.getElementById("tada").addEventListener("click", sound);
<div id="playing">
</div>
<button id="tada">Tada</button>
I'm not seeing any problems with this script.
Decide audioURL, set audioEl to null as it will be used later
When the element with ID "tada" is clicked, run our sound function.
Remove the audio.
Create the audio element.
When the audio is finished, remove the audio.
Append the audio to the element with ID "playing".
Play the audio.
One thing to note is that I use the ended event, not the end event.
(This answer is here because Andrew really wants us to answer it.)