Javascript -HTML5 audio controls when song is selected - javascript

Hi this is currently my code to play a song according to which image is selected:
Javascript
function Start (audioFile)
{
var audie = document.getElementById("myAudio");
audie.src = audioFile;
audie.play();
}
function Stop ()
{
var audie = document.getElementById("myAudio");
audie.pause();
}
HTML5
<img src="images/play.png" alt="Play Button width="37" height="30" onclick="Start('EL.mp3')">
How is it that i could show the HTML 5 audio player with all the controls as soon as the button is selected ? I would like to just have one control bar and everytime the playbutton is clicked the bar appears and maybe display the song that is currently playing .

First, i suggest using jquery for writing JavaScript.
HTML
<audio controls id="myAudio" style="display:none">
JavaScript
function Start (audioFile)
{
$("#myAudio").show();
...
}
function Stop ()
{
$("#myAudio").hide();
...
}

Related

Calling src from nearest audio tag to JavaScript function without ID

I'm attempting to play multiple locally stored mp3 files on a single html page. I want a single JavaScript function in a separate js file triggered onclick that will play the correct file referenced in the adjacent audio tag. The audio just needs to play through once every time it is tapped/clicked.
I've tried using querySelector and various other techniques to find the nearest audio tag, but it always defaults to the audio tag at the top of the page. How can I limit the scope of querySelect, or is there another method of doing what I want? I don't want to have to create a unique ID for every audio tag because there are dozens of pages like this I am making.
function PlaySound() {
var sound = document.querySelector(".audio");
sound.play()
}
<audio class="audio" src="../../audio/na.mp3" autostart="false"></audio><a onclick="PlaySound()">나</a>
<audio class="audio" src="../../audio/gak.mp3" autostart="false"></audio><a onclick="PlaySound()">각</a>
First of all, you should use a button, not an anchor tag for these. They are buttons, since they only do an action on the page. Links are something that takes you to another page.
Now for your issue: when an event listener is invoked, such as your PlaySound when onclick happens, you can give it a this argument, which is the DOM instance of the button clicked.
Now your audio is a simple previousElementSibling away from grabbing, meaning and you can easily invoke audio.play() on it.
function play (button) {
console.log('Button:', button.innerText)
const audio = button.previousElementSibling
console.log('Audio', audio)
}
<audio src="1"></audio>
<button onclick="play(this)">1</button>
<audio src="2"></audio>
<button onclick="play(this)">2</button>
What you could do is store the information that are held by the audio tags inside a JavaScript array and dynamically create the list of audio and the respective buttons.
var audioList = [{
src: "../../audio/na.mp3",
text: "나"
}, {
src: "../../audio/gak.mp3",
text: "각"
}];
var container = document.querySelector("#container");
audioList.forEach(function(audio) {
var audioElem = document.createElement("audio");
var button = document.createElement("button");
audioElem.setAttribute("autostart", false);
audioElem.setAttribute("src", audio.src);
button.textContent = audio.text;
audioElem.className = "audio";
button.addEventListener("click", getButtonListener(audioElem));
container.appendChild(audioElem);
container.appendChild(button);
});
function getButtonListener(audioElem) {
return function() {
audioElem.play();
console.log("Playing:" + audioElem.src);
};
}
<div id="container"></div>
Or you could just do:
var audioList = {
"나": "../../audio/na.mp3",
"각": "../../audio/gak.mp3"
};
function openAudio(target){
document.querySelector("audio[src='" + audioList[target.textContent] + "']").play();
console.log("Playing: " + audioList[target.textContent]);
}
<audio class="audio" src="../../audio/na.mp3" autostart="false"></audio>
<button onclick="openAudio(this)">나</button>
<audio class="audio" src="../../audio/gak.mp3" autostart="false"></audio>
<button onclick="openAudio(this)">각</button>

How to randomize video on click and on page load

