youtube <video> element always comes up empty in firefox contentscript - javascript

main.js
highLevelTab.attach({
contentScriptFile: "./yt-controls.js"
});
/data/yt-controls.js
window.addEventListener("load", function(e) {
var video = window.document.getElementsByTagName("video");
console.log(video);
});
video comes up as {"0":{}}. Do I need to inject this into the page script in order to get the actual values?

Turns out you can use unsafeWindow in firefox to access the page as it is, after all scripts on the page have messed with it, as detailed here. So,
window.addEventListener("load", function(e) {
var video = unsafeWindow.document.getElementsByTagName("video");
console.log(video);
});

Related

HTML5 duration time of MP3 sometimes works

I'm having problems showing the duration time of an MP3 file in my HTML5 audio player. Sometimes it will load the duration time, sometimes it won't.
The times it doesn't load is when I'm making changes to the CSS and when I refresh the page.
When I change the MP3 file to load another MP3 file, the duration time shows up. It goes away when I refresh the page.
This is the code for duration time:
audio.addEventListener('loadedmetadata', function(){
progress.setAttribute('max', Math.floor(audio.duration));
duration.textContent = toHHMMSS(audio.duration);
});
I'm new at JavaScript so I have no idea how to code. I'm using this code from https://codepen.io/davatron5000/pen/uqktG and when you refresh the page, the duration of mp3 file disappears.
This is probably because of cache.
If you are setting your audio's src in the markup (html), the cached version of your media may already be loaded* when you attach the event listener.
Hence your event handler won't fire ever :
window.onload = function(){ // kinda force the situation
aud.onloadedmetadata = function(e){ // this won't fire
console.log('metatadata loaded');
};
};
<audio src="https://dl.dropboxusercontent.com/s/agepbh2agnduknz/camera.mp3" id="aud"/>
But in this case, you can already access its duration.
So you just have to check for its duration :
window.onload = function() {
if (aud.duration) {
doSomething();
} else {
aud.onloadedmetadata = doSomething;
}
}
function doSomething(event) {
console.log(aud.duration);
console.log('from event handler :', !!event);
}
<audio src="https://dl.dropboxusercontent.com/s/agepbh2agnduknz/camera.mp3" id="aud" />
Or you can set again your media src in js.
window.onload = function() {
aud.onloadedmetadata = function doSomething(event) {
console.log(aud.duration);
}
aud.src = aud.src; // forces the event to fire again
}
<audio src="https://dl.dropboxusercontent.com/s/agepbh2agnduknz/camera.mp3" id="aud" />
*UAs have different behavior for this, e.g FF will store all the load events until all the inline scripts has been parsed. Safari and sometimes Chrome fire it as soon as they can.

How to add event listener in JS if html5 video fails to load

In a Django website I've built, users can add videos for others to see and comment on. Not all users have devices that support video playback, and thus for such edge cases, I want to allow video download.
To do this, I first need to detect whether the video failed or not. How can I do that? I have a working solution below, but with issues I need to resolve.
Currently I'm trying the following in my Django template (where all videos are listed using a ListView). This actually works, but breaks down if I reload the page:
<script>
var videos = document.querySelectorAll('video');
for (var i = 0; i < videos.length; i++) {
(function() {
var v = videos[i];
var s = v.querySelector('source');
//console.log(source);
s.addEventListener('error', function(ev) {
var d = document.createElement('div');
d.innerHTML = v.innerHTML;
console.log("hello")
console.log(v);
v.parentNode.replaceChild(d, v);
}, false);
}());
}
</script>
I.e. first I go through all video tags in the HTML page, then for each tag, I look up the source tag inside. Next, I try to add an event listener to the source tag, catch the error, and do some processing. However, I've found that the event listener is not fired if I reload the page. Maybe the event handler is being added too late; i.e. the browser already attempted to access the video source before the event handler was added. Can someone help me out here? Thanks in advance.
You can use load event of window to set src of <video> element, Node.replaceChild(), download attribute at <a> element
window.onload = function() {
var video = document.querySelector("video");
video.addEventListener("error", function(event) {
var a = document.createElement("a");
a.href = this.src;
a.innerHTML = "download media";
a.download = ""; // set suggested file name here
this.parentElement.replaceChild(a, this);
});
video.src = "media.file";
}
<video controls="">
<source src="" type="video/mp4">
</video>

