In testing out the HTML5 track element, the cue comes up null. The TextTrackList and track element appear to load. Also, I am aware that VTT files aren't accessible locally, and I'm testing on a server. Can anyone help out? Thanks in advance.
This is my Javascript:
var audioElement = document.querySelector("audio");
var textTracks = audioElement.textTracks;
var textTrack = textTracks[0];
var ques = textTrack.cues;
var que = ques[0];
console.log(que);
Here's the HTML:
<audio src="Audio Files/Q_firefox.ogg" controls>
<track src="cues.vtt"></track>
</audio>
The cue value changes as the track plays so you need to listen for the value to change and run your function each time the text changes. Try this example based on your question:
var audioElement = document.querySelector("audio");
var textTrack = audioElement.textTracks[0];
// When cue value changes run your code
textTrack.oncuechange = function(e) {
var cue = this.activeCues[0];
if(cue){
console.log(cue.text);
}
}
<audio src="http://html5-demos.appspot.com/static/video/track/Google_Developer_Stories.webm" controls>
<track src="http://html5-demos.appspot.com/static/video/track/video-subtitles-en.vtt" default>
</audio>
Also note no need to close HTML track tag.
Related
I have a sample html5 video with simple html code.
What I need to do is a customized mute button for all the videos, meaning:
if the user clicks on the mute/unmute button for one video, all the other videos get muted/unmuted as well
Is there any way of doing this?
without your html code it is pretty vague but in JS you can do it :
here is a link of the documentation im using :
https://www.w3schools.com/tags/av_prop_muted.asp
https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_av_prop_muted
<button onclick="enableMute()" type="button">Mute sound</button>
<button onclick="disableMute()" type="button">Enable sound</button>
<video id="myVideo" width="320" height="176" controls>
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
<script>
var vid = document.getElementById("myVideo");
function enableMute() {
vid.muted = true;
}
function disableMute() {
vid.muted = false;
}
</script>
So to trigger the action on all your videos you can :
add a class preferably or id on all your video tag
make js know about them
var vid = document.getElementById("myVideo");
var vid1 = document.getElementById("myVideo1");
var vid2 = document.getElementById("myVideo2");
var vid3 = document.getElementById("myVideo3");
var vid4 = document.getElementById("myVideo4");
add an onClick action on a button that trigger an action here Mute action which will mute or unmute your videos using the mute property of your element, the action would like
function enableMute() {
vid.muted = true;
vid1.muted = true;
vid2.muted = true;
vid3.muted = true;
vid4.muted = true;
}
I think you could do it without this much duplication of code if you add the same class to all your element, and looping through all of them in the action you trigger when you click on the button and then change for each of them their property but not sure exactly how to do it
I am trying to change the audio file on a button click and am getting the error
Uncaught TypeError: audio.load is not a function
My code is below, the idea is to press the button and then the audio file will change.
Without the audio.load() line, the code will run and the src will update, but the audio does not change. What am I missing?
HTML:
<!DOCTYPE HTML>
<html>
<body>
<br>
<audio controls>
<source src = "audio_file_1.mp3"
id="audio" type="audio/mpeg">
Your browser does not support the audio element!
</audio>
<br>
<button onClick="changeAudio();">Change</button>
</body>
<script src="temp.js"></script>
</html>
Javascript:
// temp js
var a = 1;
function changeAudio() {
var audio = document.getElementById('audio');
if (a==1) {
audio.src = 'audio_file_1.mp3';
a = 2;
}
else {
audio.src = 'audio_file_2.mp3';
a = 1;
}
audio.load();
}
changeAudio();
(also, if anyone knows example sound files that I can use instead of the audio_file_1.mp3 and audio_file_2.mp3, I would be happy to update the code so anyone can run it more easily)
Edit WRT Rob M's answer:
For anyone with the same problem, the solution is to change two lines:
First, in the HTML code, the <audio control> should turn to <audio control id="audio_id">
Second, in the javascript code the audio.load() should turn to document.getElementById('audio_id').load();
There is no .load() event on a <source> tag, it is on the <audio> tag - update your code to call load() on the parent <audio> tag and it should work.
Well, I think you are trying to access to <audio> element by its id attribute, but you haven't set id attribute to audio tag.
It must be something like this
<audio id="audio" controls>
<source src = "audio_file_1.mp3"
id="track" type="audio/mpeg">
Your browser does not support the audio element!
</audio>
And changing audio file:
var a = 1;
function changeAudio() {
var audio = document.getElementById('audio');
if (a==1) {
document.getElementById('track') = 'audio_file_1.mp3';
a = 2;
}
else {
document.getElementById('track') = 'audio_file_2.mp3';
a = 1;
}
audio.load();
}
changeAudio();
Whenever I run the script it returns NaN for audio duration.
Script
var mytrack = document.getElementById('mytrack');
var duration1 = document.getElementById('fullDuration');
duration1.innerHTML = parseInt(mytrack.duration);
HTML
<audio id="mytrack" controls autoplay>
<source src="kalimba.mp3" type="audio/mp3" />
</audio>
<span id="fullDuration">0:00</span>
It is always advised to use the event of loadedmetadata and then calling them will always work. Using Event Listeners are best in this case.
var a = document.getElementById('mytrack');
a.addEventListener("loadedmetadata", function() {
var duration1 = document.getElementById('fullDuration');
duration1.innerHTML = parseInt(a.duration);
}, true);
This waits till the media is loaded and then it sets the contents of the <span> tag. For best results, please put this code either in the end of the document, before </body> tag or use window's load event:
document.addEventListener('DOMContentLoaded', function () {
var a = document.getElementById('mytrack');
a.addEventListener("loadedmetadata", function() {
var duration1 = document.getElementById('fullDuration');
duration1.innerHTML = a.duration;
}, true);
}, false);
As said in comments, there's also another way to do it using preload attribute:
This enumerated attribute is intended to provide a hint to the browser about what the author thinks will lead to the best user experience.
But since you already haveautoplay attribute, I guess preload won't be necessary.
The autoplay attribute has precedence over preload. If autoplay is specified, the browser would obviously need to start downloading the audio for playback.
You can use oncanplaythrough event. parseInt() is not necessary.
var mytrack = document.getElementById("mytrack");
var duration1 = document.getElementById("fullDuration");
mytrack.oncanplaythrough = function() {
duration1.innerHTML = this.duration
}
<audio id="mytrack" controls autoplay>
<source src="https://upload.wikimedia.org/wikipedia/commons/6/6e/Micronesia_National_Anthem.ogg" type="audio/ogg">
</audio>
<span id="fullDuration">0:00</span>
Question: I have 2 audio sounds and I want to play one HTML5 audio element at a time.
Similar Post: Play one HTML audio element at a time.
I saw a similar post to my question. However, as a JavaScript beginner I did not understand the code. So I tried a simpler way so I can understand, but is not working. I would appreciate any suggestions.
HTML5 code: (For this example only I used the same audio source as a previous post: http://jsfiddle.net/RE006/8djstmvy/
<div>
<h2>Example 1</h2>
<audio id="sound1" src=http://geo-samples.beatport.com/lofi/5005876.LOFI.mp3 controls="controls" preload="none">
<p>Your browser does not support the audio element.</p>
</audio>
</div>
<div>
<h2>Example 2</h2>
<audio id="sound2" src=http://geo-samples.beatport.com/lofi/5005933.LOFI.mp3 controls="controls" preload="none">
<p>Your browser does not support the audio element.</p>
</audio>
</div>
JavaScript:
var $ = function (id) {
return document.getElementById(id);
}
var sound1_click = function() {
//starts playing
$("sound1").play ();
//pause playing
$("sound2").pause();
}
var sound2_click = function() {
//starts playing
$("sound2").play ();
//pause playing
$("sound1").pause();
}
window.onload = function () {
$("sound1").onclick = sound1_click;
$("sound2").onclick = sound2_click;
}
I think the problem is you are listing to click event, when you should be listening to play event, also for some reason, window.onload does not work properly in jsfiddle, so replace
window.onload = function () {
$("sound1").onclick = sound1_click;
$("sound2").onclick = sound2_click;
}
with
$("sound1").onplay = sound1_click;
$("sound2").onplay = sound2_click;
fiddle demo
or you can simply generalize it by:
var audios = document.getElementsByTagName('audio');
for(var i=0; i<audios.length;i++) audios[i].onplay = pauseAllAudios.bind(null, audios[i]);
function pauseAllAudios(audio){
for(var i=0; i<audios.length;i++)
if(audios[i]!=audio) audios[i].pause();
};
fiddle demo
on an website I have a simple video player tag and a list of videos. Onclick to an element of the videolist I change the poster and src attribute of the video tag an den src and type of the source-tag inside the video tag.
This all works fine in FF and IE but it don't works in chrome.
VideoTag
<video id='video' class='video-js vjs-default-skin' controls preload='none' width='640' height='320' poster='./poster/dummy.png' data-setup='{}' preload='none'>
<source src='./video/BeHappyToBeAlive.mp4' type='video/mp4'>
<track kind='captions' src='demo.captions.vtt' srclang='en' label='English'></track><!-- Tracks need an ending tag thanks to IE9 -->
<track kind='subtitles' src='demo.captions.vtt' srclang='en' label='English'></track><!-- Tracks need an ending tag thanks to IE9 -->
Your Browser does not support video tag. Please update your Browser.
</video>
JavaScript
$(document).ready(function(){
var videoChanging = false;
function changeVideo(videoTag) {
var video = videoTag.children().first();
var src = video.children('source');
var title = video.parent().find('h3').html();
var description = video.parent().find('p').html();
var poster = video.attr('poster');
var source = video.children().first().attr('src');
var mainVideo = $('#video_html5_api');
var mainVideoBox = $('#video');
mainVideo.children('source').remove();
mainVideo.prepend(src.clone());
mainVideo.attr('poster', poster);
mainVideo.attr('src', source);
mainVideoBox.parent().find('h3').html(title);
mainVideoBox.parent().find('p').html(description);
document.getElementById('video_html5_api').load();
videoChanging = false;
setTimeout(function(){
document.getElementById('video_html5_api').play();
}, 200);
}
$('.videoListItemBox > a ').on('click', function () {
if( videoChanging ){
return;
}
document.getElementById('video_html5_api').pause();
var video = $(this);
videoChanging = true;
var changeMovieCallback = function(){ changeVideo( video ); }
var t = setTimeout(changeMovieCallback, 200);
});
});
When I add an alert to the beginn of the changeVideo(videoTag) function it will works fine in chrome.
Can somebody explain my why and give me a solution to fix this problem?
It might be the preload='none' property on your video element. But it is hard to tell - your sample is too complex. How about something simple?
<video id='video' controls width='640' height='320'>
Your Browser does not support video tag. Please update your Browser.
</video>
<div class= "videoListItemBox">
<a href="#" data-src="http://html5demos.com/assets/dizzy.mp4"
data-poster="http://lorempixel.com/640/320/">video 1</a>
<a href="#" data-src="http://techslides.com/demos/sample-videos/small.mp4"
data-poster="http://lorempixel.com/640/320/">video 2</a>
<div>
code:
$(function(){
$('.videoListItemBox > a ').on('click', function (e) {
var link = $(this);
$('#video')
.attr('poster', link.data('poster'))
.attr('src', link.data('src'))
.get(0).play();
e.preventDefault();
});
});
See this jsbin: http://jsbin.com/bamafaki/2/edit
Do note that *.mp4 files are not supported on all browsers, so you should expand your code to include *.webm files as a fallback.
This reason why the newly selected video is loading on alert message box is that it causes postback which is when the video is loaded.