Why does audio not start when 'play' button is first clicked? - javascript

I'm having trouble with audio in Firefox. I have an .ogg audio clip in an <audio> tag, and Firefox does not start playing the file when the play button is fisrt pressed. However, if the play button is pressed and then a time is selected from the timeline, the audio will start playing from the time selected. The file will also start playing if the play button is pressed repeatedly (e.g. play/pause/play).
I'm also using the web audio API to run the audio through an AnalyserNode. The issue, however, does not seem to relate to the analyser specifically, as this can be removed without affecting this issue. It seems to have something to do with createMediaElementSource. If I remove the JavaScript code related to this, the issue disappears.
The audio file is being served from the same origin, so I'm fairly certain this is not a CORS issue (as described here). As I said, the audio will play, but only if a time is selected on the timeline.
I'm including the simplest example of the issue below. This would likely need to be run from an HTTP server (python -m http.server, python -m SimpleHTTPServer or whatever) in order to avoid any CORS issues. For this reason, I don't think I can include a JSFiddle demonstration of this issue here.
This issue appears to be Firefox only. It definitely does not affect Chrome, but I haven't actually tested any other browsers yet.
<audio id="audio" controls>
<source src="piano-sonata-no13.ogg" type="audio/ogg" />
</audio>
<script>
var audio_node = document.getElementById('audio');
var audioctx = new (window.AudioContext || window.webkitAudioContext)();
var analyser = audioctx.createAnalyser();
window.addEventListener('load', function(e) {
var source = audioctx.createMediaElementSource(audio_node);
source.connect(analyser);
source.connect(audioctx.destination);
}, false);
</script>
Edit: An example of this issue can be found here: http://mdn.github.io/media-source-buffer/

Try replacing the window "load" event listener with this:
audio_node.addEventListener('canplay', function(e) {
var source = audioctx.createMediaElementSource(audio_node);
source.connect(analyser);
source.connect(audioctx.destination);
}, false);

This issue appears to be related to a Firefox bug.
The gist of it is, it appears as if createMediaElementSource is currently somewhat broken in Firefox, and you can't use the audio API with createMediaStreamSource and have it work as expected.
I found a workaround here (WARNING: page autoplays audio), but as far as I can tell, it only works when autoplay is set to true. Quick testing suggests that setting audio.autoplay to true, and immediately calling audio.pause() may be an acceptable workaround to this issue. One downside to this method is that when the play button is pressed, the audio does not start at the very beginning of the file.
This solution would look something like this:
<audio id="audio" controls>
<source src="piano-sonata-no13.ogg" type="audio/ogg" />
</audio>
<script>
var audio_node = document.getElementById('audio');
audio_node.autoplay = true;
// Alternatively, the autoplay attribute can be set on the <audio> tag
var audioctx = new (window.AudioContext || window.webkitAudioContext)();
var analyser = audioctx.createAnalyser();
window.addEventListener('load', function(e) {
var source = audioctx.createMediaElementSource(audio_node);
source.connect(analyser);
source.connect(audioctx.destination);
audio_node.pause();
}, false);
</script>

Related

Use javascript variable for video source in HTML [duplicate]