I have been scratching my head for a few days now with this one. Just trying to get better at javascript but no one seems to be able to figure out what I am doing wrong here.
What I want is to create a data structure or array containing videos
On page load I would like a random video to be loaded and begin playing
After this I would like the user to be able to click the video to initiate the math.random and generate a new video in its place.
Issues -
1 - With the code I have whenever I click to randomize the video just disappears no console errors or anything.
2 - The page doesn't randomize on load
3 - I am not sure if this is the best way to go about as far as data structure is concerned?
This doesn't seem logically like a hard problem to solve but for me its been a real head scratcher.
Any help is greatly appreciated!!
HTML
<a href="#" class="click">
<section>
<div>
<video loop autoplay>
<source src="videos/1.webm" type="video/ogg">
<source src="videos/1.mp4" type="video/mp4">
Your browser does not support the <code>video</code> element.
</video>
</div>
</section>
</a>
JavaScript
//Array of Videos
var videos = [
[{type:'mp4', 'src':'videos/1.mp4'}, {type:'webm', 'src':'videos/1.webm'}],
[{type:'mp4', 'src':'videos/2.mp4'}, {type:'webm', 'src':'videos/2.webm'}],
];
//onClick + Action
$(function() {
$('a.click').click(function(e) {
e.preventDefault();
var randomIndex = parseInt(Math.random()*videos.length);
$(this).find('videos').append('<source src="'+videos[randomIndex]+'" />');
});
});
//onLoad Randomize
function getRandomVideo() {
var number = Math.floor(Math.random()*video.length);
document.write('<source src="'+videos[number]+'" />');
}
$(function() {
$('a.click').click(function(e) {
e.preventDefault();
console.log("hello world");
var number = Math.floor(Math.random()*videos.length);
$(this).html('<source src="'+videos[number]+'" />');
});
});
Here is working pen http://codepen.io/easingthemes/pen/PwWRdx
<a> tag will break on some browsers around block elements. You don't need <a>.
You need videos[number][index].src because videos[number] is an object.
Also you need to reload video when you change src
$('video').load();
$('video').play();
HTML
<section>
<div>
<video loop autoplay>
<source src="http://html5demos.com/assets/dizzy.mp4" type="video/mp4">
<source src="http://techslides.com/demos/sample-videos/small.webm" type="video/ogg">
Your browser does not support the <code>video</code> element.
</video>
</div>
</section>
JS
var videos = [
[{type:'mp4', 'src':'http://techslides.com/demos/sample-videos/small.mp4'}, {type:'webm', 'src':'http://techslides.com/demos/sample-videos/small.webm'}],
[{type:'mp4', 'src':'http://html5demos.com/assets/dizzy.mp4'}, {type:'webm', 'src':'http://html5demos.com/assets/dizzy.webm'}],
];
$(function() {
$('section').on('click', 'div', function(e) {
var number = Math.floor(Math.random()*videos.length);
$(this).find('source').each(function(index){
videoSrc = videos[number][index].src;
$(this).attr('src', videoSrc);
$('video').load();
$('video').play();
});
});
});
Ok this is an array of array of objects this is a function to change the 1st and second src and type
function getRandomVideo(videos) {
var number = Math.floor(Math.random()*videos.length);
$('.click video source').eq(0).attr('type',videos[number][0].type).attr('src',videos[number][0].src);
$('.click video source').eq(1).attr('type',videos[number][1].type).attr('src',videos[number][1].src);
$('.click video').load();
$('.click video').play();
}
DEMO use this function in any event you want

Javascript move multiple elements to separate div's and back

