HTML5 getElementById doesn't work using Firefox - javascript

I am sure that in the past I accessed the audio element, and I know it is a valid way of using it. But I cannot find out why this time it just doesn't work !!! what am I doing wrong? (I am using firefox)
what is wrong with calling the following code?
<html>
<head>
<script>
<!-- var audio = new Audio(); audio.src = 'sounds/audio1_1.mp3'; audio.controls = true; audio.loop = true; audio.autoplay = true; -->
var audioElement_theme;
audioElement_theme = document.getElementById("audio1_1");
audioElement_theme.play();
</script>
</head>
<body>
<audio id="audio1_1"><source src="sounds/audio1_1.ogg" type="audio/ogg" /><source src="sounds/audio1_1.mp3" type="audio/mpeg" />Your browser does not support the audio element.</audio>
<div id="mp3_player">
<div id="audio_box"></div>
<canvas id="analyser_render"></canvas>
</div>
</body>
</html>
But when I change:
audioElement_theme = document.getElementById("audio1_1");
audioElement_theme.play();
to:
var audio = new Audio();
audio.src = 'sounds/audio1_1.mp3';
audio.controls = true;
audio.loop = true;
audio.autoplay = true;
It works !!!

The element doesn't exist at the time you try to get it by its id.
Move the script so it is after the audio element.
You also have an HTML comment inside the the script. That might also interfere.
A JavaScript comment looks:
// like this
or
/* like this */

YOur code works, I tested it. When you run your current code it will give you an error in console windows like "Can not read property .paly() of null" so move your Script after audio tag. So just move your code after tag.

Related

Change audio file on button click

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();

Infinite loop with random playlist

I have numerous MP3 files in a folder.
When I enter a page, I want a song from that playlist to play. After this song is over, I want a new one to play (not the same one) and so on.
<script type="text/javascript">
var song = ["../audio/1.mp3" , "../audio/2.mp3", "../audio/3.mp3", "../audio/4.mp3", "../audio/5.mp3" ];
var soundFile = song[Math.floor(Math.random()*song.length)];
document.write("<embed id='sound' src='" + soundFile + "' loop='true' type='audio/mpeg' controller='false' height='0' width='0'>");
</script>
What's wrong, because it always plays the same song.
Use an already defined embedded element and set the src attribute.
<embed id='sound' loop='true' type='audio/mpeg' controller='false' height='0' width='0'>
<script type="text/javascript">
var songs = ["../audio/1.mp3" , "../audio/2.mp3", "../audio/3.mp3", "../audio/4.mp3", "../audio/5.mp3" ];
var remainingSongs = songs;
var el = document.getElementById("sound");
var pickSong = function(){
// No songs left?
if(!remainingSongs.length) {
remainingSongs = songs;
}
// Pick song
var index = Math.floor(Math.random() * (remainingSongs.length - 1));
var soundFile = remainingSongs[index];
// Remove song from array
remainingSongs.splice(index, 1);
el.setAttribute("src", soundFile);
}
pickSong();
el.addEventListener("ended", pickSong, false);
</script>
You have an off-by-one error. I think it should be:
var soundFile = song[(Math.floor((Math.random())*(song.length-1)))];
But otherwise this should work. Could be a combination of the erroneous code and weird browser caching?
Also, check the web server you are using to serve the files and clear its cache.
Plus make sure your audio files are actually different.
Also, random chance may be tricking you. Give it a few goes.
This works for me in Chrome Canary on OSX:
<!DOCTYPE html>
<html>
<head>
<script>
var song = ['./foo.m4a', 'bar.m4a', 'bam.m4a'];
var soundFile = song[(Math.floor((Math.random())*(song.length-1)))];
document.write('<embed id="sound" src="' + soundFile + '" loop="true" type="audio/mpeg" controller="false" height="0" width="0">');
</script>
</head>
<body></body>
</html>
The problem is the loop attribute for the embed element doesn't know about your array of audio sources. It's just going to loop over the same source file.
Luckily, there is a pretty easy solution. The following will create an Audio element, with the Audio constructor, and continue to set a "random" audio source from the song array when the previous is done playing. We can do this by listening for the ended event.
<script type="text/javascript">
var song = ["../audio/1.mp3" , "../audio/2.mp3", "../audio/3.mp3", "../audio/4.mp3", "../audio/5.mp3" ];
var audio = new Audio();
var setSound = function() {
var soundFile = escape(song[Math.floor(Math.random()*song.length)]);
audio.setAttribute('src', soundFile);
audio.play();
};
// set initial source
setSound();
// set a new source, when current sound is done playing
audio.addEventListener('ended', setSound, false);
</script>

