How can i Check if <object> failed to load? - javascript

I have the following code:
document.getElementById("launcherDiv").innerHTML =
"<object id='launcher'
classid='CLSID:17E88883-3488-46B8-BE4D-30568888855'
codebase='Helper.CAB#version=8,8,8,88'>
</object>";
Let say the download/installing failed,
How can I know this? depending of it that I can't know how much time it supposed to take..
If I will check in a loop how can I know when to end?
previously I used to define the tag inside the HTML and it waiting until the installation finished or failed.
But now I need delay loading of this ActiveX so I can't use this
Can anyone help me?

If object tag is failed to load then it will render inner HTML between tag. For example
<object data="my/file/path.pdf">Object not supported</object>
If object fails then it will show inner text i.e. "Object not supported"

Maybe this helps:
var iv = setInterval(function () {
if (document.all["launcher"].readyState == 4) {
clearInterval(iv)
alert("Object loaded")
}
}, 100);
What it does is set an interval which checks the readystate every 100 seconds and if the object has loaded it alerts.

I know this is a old post but I was trying something like this my self.
In the object tag you can do something else inside it.
For example I was making a music site and If the custom player didnt load I wanted the audio tag to take over.
example:
<object>
<load customplayer> <!--==If this fails do the next line ==-->
<audio>
load song
</audio>
</object>

The only difference between the (first) anchor in an object that successfully loaded embedded content and the fallback content (first) anchor in an object that did not successfully load are the dimensions of the element. So all you have to do is determine your policy of the element you use for fallback (this is very likely an anchor element though some people might still support Flash as fallback content) and then target that element and get it's height in example; if the height is greater than 0 the object element did not successfully load.
var o = document.getElementsByTagName('object');
console.log(o[0].getElementsByTagName('a')[0].getBoundingClientRect().height);

Related

How should I register event handlers to a video that is handled by the videojs?