How do I load a video into a HTML5 page with javascript using onclick

I want to call a function onclick (which I know works) then load it into the page:
I'm trying to create a video element in HTML5 including some attributes for it.
I know it works because I tested it with the following alert:
alert("createSmallVideo has been called");
I've commented the alert now and I know the function is being called but why isn't the video being displayed on the web page:
function createSmallVideo(){
//alert("createSmallVideo has been called");
var video = document.createElement("video");
video.setAttribute("id", "VideoElement");
video.setAttribute("src", "videos/small.ogv");
video.setAttribute("controls", "controls");
video.setAttribute("preload", "auto");
document.getElementById("#VideoContainer").appendChild(video);
}
What am I doing wrong? Please help!
Because there is no element on your page with an id of #VideoContainer (or if there is there shouldn't be). An element Id cannot contain a #. If you open your JavaScript console you'll probably find a null reference error message. Try removing the # from your call to document.getElementById().
you can preload it with javascript too
function loadVideo(videoUrl){
var video;
try {
video = new Video();
} catch(e) {
video = document.createElement('video');
}
video.src = videoUrl;
bindOnce(video, 'canplaythrough', function() {alert("Loaded");});
video.onerror = function(e){alert("Error");};
video.load();
}

Getting Current YouTube Video Time

I am writing a Browser Plugin and need to find a way to get the current time a YouTube Video playing on YouTube using JavaScript. I have been playing around in the Chrome JavaScript Console and haven't had any luck.
It appears that the chrome API only works with embedded video players not a video that is playing on on youtube.com. One option I looked into is in the share section of a video their is an input box for the "start at:" time that contains the current time of the video. I have tried using .value and .text on this input box and they both return undefined? Does anyone have any ideas?
ytplayer = document.getElementById("movie_player");
ytplayer.getCurrentTime();
See the api
Update: if it didn't work, also try player.playerInfo.currentTime (codepen live example)
Depends on what you want
player.getCurrentTime():Number
Returns the elapsed time in seconds since the video started playing.
player.getDuration():Number
Returns the duration in seconds of the currently playing video. Note
that getDuration() will return 0 until the video's metadata is loaded,
which normally happens just after the video starts playing.
http://code.google.com/apis/youtube/js_api_reference.html
Finally I found how to make it work on iOS (and Android too).
Actually, the whole youtube js api was broken for me if run on mobile browser.
Problem solved by creating player using new YT.Player as described in YouTube IFrame API.
Please note: only creating <iframe> from <div> placeholder works for mobile browsers at the time. If you try to use existing <iframe> in new YT.Player call, as mentioned in IFrame API, this will not work.
After player created, it's possible to use player.getCurrentTime() or player.getDuration() with player instance created.
Note: I had no luck calling this methods on player obtained with
player = document.getElementById(...) (from #JosephMarikle answer).
Only created player instance worked in mobile browsers.
Useful links:
YouTube IFrame API
YouTube JavaScript API
YouTube Player Demo
You can use Html5 Video API on youtube.com
var htmlVideoPlayer = document.getElementsByTagName('video')[0];
htmlVideoPlayer.currentTime
Note: It's not gonna work on Youtube Iframe API because Iframes are isolated. You cannot access the context of a Youtube IFrame .
In 2020, this works:
player.playerInfo.currentTime
full code:
see it live on codepen
Just FYI, There is a new iframe API for the YouTube player:
https://developers.google.com/youtube/iframe_api_reference
document.querySelector('video').currentTime
Stop at specific time youtube video and show notification box in GWD
<script>
var yid = document.getElementById("gwd-youtube_1");
var idBox = document.getElementById("box1");
pausing_function = function(event) {
var aa = setInterval(function() {
if (yid.getCurrentTime() > 8.0 && yid.getCurrentTime() < 8.1) {
yid.pause(yid);
idBox.style.opacity = 1;
console.log(yid.getCurrentTime() + "playing")
clearInterval(aa);
yid.removeEventListener("playing", pausing_function);
}
}, 100)
}
yid.addEventListener("playing", pausing_function);
var pausing_function_1 = function() {
if (yid.getCurrentTime() > 8.1) {
console.log(yid.getCurrentTime() + "pause")
// remove the event listener after you paused the playback
yid.removeEventListener("playing", pausing_function);
}
};
</script>
play video and hide notification
<script type="text/javascript" gwd-events="handlers">
window.gwd = window.gwd || {};
gwd.pauseVideo = function(event) {
var idBox = document.getElementById("box1");
idBox.style.opacity = 0;
};
</script>
<script type="text/javascript" gwd-events="registration">
// Support code for event handling in Google Web Designer
// This script block is auto-generated. Please do not edit!
gwd.actions.events.registerEventHandlers = function(event) {
gwd.actions.events.addHandler('gwd-youtube_1', 'playing', gwd.pauseVideo, false);
};
gwd.actions.events.deregisterEventHandlers = function(event) {
gwd.actions.events.removeHandler('gwd-youtube_1', 'playing', gwd.pauseVideo, false);
};
document.addEventListener("DOMContentLoaded", gwd.actions.events.registerEventHandlers);
document.addEventListener("unload", gwd.actions.events.deregisterEventHandlers);
</script>

Capture iframe load complete event

Is there a way to capture when the contents of an iframe have fully loaded from the parent page?
<iframe> elements have a load event for that.
How you listen to that event is up to you, but generally the best way is to:
1) create your iframe programatically
It makes sure your load listener is always called by attaching it before the iframe starts loading.
<script>
var iframe = document.createElement('iframe');
iframe.onload = function() { alert('myframe is loaded'); }; // before setting 'src'
iframe.src = '...';
document.body.appendChild(iframe); // add it to wherever you need it in the document
</script>
2) inline javascript, is another way that you can use inside your HTML markup.
<script>
function onMyFrameLoad() {
alert('myframe is loaded');
};
</script>
<iframe id="myframe" src="..." onload="onMyFrameLoad(this)"></iframe>
3) You may also attach the event listener after the element, inside a <script> tag, but keep in mind that in this case, there is a slight chance that the iframe is already loaded by the time you get to adding your listener. Therefore it's possible that it will not be called (e.g. if the iframe is very very fast, or coming from cache).
<iframe id="myframe" src="..."></iframe>
<script>
document.getElementById('myframe').onload = function() {
alert('myframe is loaded');
};
</script>
Also see my other answer about which elements can also fire this type of load event
Neither of the above answers worked for me, however this did
UPDATE:
As #doppleganger pointed out below, load is gone as of jQuery 3.0, so here's an updated version that uses on. Please note this will actually work on jQuery 1.7+, so you can implement it this way even if you're not on jQuery 3.0 yet.
$('iframe').on('load', function() {
// do stuff
});
There is another consistent way (only for IE9+) in vanilla JavaScript for this:
const iframe = document.getElementById('iframe');
const handleLoad = () => console.log('loaded');
iframe.addEventListener('load', handleLoad, true)
And if you're interested in Observables this does the trick:
import { fromEvent } from 'rxjs';
const iframe = document.getElementById('iframe');
fromEvent(iframe, 'load').subscribe(() => console.log('loaded');
Note that the onload event doesn't seem to fire if the iframe is loaded when offscreen. This frequently occurs when using "Open in New Window" /w tabs.
Step 1: Add iframe in template.
<iframe id="uvIFrame" src="www.google.com"></iframe>
Step 2: Add load listener in Controller.
document.querySelector('iframe#uvIFrame').addEventListener('load', function () {
$scope.loading = false;
$scope.$apply();
});
You can also capture jquery ready event this way:
$('#iframeid').ready(function () {
//Everything you need.
});
Here is a working example:
http://jsfiddle.net/ZrFzF/

Categories

Resources