I'm trying to build a video player that works everywhere. so far I'd be going with:
<video>
<source src="video.mp4"></source>
<source src="video.ogv"></source>
<object data="flowplayer.swf" type="application/x-shockwave-flash">
<param name="movie" value="flowplayer.swf" />
<param name="flashvars" value='config={"clip":"video.mp4"}' />
</object>
</video>
(as seen on several sites, for example video for everybody)
so far, so good.
But now I also want some kind of playlist/menu along with the video player, from which I can select other videos. Those should be opened within my player right away. So I will have to "dynamically change the source of the video" (as seen on dev.opera.com/articles/everything-you-need-to-know-html5-video-audio/ - section "Let's look at another movie") with Javascript. Let's forget about the Flash player (and thus IE) part for the time being, I will try to deal with that later.
So my JS to change the <source> tags should be something like:
<script>
function loadAnotherVideo() {
var video = document.getElementsByTagName('video')[0];
var sources = video.getElementsByTagName('source');
sources[0].src = 'video2.mp4';
sources[1].src = 'video2.ogv';
video.load();
}
</script>
The problem is, this doesn't work in all browsers. Namely, in Firefox there is a nice page where you can observe the problem I'm having: http://www.w3.org/2010/05/video/mediaevents.html
As soon as I trigger the load() method (in Firefox, mind you), the video player dies.
Now I have found out that when I don't use multiple <source> tags, but instead just one src attribute within the <video> tag, the whole thing does work in Firefox.
So my plan is to just use that src attribute and determine the appropriate file using the canPlayType() function.
Am I doing it wrong somehow or complicating things?
I hated all these answers because they were too short or relied on other frameworks.
Here is "one" vanilla JS way of doing this, working in Chrome, please test in other browsers:
var video = document.getElementById('video');
var source = document.createElement('source');
source.setAttribute('src', 'http://techslides.com/demos/sample-videos/small.mp4');
source.setAttribute('type', 'video/mp4');
video.appendChild(source);
video.play();
console.log({
src: source.getAttribute('src'),
type: source.getAttribute('type'),
});
setTimeout(function() {
video.pause();
source.setAttribute('src', 'http://techslides.com/demos/sample-videos/small.webm');
source.setAttribute('type', 'video/webm');
video.load();
video.play();
console.log({
src: source.getAttribute('src'),
type: source.getAttribute('type'),
});
}, 3000);
<video id="video" width="320" height="240"></video>
External Link
Modernizr worked like a charm for me.
What I did is that I didn't use <source>. Somehow this screwed things up, since the video only worked the first time load() was called. Instead I used the source attribute inside the video tag -> <video src="blabla.webm" /> and used Modernizr to determine what format the browser supported.
<script>
var v = new Array();
v[0] = [
"videos/video1.webmvp8.webm",
"videos/video1.theora.ogv",
"videos/video1.mp4video.mp4"
];
v[1] = [
"videos/video2.webmvp8.webm",
"videos/video2.theora.ogv",
"videos/video2.mp4video.mp4"
];
v[2] = [
"videos/video3.webmvp8.webm",
"videos/video3.theora.ogv",
"videos/video3.mp4video.mp4"
];
function changeVid(n){
var video = document.getElementById('video');
if(Modernizr.video && Modernizr.video.webm) {
video.setAttribute("src", v[n][0]);
} else if(Modernizr.video && Modernizr.video.ogg) {
video.setAttribute("src", v[n][1]);
} else if(Modernizr.video && Modernizr.video.h264) {
video.setAttribute("src", v[n][2]);
}
video.load();
}
</script>
Hopefully this will help you :)
If you don't want to use Modernizr , you can always use CanPlayType().
Your original plan sounds fine to me. You'll probably find more browser quirks dealing with dynamically managing the <source> elements, as indicated here by the W3 spec note:
Dynamically modifying a source element and its attribute when the element is already inserted in a video or audio element will have no effect. To change what is playing, just use the src attribute on the media element directly, possibly making use of the canPlayType() method to pick from amongst available resources. Generally, manipulating source elements manually after the document has been parsed is an unncessarily[sic] complicated approach.
http://dev.w3.org/html5/spec/Overview.html#the-source-element
I solved this with this simple method
function changeSource(url) {
var video = document.getElementById('video');
video.src = url;
video.play();
}
Instead of getting the same video player to load new files, why not erase the entire <video> element and recreate it. Most browsers will automatically load it if the src's are correct.
Example (using Prototype):
var vid = new Element('video', { 'autoplay': 'autoplay', 'controls': 'controls' });
var src = new Element('source', { 'src': 'video.ogg', 'type': 'video/ogg' });
vid.update(src);
src.insert({ before: new Element('source', { 'src': 'video.mp4', 'type': 'video/mp4' }) });
$('container_div').update(vid);
According to the spec
Dynamically modifying a source element and its attribute when the
element is already inserted in a video or audio element will have no
effect. To change what is playing, just use the src attribute on the
media element directly, possibly making use of the canPlayType()
method to pick from amongst available resources. Generally,
manipulating source elements manually after the document has been
parsed is an unncessarily complicated approach.
So what you are trying to do is apparently not supposed to work.
Just put a div and update the content...
<script>
function setvideo(src) {
document.getElementById('div_video').innerHTML = '<video autoplay controls id="video_ctrl" style="height: 100px; width: 100px;"><source src="'+src+'" type="video/mp4"></video>';
document.getElementById('video_ctrl').play();
}
</script>
<button onClick="setvideo('video1.mp4');">Video1</button>
<div id="div_video"> </div>
Yaur: Although what you have copied and pasted is good advice, this does not mean that it is impossible to change the source element of an HTML5 video element elegantly, even in IE9 (or IE8 for that matter).(This solution does NOT involve replacing the entire video element, as it is bad coding practice).
A complete solution to changing/switching videos in HTML5 video tags via javascript can be found here and is tested in all HTML5 browser (Firefox, Chrome, Safari, IE9, etc).
If this helps, or if you're having trouble, please let me know.
This is my solution:
<video id="playVideo" width="680" height="400" controls="controls">
<source id="sourceVideo" src="{{video.videoHigh}}" type="video/mp4">
</video>
<br />
<button class="btn btn-warning" id="{{video.videoHigh}}" onclick="changeSource(this)">HD</button>
<button class="btn btn-warning" id="{{video.videoLow}}" onclick="changeSource(this)">Regular</button>
<script type="text/javascript">
var getVideo = document.getElementById("playVideo");
var getSource = document.getElementById("sourceVideo");
function changeSource(vid) {
var geturl = vid.id;
getSource .setAttribute("src", geturl);
getVideo .load()
getVideo .play();
getVideo .volume = 0.5;
}
</script>
I have a similar web app and am not facing that sort of problem at all. What i do is something like this:
var sources = new Array();
sources[0] = /path/to/file.mp4
sources[1] = /path/to/another/file.ogg
etc..
then when i want to change the sources i have a function that does something like this:
this.loadTrack = function(track){
var mediaSource = document.getElementsByTagName('source')[0];
mediaSource.src = sources[track];
var player = document.getElementsByTagName('video')[0];
player.load();
}
I do this so that the user can make their way through a playlist, but you could check for userAgent and then load the appropriate file that way. I tried using multiple source tags like everyone on the internet suggested, but i found it much cleaner, and much more reliable to manipulate the src attribute of a single source tag. The code above was written from memory, so i may have glossed over some of hte details, but the general idea is to dynamically change the src attribute of the source tag using javascript, when appropriate.
Another way you can do in Jquery.
HTML
<video id="videoclip" controls="controls" poster="" title="Video title">
<source id="mp4video" src="video/bigbunny.mp4" type="video/mp4" />
</video>
<div class="list-item">
<ul>
<li class="item" data-video = "video/bigbunny.mp4">Big Bunny.</li>
</ul>
</div>
Jquery
$(".list-item").find(".item").on("click", function() {
let videoData = $(this).data("video");
let videoSource = $("#videoclip").find("#mp4video");
videoSource.attr("src", videoData);
let autoplayVideo = $("#videoclip").get(0);
autoplayVideo.load();
autoplayVideo.play();
});
I come with this to change video source dynamically. "canplay" event sometime doesn't fire in Firefox so i have added "loadedmetadata". Also i pause previous video if there is one...
var loadVideo = function(movieUrl) {
console.log('loadVideo()');
$videoLoading.show();
var isReady = function (event) {
console.log('video.isReady(event)', event.type);
video.removeEventListener('canplay', isReady);
video.removeEventListener('loadedmetadata', isReady);
$videoLoading.hide();
video.currentTime = 0;
video.play();
},
whenPaused = function() {
console.log('video.whenPaused()');
video.removeEventListener('pause', whenPaused);
video.addEventListener('canplay', isReady, false);
video.addEventListener('loadedmetadata', isReady, false); // Sometimes Firefox don't trigger "canplay" event...
video.src = movieUrl; // Change actual source
};
if (video.src && !video.paused) {
video.addEventListener('pause', whenPaused, false);
video.pause();
}
else whenPaused();
};
Using the <source /> tags proved difficult for me in Chrome 14.0.835.202 specifically, although it worked fine for me in FireFox. (This could be my lack of knowledge, but I thought an alternate solution might be useful anyway.) So, I ended up just using a <video /> tag and setting the src attribute right on the video tag itself. The canPlayVideo('<mime type>') function was used to determine whether or not the specific browser could play the input video. The following works in FireFox and Chrome.
Incidently, both FireFox and Chrome are playing the "ogg" format, although Chrome recommends "webm". I put the check for browser support of "ogg" first only because other posts have mentioned that FireFox prefers the ogg source first (i.e. <source src="..." type="video/ogg"/> ). But, I haven't tested (and highly doubt) whether or not it the order in the code makes any difference at all when setting the "src" on the video tag.
HTML
<body onload="setupVideo();">
<video id="media" controls="true" preload="auto" src="">
</video>
</body>
JavaScript
function setupVideo() {
// You will probably get your video name differently
var videoName = "http://video-js.zencoder.com/oceans-clip.mp4";
// Get all of the uri's we support
var indexOfExtension = videoName.lastIndexOf(".");
//window.alert("found index of extension " + indexOfExtension);
var extension = videoName.substr(indexOfExtension, videoName.length - indexOfExtension);
//window.alert("extension is " + extension);
var ogguri = encodeURI(videoName.replace(extension, ".ogv"));
var webmuri = encodeURI(videoName.replace(extension, ".webm"));
var mp4uri = encodeURI(videoName.replace(extension, ".mp4"));
//window.alert(" URI is " + webmuri);
// Get the video element
var v = document.getElementById("media");
window.alert(" media is " + v);
// Test for support
if (v.canPlayType("video/ogg")) {
v.setAttribute("src", ogguri);
//window.alert("can play ogg");
}
else if (v.canPlayType("video/webm")) {
v.setAttribute("src", webmuri);
//window.alert("can play webm");
}
else if (v.canPlayType("video/mp4")) {
v.setAttribute("src", mp4uri);
//window.alert("can play mp4");
}
else {
window.alert("Can't play anything");
}
v.load();
v.play();
}
I have been researching this for quite a while and I am trying to do the same thing, so hopefully this will help someone else. I have been using crossbrowsertesting.com and literally testing this in almost every browser known to man. The solution I've got currently works in Opera, Chrome, Firefox 3.5+, IE8+, iPhone 3GS, iPhone 4, iPhone 4s, iPhone 5, iPhone 5s, iPad 1+, Android 2.3+, Windows Phone 8.
Dynamically Changing Sources
Dynamically changing the video is very difficult, and if you want a Flash fallback you will have to remove the video from the DOM/page and re-add it so that Flash will update because Flash will not recognize dynamic updates to Flash vars. If you're going to use JavaScript to change it dynamically, I would completely remove all <source> elements and just use canPlayType to set the src in JavaScript and break or return after the first supported video type and don't forget to dynamically update the flash var mp4. Also, some browsers won't register that you changed the source unless you call video.load(). I believe the issue with .load() you were experiencing can be fixed by first calling video.pause(). Removing and adding video elements can slow down the browser because it continues buffering the removed video, but there's a workaround.
Cross-browser Support
As far as the actual cross-browser portion, I arrived at Video For Everybody as well. I already tried the MediaelementJS Wordpress plugin, which turned out to cause a lot more issues than it resolved. I suspect the issues were due to the Wordpress plug-in and not the actually library. I'm trying to find something that works without JavaScript, if possible. So far, what I've come up with is this plain HTML:
<video width="300" height="150" controls="controls" poster="http://sandbox.thewikies.com/vfe-generator/images/big-buck-bunny_poster.jpg" class="responsive">
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.ogv" type="video/ogg" />
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4" />
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.webm" type="video/webm" />
<source src="http://alex-watson.net/wp-content/uploads/2014/07/big_buck_bunny.iphone.mp4" type="video/mp4" />
<source src="http://alex-watson.net/wp-content/uploads/2014/07/big_buck_bunny.iphone3g.mp4" type="video/mp4" />
<object type="application/x-shockwave-flash" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" width="561" height="297">
<param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
<param name="allowFullScreen" value="true" />
<param name="wmode" value="transparent" />
<param name="flashVars" value="config={'playlist':['http://sandbox.thewikies.com/vfe-generator/images/big-buck-bunny_poster.jpg',{'url':'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4','autoPlay':false}]}" />
<img alt="No Video" src="http://sandbox.thewikies.com/vfe-generator/images/big-buck-bunny_poster.jpg" width="561" height="297" title="No video playback capabilities, please download the video below" />
</object>
<strong>Download video:</strong> MP4 format | Ogg format | WebM format
</video>
Important notes:
Ended up putting the ogg as the first <source> because Mac OS Firefox quits trying to play the video if it encounters an MP4 as the first <source>.
The correct MIME types are important .ogv files should be video/ogg, not video/ogv
If you have HD video, the best transcoder I've found for HD quality OGG files is Firefogg
The .iphone.mp4 file is for iPhone 4+ which will only play videos that are MPEG-4 with H.264 Baseline 3 Video and AAC audio. The best transcoder I found for that format is Handbrake, using the iPhone & iPod Touch preset will work on iPhone 4+, but to get iPhone 3GS to work you need to use the iPod preset which has much lower resolution which I added as video.iphone3g.mp4.
In the future we will be able to use a media attribute on the <source> elements to target mobile devices with media queries, but right now the older Apple and Android devices don't support it well enough.
Edit:
I'm still using Video For Everybody but now I've transitioned to using FlowPlayer, to control the Flash fallback, which has an awesome JavaScript API that can be used to control it.
Try moving the OGG source to the top. I've noticed Firefox sometimes gets confused and stops the player when the one it wants to play, OGG, isn't first.
Worth a try.
You shouldn't try to change the src attribute of a source element, according to this spec note .
Dynamically modifying a source element and its attribute when the element is
already inserted in a video or audio element will have no effect. To
change what is playing, just use the src attribute on the media
element directly
So lets say you have:
<audio>
<source src='./first-src'/>
</audio>
To modify the src:
<audio src='./second-src'/>
<source src='./first-src'/>
</audio>
if you already have a loaded video and you try to upload a new one over that one make sure to use the videoRef.load() on the second one, otherwise it wont load.
*videoRef should be the ref of the displayed <video></video> tag
Using JavaScript and jQuery:
<script src="js/jquery.js"></script>
...
<video id="vid" width="1280" height="720" src="v/myvideo01.mp4" controls autoplay></video>
...
function chVid(vid) {
$("#vid").attr("src",vid);
}
...
<div onclick="chVid('v/myvideo02.mp4')">See my video #2!</div>
I ended up making the accepted ansower into a function and improving the resume to keep the time. TLDR
/**
* https://stackoverflow.com/a/18454389/4530300
* This inspired a little function to replace a video source and play the video.
* #param video
* #param source
* #param src
* #param type
*/
function swapSource(video, source, src, type) {
let dur = video.duration;
let t = video.currentTime;
// var video = document.getElementById('video');
// var source = document.createElement('source');
video.pause();
source.setAttribute('src', src);
source.setAttribute('type', type);
video.load();
video.currentTime = t;
// video.appendChild(source);
video.play();
console.log("Updated Sorce: ", {
src: source.getAttribute('src'),
type: source.getAttribute('type'),
});
}