I want to register an event handler to a video that is handled by the videojs but I can`t select the element in a reliable manner because the videojs removes the attributes from the video tag and add them to a container element that it adds.
videojs seems to append the same suffix: _html5_api to every video element ID, when it is wrapped inside the container div. Quoting from the source:
// Update tag id/class for use as HTML5 playback tech
// Might think we should do this after embedding in container so .vjs-tech class
// doesn't flash 100% width/height, but class only applies with .video-js parent
tag.id += '_html5_api';
So, one would argue that, a trivial fix would be something like this:
var vid = document.getElementById("ORIGINALVIDEOID_html5_api")
Of course, this hack lacks reliability since this suffix might change in future versions. However, one thing that is unlikely to be changed in the future, is the presence of the video element (albeit with a different ID) inside the wrapper div.
So, a more reliable way to obtain the video element per se is (assuming that the video tag ID is "cool"):
videojs("cool").ready(function(){
// Approach 1
var video1 = this.contentEl().querySelector("video");
console.log("video1");
console.log(video1);
// Approach 2
var video_id = this.contentEl().querySelector("video").getAttribute("id");
var video2 = document.getElementById(video_id);
console.log("video2");
console.log(video2);
// Not really needed, but here is a test that both approaches yield the same result
console.log("video1 === video2 ?")
console.log(video1===video2)
})
which yields in Firefox:
I included two approaches in the above script: one straightforward and one indirect (via the document and using the acquired ID). Of course you can use whichever of video1 and video2 you want.
A few things to note here:
This works only when inside a videojs().ready() function; this is a way to be 100% sure that the player is loaded
contentEl() returns the wrapper div and then, querySelector() is used on it to access the video element.
The other answers are trying to get a video element within the player but this is flawed as the player tech can be something other than a video element, e.g. the Flash tech. You should use the video.js API to listen to the events which will be surfaced from the tech.
var player = videojs("id");
player.on('play', function() {…});

How to use window.location with randomized objects?

I've made a site that randomizes HTML videos or images just to practice my javascript.
I am trying to make it so that each time a video is randomized the URL location will change to represent the new video, this way users would be able to link directly to a video that was randomized.
Currently it only displays a static url that does not change whenever content is loaded.
Here is the obligatory codepen
Codepen
function chooseRandomVideoFromList() {
var i = Math.floor(Math.random() * currentList.length);
var video = currentList[i];
var $video = $('video');
// clear
$video.html('');
// <source src="" type="">
video.sources.forEach(function (source) {
var $source = $('<source>').attr('type', source.type).attr('src', source.src);
$video.append($source);
});
Any help or advice would be greatly appreciated, i've read the documentation and I am still stumped :S
Thanks guys!
You cannot directly write on the window.location.href property, but you may change your sites url with the html5 history api and pushstate.
Example:
history.pushState({}, "Stackoverflow", "http://stackoverflow.com");
This should work in all modern browsers, see: http://caniuse.com/#search=pushstate
More information on this topic could be found here: https://developer.mozilla.org/de/docs/Web/Guide/DOM/Manipulating_the_browser_history
Though keep in mind you need also to listen on popstate events if you want the users to be able to use their browsers back and forward buttons. Also your server side code needs to handle the urls.
If you need to support older browsers or don't want the server side to be involved you could set the window.location.hash property instead which does not change the url itself but let you change the hash part of the current url, for example:
window.location.hash = "uri=stackoverflow.com";
This way you might store the Index of the video currently shown. When loading the page you might want to check if there's a value in "window.location.hash" and if it is a valid index for your videoFiles. If so you should play that video.
Example (insert in your starting code):
if (window.location.hash !== "") {
showSpecificVideoFromList(window.location.hash);
}
And this one in your chooseRandomVideoFromList:
window.location.hash=i;
Then implement your showSpecificVideoFromList in order to show the given index (and check for validity)

How to correctly replay any flash .swf file using Javascript?

I am trying to replay a .swf flash file using javascript.Currently I am aware of two methods of doing this:
1) hide the element and show it again
2) select the DOM element of the swfobject and call .Rewind() and .Play()
http://jsfiddle.net/me2loveit2/4qth8/
//method one
$('#objectID').hide();
setTimeout(function(){
$('#objectID').show();
},10)
//Method 2
document.getElementById('objectID').Rewind();
document.getElementById('objectID').Play();
The problem with hide and show is that it sometimes flashes on the screen and is visually unappealing.
And the problem with .Rewind() or .GotoFrame(0) and .Play() is that it only rewinds the main timeline.(notice only the second green block resets and animates)
I usually have no control or way to change anything within the flash, so I am trying to find a solution that does not involve editing the flash file.
Is there is a way to get the name of all the movie clips that are in the swf using Javascript?. Then I could rewind them individually using .TGotoFrame('movieclip',0)
Can I trigger the same events that hide and show do without actually hiding and showing the element? (How?)
Or is there a better way to replay?
You could also restart it without the 10ms delay by using swfobject to rewrite the swf tag:
$(document).on('click','#replay3',function(){
swfobject.embedSWF("http://philipp.werminghausen.us/testing/test.swf", 'replace', 275, 200, "9", null, {}, params, {}, function (res) {});
});
Example:
http://jsfiddle.net/5jqW4/
I found another way to do it as well by removing and reinserting one of the <param> tags.
This way I don't need to re-create the object:
http://jsfiddle.net/me2loveit2/5jqW4/10/
var param = $('#swf_movie').children().first().detach();
$('#swf_movie').append(param);

How to Catch NETWORK_NO_SOURCE Errors with an HTML5 Video Tag

If none of the < source > tags provided for an HTML5 < video > tag are playable, I want to display an error.
According to this page on the Mozilla Developer Network, it seems I have to check the networkState property of the video element to see if any sources loaded, as each seperate source tag throws its own error when it fails to load.
To detect that all child elements have failed to load, check the value of the media element's networkState attribute. If this is HTMLMediaElement.NETWORK_NO_SOURCE, you know that all the sources failed to load.
But at what point should I check the networkState? If I check immediately on calling video_tag.load(), it always tells me the networkState is NETWORK_NO_SOURCE even if the source elements are valid and the video plays fine. Therefore, I assume I hvae to wait until the source tags have been tried by the browser.
Here's the test:
var state = this._video_tag.networkState;
console.log( 'networkState', state );
if( state == this._video_tag.NETWORK_NO_SOURCE )
{
throw new Error( 'No valid sources' );
}
I have tried all of the following video element events with invalid source tags: loadstart, loadedmetadata, loadeddata & error with the following results (in Firefox):
loadstart: called but networkState is NETWORK_LOADING
loadedmetadata: not called
loadeddata: not called
error: not called
However, if I check out the video tag in Firebug, the networkState is NETWORK_NO_SOURCE just as expected.
What event should I be using to control when to check the video tag, or is there a better way of doing this?
If you are using source tags you can set the onerror attribute on the last source tag in the list instead. See the bottom of section 4.8.8 on this page for more details.
Quote from that reference:
If the author isn't sure if user agents will all be able to render the
media resources provided, the author can listen to the error event on
the last source element and trigger fallback behavior:
<script>
function fallback(video) {
// replace <video> with its contents
while (video.hasChildNodes()) {
if (video.firstChild instanceof HTMLSourceElement)
video.removeChild(video.firstChild);
else
video.parentNode.insertBefore(video.firstChild, video);
}
video.parentNode.removeChild(video);
}
</script>
<video controls autoplay>
<source src='video.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<source src='video.ogv' type='video/ogg; codecs="theora, vorbis"'
onerror="fallback(parentNode)">
...
</video>
This example isn't perfect because you don't get the event object like you do when the onerror attribute is on the video tag (which only works if you have a src attribute in the video tag instead of in a series of tags. However, I believe you can then retrieve the error state from the video tag with the networkState JS variable on that tag. I haven't tested that though. So it is up to you at that point. It sounds like what I have here might be satisfactory for your needs.
Notes:
While you can instead listen for an "error" event on the last source tag, I found that this was unreliable. In cases where the preload attribute is not set to none, I could not find a way to reliably add a listener for the event before the event fired. This forced me to use the onerror attribute.
If you do find a way to reliably listen for the event I wanted to add this note. According to this Chromium issue the error event on the source tag does NOT bubble which means that you have to listen to it on that specific tag.
i used sth this to check network status of the videos. this is taken from official w3c html5 page ( http://dev.w3.org/html5/spec/Overview.html#the-video-element )
<script>
function failed(e) {
// video playback failed - show a message saying why
switch (e.target.error.code) {
case e.target.error.MEDIA_ERR_ABORTED:
alert('You aborted the video playback.');
break;
case e.target.error.MEDIA_ERR_NETWORK:
alert('A network error caused the video download to fail part-way.');
break;
case e.target.error.MEDIA_ERR_DECODE:
alert('The video playback was aborted due to a corruption problem or because the video used features your browser did not support.');
break;
case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
alert('The video could not be loaded, either because the server or network failed or because the format is not supported.');
break;
default:
alert('An unknown error occurred.');
break;
}
}
</script>
<video src="tgif.vid" autoplay controls onerror="failed(event)"></video>
The 'error' event is not called because it is triggered by the elements inside, and to make the event be triggered also on the element, you have to use the addEventListener method with the useCapture parameter set to true, like this:
video.addEventListener('error', callback, true);
And then inside the callback you can check the networkState property, which is going to be NETWORK_NO_SOURCE if the video cannot play the sources.
Check out the docs from MDN about addEventListener and the useCapture parameter
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

Toggling between instances of NiftyPlayer on a page - won't stop playing when hidden on IE

I've got a page with links to MP3s, when the link is clicked I use javascript to show a small Flash player (NiftyPlayer) under the link. When a different link is clicked, the old player is hidden and the new player is revealed.
The player auto-starts when the element is shown, and auto-stops when hidden - in Firefox.
In IE it will only auto-start and NOT auto-stop. This is what I would like to solve.
This is an example HTML with link and player
Misunderstood What You Said
<div id="player662431" class="playerhide"><embed src="http://www.example.com/shop/flash/player.swf?file=/mp3/Beat The Radar - Misunderstood What You Said.mp3&as=1" quality="high" bgcolor="#000000" width="161" height="13" name="niftyPlayer662431" align="" type="application/x-shockwave-flash" swLiveConnect="true" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>
Here is the javascript (I've got jQuery installed to let me hide all the open players on this page apart from the new one)
function toggle_visibility(id) {
$('.playerhide').hide();
var e = document.getElementById(id);
e.style.display = 'block';
}
I think what I need to do is start the player manually with javascript (rather than using the autostart as=1 function in the URL string)
There is some javascript that comes with NiftyPlayer to allow this EG
niftyplayer('niftyPlayer1').play()
there is also a stop method.
I need some help with javascript - how do I add this call to play into my toggle_visibility function (it has the same unique ID number added to the name of the player as the ID of the div that's being shown, but I don't know how to pull this ID number out of one thing and put it in another)
I also would like to be able to do
niftyplayer('niftyPlayer1').stop()
to stop the audio of the previously running player. Is it possible to store the current ID number somewhere and call it back when needed?
Thanks for the help, i'm a PHP programmer who needs some support with Javascript - I know what I want to achieve, just don't know the commands to do it!
Thanks
If you assigned each niftyplayer object a classname, f.x. ".players", then you could loop through each player, like this:
function toggle_visibility(id) {
$(".players").each(function(){
playerId = $(this).attr('id');
if(niftyplayer(playerId).getState() == 'playing') {
//Stop the currently playing player
niftyplayer(playerId).stop();
//Hide the div that was playing
$("#" + playerId).hide();
}
});
//Start the new player
niftyplayer(id).play();
$("#" + id).show();
}
So what this actually does, is it loops through all the players on the website. It checks if the status of each player is equal to "playing", if it is, then it stops it and hides the div tags. Then it starts the new player and shows that div tag.
I think this does it. Try it out.
I have a much better solution after I noticed a very nasty bug / 'feature' when using Internet Explorer in conjunction.
I had noticed that in IE the pages were taking a very long time to load when I had a lot of hidden Nifty Players, I looked closer using Fiddler and found that each instance of NiftyPlayer was preloading the MP3 in full, rather than loading on demand as with Firefox and Chrome etc.
This meant that a page with 100 items (each item having up to 4 MP3s) took several minutes to load at times with obvious data transfer implications.
My solution which is rather simpler (but maybe clunkier) than Indyber's is to just use
function toggle_visibility(id,mp3location) {
// hide all players
$(".playerarea").html('');
// show clicked player
$('#' + id).html('<embed src=\"http://www.xxx.com/shop/flash/player.swf?file=http://www.xxx.com/mp3/' + decodeURIComponent(mp3location) + '.mp3&as=1\" quality=high bgcolor=#000000 WMODE=transparent width=\"161\" height=\"13\" align=\"\" type=\"application/x-shockwave-flash\" swLiveConnect=\"true\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" class=\"playerNew\">');
}
which works fine with IE, and also solves the problem of not being able to stop the players from playing in IE

Categories