I have an image that plays and stops the track perfectly. I am trying to alternate the image source from play.png to pause.png depending on if the track is playing or not.
Here's the code I have that is working to start/stop the audio, only with a static play.png image. How can I change the src attribute using javascript between pause.png and play.png?
<img src='play.png' onclick="aud_play_pause()">
<audio id="audio1">
<source src="audio1.mp3" type="audio/mp3">
</audio>
<script>
var myAudio=document.getElementById("audio1");
function aud_play_pause(){
if (myAudio.paused){
myAudio.play();
} else {
myAudio.pause();
}
}
</script>
You'll want to use javascript's DOM manipulation functions to change this like so:
var myAudio = document.getElementById("audio1");
var image = document.getElementsByTagName("img")[0];
function aud_play_pause(){
if (myAudio.paused){
myAudio.play();
image.setAttribute("src", "pause.png");
} else {
myAudio.pause();
image.setAttribute("src", "play.png");
}
}
Although it is better to reference the img element by its ID, I used its tag name since it was the only one there.
Related
I'm testing on building a site locally on my machine using bootstrap.
I have a <video> sort of as the header of the site.
I would like this video to show the full width and height on mobile, and show a cropped/wide version of the video on desktop. I tried using inline media queries in the <source> tags, so that the src would change but nothing would work.
So I switched gears and used some javascript to change it that way.
So the crazy thing is, it seems my script works. When I look in chrome dev tools, the srcdoes in fact change when I resize my browser screen, however, it does not reflect on the site itself, it keeps whatever src I set it to in the html, as if it is ignoring my script.
I have tried everything I could think of, and I'm just stuck, not sure how to go about it any further. My code is below:
HTML
<video class="col-12" loop muted autoplay >
<source id="hvid" src="media/test.mp4" type="video/mp4">
</video>
JS
let homeVideo = document.getElementById('hvid')
console.log(homeVideo.src)
function myFunction(x) {
if (x.matches) { // If media query matches
homeVideo.src = "media/test.mp4";
} else {
homeVideo.src = "media/test-3.mp4";
}
}
var x = window.matchMedia("(max-width: 700px)")
myFunction(x) // Call listener function at run time
x.addListener(myFunction) // Attach listener function on state changes
;
console.log(homeVideo.src)
-Edits-
JS
var w = window.matchMedia("(max-width: 700px)");
var vid = document.getElementById("vid");
var source = document.getElementById("hvid");
window.addEventListener("resize", function screenres(){
if (w.matches) {
vid.pause();
source.src = "media/test.mp4";
vid.load();
vid.play();
} else {
vid.pause();
source.src = "media/test-3.mp4";
vid.load();
vid.play();
};
});
HTML
<div class="container">
<div class="row">
<video id="vid" class="col-12" loop muted autoplay>
<source id="hvid" src="media/test.mp4" type="video/mp4">
</video>
</div>
</div>
Just get the viewport size, and based on that value, pause the video, change the src link, load the new video and play the new video.
But do note that you will need to refresh the page after changing the browser size to see the video change.
If you want the video to change whenever the screen resizes as well as on page refresh, you will first need to move the above JavaScript to a function and run it when a resize event is fired. Then, for the page load, you need to remove the video element from your HTML and add it on page load using the createElement() method with the src attribute value also added depending on the viewport width.
Check this JSFiddle or run the following Code Snippet for a practical example of what I have described above:
/* JavaScript */
var w = window.matchMedia("(max-width: 700px)");
var vid = document.getElementById("vid");
var source = document.createElement("source");
source.id = "hvid";
source.setAttribute("type", "video/mp4");
vid.appendChild(source);
if (w.matches) {
vid.pause();
source.removeAttribute("src");
source.setAttribute("src", "https://storage.googleapis.com/coverr-main/mp4/Love-Boat.mp4");
vid.load();
vid.play();
} else {
vid.pause();
source.removeAttribute("src");
source.setAttribute("src", "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4");
vid.load();
vid.play();
}
window.addEventListener("resize", function(){
var w = window.matchMedia("(max-width: 700px)");
var vid = document.getElementById("vid");
var source = document.getElementById("hvid");
if (w.matches) {
vid.pause();
source.src = "https://storage.googleapis.com/coverr-main/mp4/Love-Boat.mp4";
vid.load();
vid.play();
} else {
vid.pause();
source.src = "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4";
vid.load();
vid.play();
}
});
/* CSS */
html, body {margin: 0; padding:0; width: 100%; height: 100%;}.row{display: block !important;}
<!-- CDN Links -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/><link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<!-- HTML -->
<div class="container">
<div class="row">
<video id="vid" class="col-12" loop muted autoplay></video>
</div>
</div>
I am working on a project where a sound plays when you mouseover an image and stops playing on mouseout. I want it to start over each time and there has to be multiple images on each page. I am looking for the most efficient way to make this code work. Here is the sample page: http://inventivewebdesign.com/audio-img/sound.html
Code:
<body>
<script>
function PlaySound(soundobj) {
var thissound=document.getElementById(soundobj);
thissound.play();
}
function StopSound(soundobj) {
var thissound=document.getElementById(soundobj);
thissound.pause();
thissound.currentTime = 0;
}
</script>
<a onmouseover="PlaySound('violin')" onmouseout="StopSound('violin')"><img src="violin.png"></a>
<a onmouseover="PlaySound('xy')" onmouseout="StopSound('xy')"><img src="xy.png" width="300px" height="300px"></a>
<a onmouseover="PlaySound('piccolo')" onmouseout="StopSound('piccolo')"><img src="piccolo.png"></a>
<audio id='piccolo' src='piccolo.wav'/>
<audio id='violin' src='violin.mp3'/>
<audio id='xy' src='xy.mp3'/>
</body>
This all works. My only question is how to make the code more efficient.
I saw that I should be able to do something like this:
<audio>
<source id='piccolo' src='piccolo.wav'>
<source id='violin' src='violin.mp3'>
<source id='xy' src='xy.mp3'>
</audio>
But it doesn't work. Is the first set of code above the best way to do it?
Good question #MattM. I would simply add a function to create new instances of the audio hovers, making make it easier to implement more sounds without code repetition.
function newHover(e){
var audio = new Audio(); // creates audio element
audio.src = e.audio; // the audios location
var image = new Image(); //creates the image element
image.src = e.image; // the images location
image.className = e.title; // applies the name of the instrument to both elements
audio.className = e.title;
image.addEventListener("mouseover", PlaySound); // listens for mouse movement
image.addEventListener("mouseout", StopSound);
document.body.appendChild(audio); // appends the audio and image to the body of the document
document.body.appendChild(image);
}
That way, the below code block is unnecessary:
<a onmouseover="PlaySound('violin')" onmouseout="StopSound('violin')">
<img src="violin.png">
</a>
<a onmouseover="PlaySound('xy')" onmouseout="StopSound('xy')">
<img src="xy.png" width="300px" height="300px">
</a>
<a onmouseover="PlaySound('piccolo')" onmouseout="StopSound('piccolo')">
<img src="piccolo.png">
</a>
<audio id='piccolo' src='piccolo.wav'/>
<audio id='violin' src='violin.mp3'/>
<audio id='xy' src='xy.mp3'/>
Implement this in your code, none of the HTML above is needed in this solution.
(Note: getElementById was changed to querySelector in PlaySound and PauseSound functions)
function PlaySound(e) {
var thissound = document.querySelector("audio." + e.target.className);
thissound.play();
}
function StopSound(e) {
var thissound = document.querySelector("audio." + e.target.className);
thissound.pause();
thissound.currentTime = 0;
}
function newHover(e){
var audio = new Audio();
audio.src = e.audio;
var image = new Image();
image.src = e.image;
image.className = e.title;
audio.className = e.title;
image.addEventListener("mouseover", PlaySound);
image.addEventListener("mouseout", StopSound);
document.body.appendChild(audio);
document.body.appendChild(image);
}
window.onload = function(){
newHover({
audio: "http://inventivewebdesign.com/audio-img/piccolo.wav", // Path to the audio file (the src property of audio tag)
image: "http://inventivewebdesign.com/audio-img/piccolo.png", // Path to the image file (the src property of the image tag)
title: "piccolo" // The name of the instrument (applied as a className to both the image and the audio elements)
});
newHover({
audio: "http://inventivewebdesign.com/audio-img/xy.mp3",
image: "http://inventivewebdesign.com/audio-img/xy.png",
title: "xy"
});
newHover({
audio: "http://inventivewebdesign.com/audio-img/violin.mp3",
image: "http://inventivewebdesign.com/audio-img/violin.png",
title: "violin"
});
}
a{
position: absolute;
}
img{
width: 100px;
}
<body>
<a>Hover over the images!</a>
</body>
In conclusion, your solution works effectively, However it would make it much easier for you to have a function to create the audio hovers for you.
I took a look at inventivewebdesign.com, very nice website there!
EDIT>>>>>>>>>>>>
Note - I have tested the script in Firefox and Chrome. It should work fine.
For clarification on how to use the function:
To insert an image. Call the newHover function Like so:
newHover({
audio: /*audio src here eg. music.wav*/,
image: /*image src here eg. picture.png*/,
title: /*title here eg. violin / xylophone / piccolo*/
});
The images will be inserted into the document. You can then apply css styles or do what ever else you want to them.
Everything in my code works. It just doesn't switch to the next song/video after finishing the current one. I have tried adding an onended event handler (in the tag and in JavaScript) but failed. I also tried jQuery but it did't work. For some reasons it doesn't change songs at the end of the song. Instead, it will replay the same song over and over again.
<video id="vid" src="main/" playsinline autoplay loop>
<script>
var video = document.currentScript.parentElement;
video.volume = 0.1;
var lastSong = null;
var selection = null;
var playlist = ["main/songn.mp4", "main/songl.mp4", "/main/songt.mp4", "/main/songf.mp4"]; // List of Songs
var video = document.getElementById("vid");
video.autoplay=true;
video.addEventListener("ended", selectRandom);
function selectRandom(){
while(selection == lastSong){
selection = Math.floor(Math.random() * playlist.length);
}
lastSong = selection;
video.src = playlist[selection];
}
selectRandom();
video.play();
</script>
</video>
You just need to remove the loop parameter from the video tag if you want to trigger the end event (doc):
<video id="vid" src="main/" playsinline autoplay>
(Your code will handle the loop by loading a new song when one ended.)
BTW, keep var video = document.getElementById("vid"); to refer to your <video> tag, it's shorter and cleaner than the first declaration.
I'm using the following code to trigger fullscreen when a user clicks on the play button on a <video> element:
var video = $("#video");
video.on('play', function(e){
if (video.requestFullscreen) {
video.requestFullscreen();
} else if (video.mozRequestFullScreen) {
video.mozRequestFullScreen();
} else if (video.webkitRequestFullscreen) {
video.webkitRequestFullscreen();
}
});
But nothing happens when I click the play button.
Any idea's why?
EDIT: Here's my HTML code:
<video width="458" height="258" controls id='video' >
<source src='<?= bloginfo('template_directory'); ?>/inc/pilot.mp4' type="video/mp4">
<source src='<?= bloginfo('template_directory'); ?>/inc/pilot.ogv' type="video/ogg">
<source src='<?= bloginfo('template_directory'); ?>/inc/pilot.webm' type="video/webm">
</video>
There are a couple things going on here:
First, in your code, video is a jQuery object, not the actual video element. For a jQuery object, you can reference it like this:
var actualVideo = video[0]; // (assuming '#video' actually exists)
Second, for security and good user experience, browsers will only let you trigger full screen inside a user-triggered event, like a 'click'. You can't have every web page going to full screen as soon as you visit it, and you can cause a video to start playing automatically, which would violate that rule.
So an alternative solution would be to request fullscreen in a click event, like this:
var video = $("#video");
video.on('click', function(e){
var vid = video[0];
vid.play();
if (vid.requestFullscreen) {
vid.requestFullscreen();
} else if (vid.mozRequestFullScreen) {
vid.mozRequestFullScreen();
} else if (vid.webkitRequestFullscreen) {
vid.webkitRequestFullscreen();
}
});
Ideally, you'd probably want to build out a more complete player ui, but this should give you the general idea.
A less verbose way to toggle full screen combining answers from this and other questions.
This should handle all browser flavours: chromium- and webkit-based, firefox, opera, and MS-based browsers.
var p = document.querySelector('#videoplayer');
if (!window.isFs) {
window.isFs = true;
var fn_enter = p.requestFullscreen || p.webkitRequestFullscreen || p.mozRequestFullScreen || p.oRequestFullscreen || p.msRequestFullscreen;
fn_enter.call(p);
} else {
window.isFs = false;
var fn_exit = p.exitFullScreen || p.webkitExitFullScreen || p.mozExitFullScreen || p.oExitFullScreen || p.msExitFullScreen;
fn_exit.call(p);
}
p represents the DOM object of the video element, and window.isFs is just a random variable for storing the current fullscreen state.
If your player is a jQuery object then you can get the underlying DOM-element with var p = player.get(0).
I want to add a sound clip to a button on a game I am creating. Currently It doesn't do anything and I don't know why.
At the moment In the script I have...
var audio = $(".mysoundclip")[0];
$(".minibutton").onclick(function() {
audio.play();
});
In the HTML I have...
<audio id="mysoundclip" preload="auto">
<source src="http://www.wav-sounds.com/cartoon/bugsbunny1.wav"></source>
</audio>
Then I have CSS for .minibutton.
Any ideas why it won't work?
Your jQuery had some simple errors in it.
HTML
<audio id="mysoundclip" preload="auto">
<source src="http://www.wav-sounds.com/cartoon/bugsbunny1.wav"></source>
</audio>
<button type="button">play</button>
jQuery
var audio = $("#mysoundclip")[0];
$("button").click(function() {
audio.play();
});
Fiddle: http://jsfiddle.net/iambriansreed/VavyK/
Maybe I'm a too suspicous.. but
http://www.sound-effect.com/sounds1/animal/Saf/Tiger1.wav "The requested URL was not found on this server"
If that's just a typo, you should also try to figure out which audio types a browser is capable to play:
myApp.htmlAudio = (function _htmlAudioCheck() {
var elem = document.createElement('audio'),
bool = false;
try {
if( !!elem.canPlayType ) {
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"');
bool.mp3 = elem.canPlayType('audio/mpeg;');
bool.wav = elem.canPlayType('audio/wav; codecs="1"');
bool.m4a = ( elem.canPlayType('audio/x-m4a;') || elem.canPlayType('audio/aac;'));
}
} catch(e) { }
return bool;
}());
Now we can check like
if( myApp.htmlAudio && myApp.htmlAudio.wav ) {
}
if the browser is able to playback .wav files for instance.
However, I never saw a nested source element for audio elements. That should be named track if anything. But you don't really need that here, you can just have a src attribute on the audio element itself. Example: http://jsfiddle.net/5GUPg/1/