My Problem: I would like a user to hear a sound of some sort if a number is over 100.
If (x > 100) { play sound }
How would I go about this using html5/javascript. Is it possible to play sound without having an inline little video clip. The only stuff I've seen thus far has those little quicktime players embedded within the page: http://www.w3schools.com/html/html_sounds.asp
Hopefully there's a better solution? Thanks
Use an <audio> element.
var foo = document.createElement('audio');
foo.src = 'https://dl.dropbox.com/u/8090976/Matrix%20Ring.aiff';
if (x > 100)
{
document.getElementById('foo').play();
}
Demo: http://jsfiddle.net/mattball/ZcRt9/
More reading: http://html5doctor.com/native-audio-in-the-browser
Related
I'm wondering if we can make audio in html without the tag. perhaps we could have buttons for play and pause but still I don't know how to control volume, etc. I searched up other websites, And couldn't find the answer.
thanks,
Smit
You can use javascript to dynamically edit the attributes of audio.
Here is a list of functions:
myaudio.play(); - This will play the music.
myaudio.pause(); - This will stop the music.
myaudio.duration; - Returns the length of the music track.
myaudio.currentTime = 0; - This will rewind the audio to the beginning.
myaudio.loop = true; - This will make the audio track loop.
myaudio.muted = true; - This will mute the track
Like this there are many functions, please go through the documentation at W3C.
You can use tag to add the audio in your website. It comes with the Controls attribute as well.
This website might be helpful for you:
http://www.webreference.com/js/column20/control.html
I am trying to figure out how to continuously play random audio sound bites, one after another without having them overlap on an HTML page using jquery. I have code that plays random sound bites on a timer, but sometimes they overlap and sometimes there is a pause in between the sounds. I had looked into ended and other EventListeners but I really have no idea what I am doing. Here is a portion my code:
<html>
<audio id="audio1">
<source src="cnn.mp3"></source>
</audio>
<audio id="audio2">
<source src="sonycrackle.mp3"></source>
</audio>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('audio').each(function(){
this.volume = 0.6;
});
var tid = setInterval(playIt, 2000);
});
function playIt() {
var n = Math.ceil(Math.random() * 2);
$("#audio"+n).trigger('play');
};
Is there a way to just continuously play these sounds bites one after another right after the previous sound plays? FWIW I have many sound bites but I am just showing two above for reference.
So I dabbled a bit, here's a full pure JavaScript solution.
Should be cross-browser, haven't tested (/lazy). Do tell me if you find bugs though
var collection=[];// final collection of sounds to play
var loadedIndex=0;// horrible way of forcing a load of audio sounds
// remap audios to a buffered collection
function init(audios) {
for(var i=0;i<audios.length;i++) {
var audio = new Audio(audios[i]);
collection.push(audio);
buffer(audio);
}
}
// did I mention it's a horrible way to buffer?
function buffer(audio) {
if(audio.readyState==4)return loaded();
setTimeout(function(){buffer(audio)},100);
}
// check if we're leady to dj this
function loaded() {
loadedIndex++;
if(collection.length==loadedIndex)playLooped();
}
// play and loop after finished
function playLooped() {
var audio=Math.floor(Math.random() * (collection.length));
audio=collection[audio];
audio.play();
setTimeout(playLooped,audio.duration*1000);
}
// the songs to be played!
init([
'http://static1.grsites.com/archive/sounds/background/background005.mp3',
'http://static1.grsites.com/archive/sounds/background/background006.mp3',
'http://static1.grsites.com/archive/sounds/background/background007.mp3'
]);
Some quick suggestions is add the attribute preload="auto" to the audio element and change the script to be $(window).onload instead of document ready. Document ready fires when html is in place but not necessarily when audio and other assets (like images) have loaded.
You could also look into using the AudioBuffer Interface in the new Web Audio API, it's described as "this interface represents a memory-resident audio asset (for one-shot sounds and other short audio clips)." which sounds like what you need. I believe part of the issues you're having (random pauses/delays/sound glitches with the audio element) are one of the reasons why it's being developed.
Read more here:
https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioBuffer
Unfortunately it's only Chrome and lastest Safari supported with Firefox support supposedly in the next 6(ish) months and no word yet on IE support.
Having
var audio = new Audio("click.ogg")
I play the click sound when needed by
audio.play()
However, sometimes user is so fast that a browser does not play the audio at all (probably when still playing a previous play request). Is this issue related to preload?
How can I force a browser to stop playing and start over? There is no stop, just pause in HTML5 audio component, correct? What workaround can be used here?
Update - Additional note:
I have multiple checkbox-like div elements with a touchend event. When such event is triggered, the elements visually change, a sound is played and an internal variable is set accordingly. If user tap on these elements slowly, everything works nicely. If tap fast, the sound is often completely skipped...
The simplest solution is to just reset the audio currentTime and ensure it's playing using the play() method. Checking if the audio is playing is not necessary as subsequent play() invocations will not do anything.
audio.currentTime = 0;
audio.play();
This is the code I've been using and it's working for me:
if(audioSupport.duration > 0 && !audioSupport.paused){
//already playing
audioSupport.pause();
audioSupport.currentTime = 0;
audioSupport.play();
}else{
//not playing
audioSupport.play();
}
I noticed that on Firefox, playing a sound again and again really fast (like a short ticking sound) will skip beats often. The best solution I got was to simply call cloneNode and play each sound that way. Its not perfect (compared to Chrome where it sounds flawless):
var audio = document.getElementById('myaudio');
setInterval(function() {
audio.cloneNode().play();
}, 100);
The only way i found how to play a short sound very quickly (so quick that the 2nd sound starts before the first ends) is to actually load 5 or 10 and if you have to play again but are already playing, just go to the next, which is not playing:
var soundEls = [];//load 10 audios instead of 1
for(var i=0;i<10;i++){
var soundEl = document.createElement('audio');
soundEl.src = url;
soundEl.preload = 'auto';
$(this._soundEl).append(soundEl);
soundEls.push(soundEl);
}
var soundElIndex = 0;
return {play:function(){
var soundEl = soundEls[soundElIndex];
if(soundEl.duration > 0 && !soundEl.paused){
//already playing, switch to next soundEl
soundElIndex++;
if(!soundEls[soundElIndex]) soundElIndex=0;
soundEls[soundElIndex].play();
}else{
//not playing
soundEl.play();
}
}};
Result of this is you can actually play the same sound over itself.
Probably not the right way to do it though.
Is it possible to seek to a particular point in html5 video displayed in a web page? I mean ,can I input a particular time value (say 01:20:30:045 ) and have the player control (slider) move to that point and play from that point onwards?
In older version of mozilla vlcplugin I think this is possible by seek(seconds,is_relative) method..but I would like to know if this is possible in html video.
Edit:
I created the page with video and added javascript as below.When I click on the link ,it displays the time of click..but it doesn't increment the play location..but continues to play normally.
Shouldn't the video play location get changed?
html
<video id="vid" width="640" height="360" controls>
<source src="/myvid/test.mp4" type="video/mp4" />
</video>
<a id="gettime" href="#">time</a>
<p>
you clicked at:<span id="showtime"> </span>
</p>
javascript
$(document).ready(function(){
var player = $('#vid').get(0);
$('#gettime').click(function(){
if(player){
current_time=player.currentTime;
$('#showtime').html(current_time+" seconds");
player.currentTime=current_time+10;
}
});
}
);
You can use v.currentTime = seconds; to seek to a given position.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/currentTime
Unfortunately it seems with some movie elements it behaves differently than others. For instance with an amazon video_element, it seems you must call pause before you can seek anywhere, then call play. However, if you call play "too quickly" after setting the currentTime then it won't stick. Odd.
Here is my current work around:
function seekToTime(ts) {
// try and avoid pauses after seeking
video_element.pause();
video_element.currentTime = ts; // if this is far enough away from current, it implies a "play" call as well...oddly. I mean seriously that is junk.
// however if it close enough, then we need to call play manually
// some shenanigans to try and work around this:
var timer = setInterval(function() {
if (video_element.paused && video_element.readyState ==4 || !video_element.paused) {
video_element.play();
clearInterval(timer);
}
}, 50);
}
Top answer is outdated.
You can still use:
this.video.currentTime = 10 // seconds
But now you also have:
this.video.faskSeek(10) // seconds
The docs provide the following warnings regarding the fastSeek method:
Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.
The HTMLMediaElement.fastSeek() method quickly seeks the media to the new time with precision tradeoff.
If you need to seek with precision, you should set HTMLMediaElement.currentTime instead.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/fastSeek
Based on the above I guess the following is best if cross browser compatibility and performance are your top priority:
const seek = secs => {
if (this.video.fastSeek) {
this.video.fastSeek(secs)
} else {
this.video.currentTime = secs
}
}
seek(10)
If you prefer accuracy over performance then stick with:
this.video.currentTime = secs
At the time of writing faskSeek is only rolled out to Safari and Firefox but expect this to change. Check the compatibility table at the above link for the latest info on browser compatibility.
I've been looking for a solution where i can "scrub" through HTML5 video. I haven't found one yet and was about to start writing my own. But before i do that, i thought it would make some sense to run it past SO first.
Before we get into my approach, see this:
http://www.kokokaka.com/demo/bluebell_ss10/site
This site of course is built in Flash but serves as an example of what i would like to achieve using HTML5.
I've experimented with the playbackRate (-1) attribute on the video tag without much luck. I suspect this is because the encoding (ogg, mp4, vp8) are better suited to forward playback.
with this, i see two possible approaches:
create two videos, one for forward play, and another for backwards play. this of course doubles the size of any videos which is not ideal.
split the video into individual jpg frames and swap out the images. This would mean i have no sound, but in my particular application, this is not an issue.
I feel that the second option is the best suited for my particular application and allows for some flexibility in playback. What do you think?
Generate a bunch of thumbnails of your video by any means.
Once you have all of your thumbs from the video, you could use something like this, which detects mouse movement and replaces the thumbnail based on the movement -- hover scrubbing.
Example 1: http://codepen.io/simsketch/pen/gwJBRg
Example 2: http://jsfiddle.net/simsketch/x4ko1x1w/
or for something less verbose, if you want to horizontally concatenate all the thumbnail images into a sprite, you can use this, another beautiful example of the hover scrub.
http://jsfiddle.net/simsketch/r6wz0nz6/152/
but you would need to bind the event to mousedown instead of mousemove
this doesn't really give you the desired effect so you would need to combine mousedown and mousemove as is suggested here: https://stackoverflow.com/a/1572688/1579789
this would somewhat give you the effect you're looking for, but without using HTML5 video, and without sound.
however, you could add sound as well if you bind the mouse movement to a timecode in the audio track i suppose. at that point, you could probably just as easily manipulate a video track instead.
i think what you want can be done with popcornjs, available at popcornjs.org
I happened to find this question today after the featured story on the Google homepage was this, which features a video scrubber.
I'd never seen a video scrubber before and was blown away!
Then I found https://www.emergeinteractive.com/demos/javascript-video-scrubber/, which describes how to achieve it.
These folks may have invented this concept for Nike years ago.
They offer a code snippet and a link to Github:
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
(function animloop(){
requestAnimFrame(animloop);
targetStep = Math.max( Math.round( getYOffset() / 30 ) , 1 ); // what frame to animate to
if(targetStep != step ) { step += (targetStep - step) / 5; } // increment the step until we arrive at the target step
changeFrame();
})();
function changeFrame() {
var thisStep = Math.round(step); // calculate the frame number
if(images.length > 0 && images[thisStep]) { // if the image exists in the array
if(images[thisStep].complete) { // if the image is downloaded and ready
$('#video').attr('src',images[thisStep].src); // change the source of our placeholder image
}
}
}