There are 3 videos, placed in 3 separate div's.
There also are 3 separate div's, but in other position of a page (lets say contA and contB and contC).
I want that if I click on the video1, then video2 and video3 goes to contA and contB, and video1 goes to contC.
If I click video1 again, all videos go back to their original position.
If I click on video2 (while its in contA), then video1 goes to contA, video3 goes to contB, video2 goes to contC.
I have prepared a jsbin demo:
Jsbin DEMO
Anyone could help? Appreciated!
EDIT: (Added a code as requested)
HTML:
<div id="vid1">
<video id="Video1" class="videos">
<source src="http://www.craftymind.com/factory/html5video/BigBuckBunny_640x360.mp4" type="video/mp4"></source>
HTML5 Video is required for this example.
</video>
</div>
<div id="vid2">
<video id="Video2" class="videos">
<source src="http://www.craftymind.com/factory/html5video/BigBuckBunny_640x360.mp4" type="video/mp4"></source>
HTML5 Video is required for this example.
</video>
</div>
<div id="vid3">
<video id="Video3" class="videos">
<source src="http://www.craftymind.com/factory/html5video/BigBuckBunny_640x360.mp4" type="video/mp4"></source>
HTML5 Video is required for this example.
</video>
</div>
<div id="contA"><br>first container<br></div>
<div id="contB"><br>second container<br></div>
<div id="contC"><br>third container<br></div>
JavaScript:
$(window).load(function()
{
//add event for all videos
$('.videos').click(videoClicked);
function videoClicked(e)
{
//get a referance to the video clicked
var sender = e.target;
//get all the videos
var $videos = $('.videos');
$videos.appendTo('#contA');
$videos.appendTo('#contB'); //but I need each video to be put to different div: #contA, #contB...
$videos.not(sender).appendTo('#contC'); //if I put the clicked video into this container, it does not go back to original one.
}
});
Think this is what you're looking for, but it's based on the naming convention used in the example. I also took the liberty of renaming contA/contB and contC to cont1, cont2 and cont3, because it's easier to manipulate.
JSBin demo
//remember last video clicked (you could check last container instead)
var lastclicked;
function videoClicked(e)
{
//get a reference to the video clicked
var sender = e.target;
//get all the videos
var $videos = $('.videos');
if(sender==lastclicked){
//reset to original positions
$.each($videos,function(){
var ind = this.id.substring(this.id.length-1); //based on the video + number naming convention
$(this).appendTo('#vid' + ind);
});
lastclicked = null;
return;
}
lastclicked= sender;
var i = 1;
//place all non clicked videos in cont1/cont2/etc
$.each($videos.not(sender),function()
{
$(this).appendTo('#cont' + i++ );
});
//place the clicked video in the last container
$(sender).appendTo('#cont' + i ); //always cont3 with fixed divs, but this is dynamic in case you add more
}
});
I will edit this answer as the desired results become more clear but i think i can give you some info to get you going in the right direction.
the section of code "but i need each video to be put to a diff cont"
I would leverage a data attribute and let each control keep track of itself.
$video.each(function()
{
var targetdiv = $(this).data('origonal-div');
$(targetdiv.ToString()).append(this);
//optionally update the data value to keep track of the next location to append to.
}
if you need more info post some questions with an update on the jsbin so i can see where you are having trouble.
Cheers

Javascript - onclick, play sound, wait x seconds, load URL

At the moment I have an image linked to a page with an onClick event to play a sound when clicked.
<div style="display:none;">
<audio id="audio1" src="SOUND.wav" controls preload="auto" autobuffer></audio>
</div>
<script> function EvalSound(soundobj)
{ var thissound=document.getElementById(soundobj); thissound.play(); }
</script>
<img src="IMAGE.png">
This works fine as is, but the sound is cut off by the page load. Assuming the "SOUND.wav" is 10 seconds long, how would I edit my code so that when the image is clicked, there is a 10 second pause while the sound plays, THEN it loads the page?
Thank you or your help.
You can change your code as follows:
<div style="display:none;">
<audio id="audio1" src="SOUND.wav" controls preload="auto" autobuffer></audio>
</div>
<script> function EvalSound(soundobj)
{ var thissound=document.getElementById(soundobj); thissound.play();
setTimeout( function() { window.location.href = 'PAGE.php'; }, 1000); } // change 1000 to whatever value you would want to wait in milliseconds.
</script>
<a href="#" onClick="EvalSound('audio1')"><img src="IMAGE.png"></a
>
Same as the answer before me, only I suggest you use the audio api to determine the duration of the sound and set it as the timeout.
Also, to change the url you could add it as an argument.
function EvalSoundAndRedirect(soundobj, url) {
var thissound = document.getElementById(soundobj);
thissound.play();
setTimeout(function() {
window.location.href = url;
}, thissound.duration);
}
Using:
<img src="IMAGE.png" />

Vimeo API: Play button and multiple videos

I'm having some trouble. I just discovered that you can control vimeo with js, and now I'm trying to create a play button that will start playing a vimeo video.
The problem I'm having is that I have multiple videos on the same page. I took the example/playground file (from here http://player.vimeo.com/playground / https://github.com/vimeo/player-api/tree/master/javascript) and removed the functionality that I don't require, however, I can't understand how I connect the play button with a certain video.
This is what I have so far
HTML:
<iframe id="player_1" src="http://player.vimeo.com/video/7100569?api=1&player_id=player_1" width="540" height="304" frameborder="0"></iframe>
<div class="intro">
<span class="hide">Play 1</span>
</div>
<iframe id="player_2" src="http://player.vimeo.com/video/7100569?api=1&player_id=player_2" width="540" height="304" frameborder="0"></iframe>
<div class="intro">
<span class="hide">Play 2</span>
</div>
JS:
var vimeoPlayers = document.querySelectorAll('iframe'),
player;
for (var i = 0, length = vimeoPlayers.length; i < length; i++) {
player = vimeoPlayers[i];
$f(player).addEvent('ready', ready);
}
function addEvent(element, eventName, callback) {
if (element.addEventListener) {
element.addEventListener(eventName, callback, false);
}
else {
element.attachEvent(eventName, callback, false);
}
}
function ready(player_id) {
// Keep a reference to Froogaloop for this player
var container = document.getElementById(player_id).parentNode.parentNode,
froogaloop = $f(player_id);
function setupSimpleButtons() {
var buttons = container.querySelector('div.intro'),
playBtn = buttons.querySelector('.hide');
// Call play when play button clicked
addEvent(playBtn, 'click', function() {
froogaloop.api('play');
}, false);
}
setupSimpleButtons();
}
})();
If I have code that is unnecessary please help me remove it.
Many thanks.
Your ready() function is called once per vimeo player. You need to change which object is hooked up with the addEvent button. To do this you probably need to put id attributes on the buttons themselves.
I figured out a way to do this much easier, you can see an example here:
http://labs.funkhausdesign.com/examples/vimeo/froogaloop2-api-basics.html

Categories

Resources