Reload Source of html5 video tag doesn't work on chrome

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.

Get cue in HTML5 track element

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.

Replacing HTML5 video src strings in javascript does not replace video

I'm a javascript novice building a simple page to practice using HTML5 video. It's basically a full-page looping video and a javascript timer that tracks and updates time on page. (Inspired, of course, by Infinite Drunk Ron Swanson). Here is a live version of the page. Be careful: both links play sound.
I'd like the script to select one of seven videos to play on page load. The code should choose a random integer between 1 and 7, generate strings to the appropriate files in a "media/" directory, and replace the video <source> tag's src attribute with the new string.
This all seems to be working correctly: there are no errors in the console, locally or as uploaded to github-pages, and when I inspect the <video> element in the Chrome developer toolbar, I can see that the code is replacing the src strings correctly. But the page doesn't seem to load different videos! This is extra-aggravating, as it was working correctly a few commits ago. I've gone back through the history to see what's changed, but I can't find anything.
I come from Python, and I suspect there's something I just don't get yet, but I don't know enough to figure out what!
UPDATE: I have solved this problem with the help of this question, by using createElement and appendChild to insert the source tags instead of changing the attributes of each element in the NodeList returned by querySelectorAll. Here is the relevant new code:
function add_source(element, src, type) {
var source = document.createElement("source");
source.src = src;
source.type = type;
element.appendChild(source);
}
function main() {
var video_no = random_int(1,7);
var video_string_mpeg = "http://ecmendenhall.github.com/Infinite-Charleston/media/Trudy" + video_no + ".mp4";
var video_string_webm = "http://ecmendenhall.github.com/Infinite-Charleston/media/Trudy" + video_no + ".webm";
var videoplayer = document.querySelector(".videoplayer");
add_source(videoplayer, video_string_mpeg, "video/mp4");
add_source(videoplayer, video_string_mpeg, "video/webm");
get_seconds();
}
This is great, but I don't completely understand why it worked. Explanations are still welcome!
Here's the javascript:
start = new Date();
start_time = start.getTime();
function get_seconds() {
var now = new Date();
var time_now = now.getTime();
var time_diff = time_now - start_time;
var seconds = time_diff/1000;
var timer_string = Math.round(seconds);
document.getElementById("timer").innerHTML = timer_string;
window.setTimeout("get_seconds();", 1000);
}
function random_int(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min; }
function main() {
var video_no = random_int(1,7);
var video_string_mpeg = "http://ecmendenhall.github.com/Infinite-Charleston/media/Trudy" + video_no + ".mp4";
var video_string_webm = "http://ecmendenhall.github.com/Infinite-Charleston/media/Trudy" + video_no + ".webm";
var sources = document.querySelectorAll(".videoplayer source");
sources.item(0).src = video_string_mpeg;
sources.item(1).src = video_string_webm;
get_seconds();
}
And the HTML:
<html>
<link rel="stylesheet" href="charleston.css">
<script src="charleston.js" type="text/javascript">
</script>
<body onload="main();">
<video class="videoplayer" loop autoplay>
<source src="http://ecmendenhall.github.com/Infinite-Charleston/media/Trudy1.mp4" type="video/mp4" />
<source src="http://ecmendenhall.github.com/Infinite-Charleston/media/Trudy1.webm" type="video/webm" />
Christ on a cracker, Trudy! Update your web browser!
<audio loop autoplay>
<source src="http://ecmendenhall.github.com/Infinite-Charleston/media/charleston.mp3" type="audio/mpeg" />
<source src="http://ecmendenhall.github.com/Infinite-Charleston/media/charleston.ogg" type="audio/ogg" />
</audio>
</video>
<div class="timer_box">
<p>Hell's bells, Trudy! You've been dancing for <a id="timer">0</a> seconds.
Tweet
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script></p>
</div>
</body>
</html>
I don't think the CSS or media files are the problem, but you can see them in the project repository if you'd like. A live version is available here. (NB: It plays sound). As you can see, it does everything right except selecting different videos.
I believe you can also call .load() on your video object to reload the <source>'s defined in the corresponding video object.
"When your listener function is triggered, it should change the media’s src property, then call the load method to load the new media and the play method to play it, as shown in Listing 3-4." - Apple

Categories

Resources