Capturing audio from <video> in web audio API, can't mute original audio

I'm working on a project where I'm using <video> elements as sources for canvas animations, and I'm aiming to send their audio through the Web Audio API using Tone.js. The canvas animations are fine, it's the audio that's giving me trouble. I'd like to keep the audio synced to the video if possible, so I'm using MediaStream.
When a video loads, it's initially muted on the element itself. I do muted="false" once audio is enabled with a button press that runs Tone.start(). I grab the video's audio via captureStream(), and hook it up to a gain node with the gain set to 0, essentially muting it again. In Firefox, everything works fine, and I can set the gain to whatever desired value. But in Chrome, I can't get rid of the original video audio – it's still going in the background. My "unmute" works, but it clearly plays a second copy of the audio, causing comb filtering.
I'm intending on doing more than just muting and unmuting, so while it's tempting to just use video.volume instead of putting in all this work, this is just a proof of concept that isn't proving much at all right now. Any help is appreciated!
let video = document.querySelector(video);
// lower the video element's audio until we're ready
// might not be necessary, but it's just a cautionary step
video.volume = 0;
// unhook the audio from the video; works in FF, but not Chrome
let stream = video.mozCaptureStream ? video.mozCaptureStream() : video.captureStream();
let audioTrack = new MediaStream(stream.getAudioTracks());
let speaker = Tone.context.createMediaStreamSource(audioTrack);
// gain node is the *actual* volume control that I'm intending to use; it starts at 0 to mute the unhooked audio
let gain = new Tone.Gain(0);
Tone.connect(speaker, gain);
Tone.connect(gain, Tone.context.destination);
// if video.volume stays at 0, we hear nothing
video.volume = 1;
Edit: It may be worth mentioning that I did start with this Vonage API support page to better understand how to go about using captureStream() like this, but the cloning and disabling process described in that article didn't work for me in FF or Chrome.
Chrome's behavior is actually the "more correct" one here (surprisingly given the many bugs they have in that area).
You are creating a clone MediaStream from the MediaElement's source. This MediaStream should not be affected by the volume set on the <video> element (specs), both Firefox and Chrome do fail here.
The captured MediaStream should thus have its own graph and when you connect it to the AudioContext, the original stream from the MediaElement should continue its life and completely ignore the captured MediaStream. This however is correctly handled by Chrome, but Firefox has it wrong (which is in part why they still do prefix the MediaElement#mozCaptureStream() method name).
But since what you want is actually Firefox's behavior, you can reproduce it by using a MediaElementAudioSourceNode, which will take the ownership of the MediaElement's audio stream, and disconnect it entirely from the MediaElement's graph. You'll thus have complete control over the output volume.
const btn = document.querySelector("button");
const vid = document.querySelector("video");
const inp = document.querySelector("input");
btn.onclick = evt => {
btn.remove();
vid.play();
const context = new AudioContext();
const gain = context.createGain();
const source = context.createMediaElementSource(vid);
source.connect(gain);
gain.connect(context.destination);
inp.oninput = evt => {
gain.gain.value = inp.value;
};
gain.gain.value = 0;
const meter = new OscilloMeter(document.querySelector("canvas"));
meter.listen(source, context);
};
button~*,button~.cont { display: none }
.cont { display: flex }
<script>class OscilloMeter{constructor(a){this.ctx=a.getContext("2d")}listen(a,b){function c(){g.getByteTimeDomainData(j),d.clearRect(0,0,e,f),d.beginPath();let a=0;for(let c=0;c<h;c++){const e=j[c]/128;var b=e*f/2;d.lineTo(a,b),a+=k}d.lineTo(d.canvas.width,d.canvas.height/2),d.stroke(),requestAnimationFrame(c)}const d=this.ctx,e=d.canvas.width,f=d.canvas.height,g=b.createAnalyser(),h=g.fftSize=256,j=new Uint8Array(h),k=e/h;d.lineWidth=2,a.connect(g),c()}}</script>
<button>Start</button>
<label>Output volume: <input type=range min=0 max=1 step=0.01 value=0></label>
<div class="cont">
<section>
<p>You can still control the input's volume through the video's UI:</p>
<video src=https://upload.wikimedia.org/wikipedia/commons/2/22/Volcano_Lava_Sample.webm id=vid controls crossorigin=anonymous height=200></video>
</section>
<section>
<p>
Processed audio (using input volume):<br>
<canvas></canvas>
</p>
</section>
</div>

Autoplay music on chrome

I have found only deprecated anwers so i need to ask how to make autoplay on chrome?
<audio autoplay loop controls src="./audio/menu.wav" data-start-screen-audio></audio>
let music = new Audio("./audio/menu.wav");
music.addEventListener("canplaythrough", function () {
music.play();
});
these two metods works on other browsers but on chrome not, how to fix that?
by default in modern browser, this is not allowed but if you add the muted attribute it will work fine
as they mention here in mdn
Note: Sites that automatically play audio (or videos with an audio track) can be an unpleasant experience for users, so should be avoided when possible. If you must offer autoplay functionality, you should make it opt-in (requiring a user to specifically enable it). However, this can be useful when creating media elements whose source will be set at a later time, under user control.
but in the case of media content you could run the play action from js
like this
<video src="" id="videoEl">
document.onload = function(){
document.getElementById('videoEL').play()
}
for more info check the autoplay guide
You may simply use (.autoplay = true;) as following (tested on Chrome Desktop):
<audio id="audioID" loop> <source src="path/audio.mp3" type="audio/mp3"></audio>
<script>
var myaudio = document.getElementById("audioID").autoplay = true;
</script>

Load different video in HTML5 video player

I have an HTML5 video tag that I dynamically load. Here's my HTML:
<video id="video" width="640" height="480" controls autoplay>
<source id="source" src="" type="video/mp4">
</video>
Here is my JavaScript for loading the video:
function RunVideo(index) {
var grid = document.getElementById("ctl00_ContentPlaceHolder1_gvPresentations");
var cell = grid.rows[(+index) + 1].cells[2].innerHTML;
var player = document.getElementById('video');
var mp4Vid = document.getElementById('source');
var movie = cell;
player.pause();
mp4Vid.setAttribute('src', movie);
player.load();
player.play();
}
The first time I load a video (from a grid view) it works fine. But any subsequent ones I try to load I get the following message in the video player:
Error: Unsupported video type or invalid file path.
How can I correctly unload the current video in order to reload a new one?
Edit
It seems to be an IE only bug. It does work in other browsers like a charm.
It is able to play each video individually on load (i.e if no other src have been set before).
The links and code are ok then.
It throws a MEDIA12899: AUDIO/VIDEO: Unknown MIME type. error.
Edit:
After I tested with this fiddle, the bug doesn't raise, so my assumptions were incorrect.
Which leaves you with the only choice of trying to re-encode your videos.
Original answer:
It seems you are facing an IE bug, when setting the source element with different codecs(not type).
I think that the browser automatically assigns for himself the codec parameter, in the type attribute and doesn't update it when the new src is set.
Even if all your videos are encapsulated in .mp4, the codecs may vary.
You can find a list of codecs that IE does support here. Basically, .webm, '
H.264 high profile' and H.264 baseline profile.
One possible workaround you may try, if my assumptions are correct, is to create a new sourceelement each time you call your RunVideo function.
function RunVideo(index) {
var grid = document.getElementById("ctl00_ContentPlaceHolder1_gvPresentations");
var cell = grid.rows[(+index) + 1].cells[2].innerHTML;
var player = document.getElementById('video');
var oldMp4Vid = document.getElementById('source');
var movie = cell;
var newmp4Vid = document.createElement('source')
newMp4Vid.src = cell;
player.removeChild(oldMp4Vid);
player.appendChild(newMp4Vid);
player.load();
}
I'm not sure it will do the trick and I'm not sure what the specs tells about setting <source> new src on the flow like that, but if this problem is only present in IE, it's probably a bug from them, maybe you could fill a bug report.
Alternatively, you could re-encode your videos with the exact same codec.

Change firefox playback bar into a onclick button for audio

SAME ISSUE! As we all know firefox and audio is a problem because of patents and such. I found this little code on the internet to play my sounfile.
I would like to play multiple files instead of just one while having the display bar not show up in the browser
you can change the player width to 0 but than the user can not click the play button :P
Is there a way of possibly having the sound play on click of a link or button.
Please note. Do not give me codes that have no compatibility outside chrome and ie.
HTML
<audio id="audioplayer" preload controls loop style="width:400px;">
<source src="sounds/sound1.mp3">
<source src="sounds/sound1.caf">
</audio>
Javascript
<script type="text/javascript">
var audioTag = document.createElement('audio');
if (!(!!(audioTag.canPlayType) && ("no" != audioTag.canPlayType("audio/mpeg")) && ("" != audioTag.canPlayType("audio/mpeg")))) {
AudioPlayer.embed("audioplayer", {soundFile: "sounds/sound1.mp3"});
}
</script>
RECAP:
Have the sound play on a button or link click.
Have multiple sounds available to play (not just one)
Compatibility with firefox
non visible soundbar.
Still learning myself. But this is a button, with a script to play an audio file. (part of my own solution) Plays only 1 sound at a time, but doesn't show anything about it.
You could also make a funtion like this, without setting the src, using the pause() command.
currenttime is used to change the part where the audio file was.
Sound play button<br>
<script>
sound = new Audio();
function playSnd(soundSrc) {
sound.src = soundSrc;
sound.play();
}
</script>

Categories