Html video shows white screen when added dynamically using ajax - javascript

Using jQuery, I'm sending an AJAX request that will send back JSON data with HTML code. The html code will then be appended to the document's body. Here is what I'm doing:
$.get('get.php', { req: 'video_html' }, function (data) {
if (data.responsetype === "SUCCESS") {
$(document.body).append(data.video_html);
}
});
The video_html code is as following:
<video id="newVideo" src="http://.... .mp4" preload="yes">
Your browser does not support video playing.
</video>
The video is added to the document body successfully, the URL (src attribute) is also linked properly to the video but it shows a white screen instead. Anyone knows why?

I added a timeout and it worked:
$.get('get.php', { req: 'video_html' }, function (data) {
setTimeout(function(){
if (data.responsetype === "SUCCESS") {
$(document.body).append(data.video_html);
}
}, 1000);
});

Related

How to get data into the HTML page of an ExtensionSidebarPane?

I have successfully created a ExtensionSidebarPane which displays some data I have in stored in local storage:
saving the data:
localStorage.setItem('savedDataForReview',JSON.stringify(savedDataObject));
creating and updating the panel:
chrome.devtools.panels.elements.createSidebarPane("Data Reviewing Panel",
function() {
chrome.devtools.inspectedWindow.eval(
'localStorage.getItem("savedDataForReview")',
function (result) {
pane.setObject(JSON.parse(result));
}
);
});
This works nicely. However I now want to improve the pane to have some tables and buttons, so I need to use HTML instead of just setting a JSON object. So I need to use
pane.setPage('html/my_reviewing_pane.html');
in place of the setObject line.
This works, however I can't seem to get access to local storage from within that pane HTML page.
If I include some javascript to access my saved data localStorage.getItem('savedDataForReview') then it returns null.
How can I pass data into the HTML page on an ExtensionSidebarPane? I imagine this is a scoping issue but I am not sure how I can get around it. I can't even easily build the HTML from within the function where the data is in scope, because setPage takes a local file path rather than an HTML string.
Hope someone can help.
In the end, I went with using a background script and messaging passing. Thank you #wOxxOm for the pointers.
I added a background script background.js, adding to the manifest.json:
...
"background": {
"scripts":["background.js"],
"persistent":false
},
...
In my background.js script I added the following code so that it can receive messages from anywhere in the extension (content scripts, panel JS or pane JS):
chrome.runtime.onMessage.addListener(function(rq, sender, sendResponse) {
if (rq.action=="getData") {
sendResponse(getData());
return true;
} else if (rq.action=="deleteData") {
sendResponse(deleteData());
} else if (rq.action=="storeData") {
sendResponse(storeData(rq.data));
} else {
console.log('received unrecognized request:');
console.dir(rq);
sendResponse(null);
}
return true;
});
function storeData(object) {
localStorage.setItem("savedDataForReview",JSON.stringify(object));
return true;
}
function getData() {
return JSON.parse(localStorage.getItem('savedDataForReview'));
}
function deleteData() {
localStorage.removeItem('savedDataForReview');
return true;
}
Then within my content script I send storage messages to the background script like this:
function getData(callback) {
chrome.extension.sendMessage({action: "getData"}, function(resp) {
callback(resp);
});
}
function storeData(callback, data) {
chrome.extension.sendMessage({action: "storeData", data: data}, function(resp) {
callback(resp);
})
}
function deleteData(callback) {
chrome.extension.sendMessage({action: "deleteData", data: data}, function(resp) {
callback(resp);
})
}
storeData(function(response) {
console.log(`response from storing data was: ${response}`);
},data);
And in my pane's HTML page my_reviewing_pane.html I include a javascript file:
<h2>Reviewing Pane</h2>
<div id="review_table">
</div>
<script src="my_reviewing_pane.js"></script>
In that javascript file my_reviewing_pane.js I access the stored data by sending a message to the background script like this:
function getData(callback) {
chrome.extension.sendMessage({action: "getData"}, function(resp) {
callback(resp);
});
}
getData(function(savedDataFromStorage) {
let tableDiv = document.getElementById("review_table");
console.dir(savedDataFromStorage);
// now set HTML content into tableDiv.innerHTML using data from savedDataFromStorage...
});
Finally I create and set the pane from within the javascript of my devtools page:
chrome.devtools.panels.elements.createSidebarPane("Reviewing Pane",
function (pane) {
pane.setPage('my_reviewing_pane.html');
}
);
I decided to use HTML5 Local Storage rather than Chrome storage because I didn't need syncing and didn't want the size limits - but I think Chrome storage looks more powerful for a lot of use cases. See this article.
Hope this is useful to someone else.

Load video source into videojs or mediaelementjs dynamically from ajax?

I need to load video source, multiple types, from another website, which on get returns text link into video.
For example i open:
http://www.getthisvideoexample.com?whichvideo=id0
it shows in web browser text link:
http://someotherserver.com/somesubdomainrandomuniquenumber/thisisyourvideovalidforsometime.mp4
or
http://www.getthisvideoexample.com?whichvideo=id0&webm=true
and it shows in web browser text link:
http://someotherserver.com/somesubdomainrandomuniquenumber/thisisyourvideovalidforsometime.webm
But this server sometimes, when load is high,returns 500 error.
So i need to handle it all.
Lets take for example:
<video id="myVideo"></video>
var player = new MediaElementPlayer('#myVideo', {
type: ['video/mp4', 'video/webm'],
success: function (mediaElement, domObject) {
var sources = [
{ src: "HOW_TO_PUT_HERE_DYNAMICALLY_LOADED_MP4_LINK?", type: 'video/mp4' },
{ src: "HOW_TO_PUT_HERE_DYNAMICALLY_LOADED_WEBM_LINK?", type: 'video/webm' }
];
mediaElement.setSrc(sources);
mediaElement.load();
mediaElement.play();
}
});
Also how to make it so, that if 500 or other error is returned instead of link to video, code will just wait few seconds and try again, or display message with text "trying again, wait...."?
Thanks.
I would try a different approach.
I would place an ajax request (using jQuery.ajax()) within a setInterval loop (every 2 seconds perhaps). If the AJAX request, either
http://www.getthisvideoexample.com?whichvideo=id0 // returns a MP4 file
... or
http://www.getthisvideoexample.com?whichvideo=id0&webm=true // returns a webm file
... is successful, then clear the interval (clearInterval()), otherwise keep trying until the server responds successfully (you may need to set a method to clear the interval after some time in case the server is not available, otherwise you will end up in an infinity loop)
How-to?
If the ajax request is successful, then I would build the <video> tag structure with the response and append the tag to a video container (a <div> perhaps)
Then I would bind MEJS to the selector of the newly appended tag like :
var URL = "http://www.getthisvideoexample.com?whichvideo=id0 "; // request video URL
jQuery(document).ready(function ($) {
var getVideo = setInterval(function () {
$.ajax({
url: URL,
cache: false,
dataType: "json", // or else
success: function (response) {
clearInterval(getVideo); // ends loop
// build video tag
// select proper type, based on response
var video = '<video id="video_player" width="320" height="240" controls>' +
'<source src="' + response + '" type="video/' + (response.indexOf("webm") == -1 ? 'mp4' : 'webm') + '" />' +
'</video>';
// target container's selector
$("#videoContainer")
.html(video) // insert video tag
.find("#video_player") // find video selector after insertion
// bind MEJS
.mediaelementplayer({
// MEJS options
});
},
error: function () {
// error in ajax, will try again in 2 seconds
}
});
}, 2000);
}); // ready

Build HTML5 video content, then play video on click event iOS

I have a content area that gets dynamically loaded with new content when you press the previous or continue buttons. A simple example of html is:
<div id="contentArea"></div>
<nav>
<ul>
<li class="butPrev">Previous</li>
<li class="butNext">Next</li>
</ul>
</nav>
What I used to do in iOS6 is have a mask over the content area on first load that I could click to trigger audio and video and then all other dynamic HTML5 videos would play. I am not sure about iOS7, but iOS8 doesn't allow this. I would have to do it for each page, which defeats the purpose of the mask and is a pain for a user.
As an alternative, I am trying to trigger the play of videos with the next button click. The problem is that the next button captures the dynamic content, loads it into the content area and at that time needs to trigger the play, which iOS doesn't like. Is there any way to wait until the content area is loaded, while staying within the click event so it doesn't get blocked? Here is what I am trying (I have stripped out the Ajax stuff):
var contentLoaded = false;
$('nav li').click(function(){
contentLoaded = false;
//load HTML with HTML5 video via Ajax
//when done, sets contentLoaded = true
triggerAutoplay();
});
function triggerAutoplay() {
if (contentLoaded) {
$('video[autoplay]').each(function(){
if ($('this').attr('autoplay') != "false") {
this.play();
}
});
} else {
setTimeout(triggerAutoplay,100);
}
}
im not sure if i understand you right, but maybe you should call the play in the success of your ajax call like so:
$('nav li').click(function(){
$.ajax({
url: "whatever"
}).done(function() {
//do some stuff
triggerAutoplay();
});
});
function triggerAutoplay() {
$('video[autoplay]').each(function(){
if ($('this').attr('autoplay') != "false") {
this.play();
}
});
}
The play trigger has to be within the click function, so I have to set async to false so that the ajax completes before the function is call like:
$('nav li').click(function(){
$.ajax({
url: "whatever",
async: false
});
triggerAutoplay();
});
function triggerAutoplay() {
$('video[autoplay]').each(function(){
if ($('this').attr('autoplay') != "false") {
this.play();
}
});
}

jquery play sound on body replacement

I have a simple site which gets refreshed once every 30 seconds via a jquery full body refresh.
Now once a page refresh occurs I want a short sound to play and I tried to do this with various methods.
the methods work on my pc (IE, chrome and firefox) but the target is a samsung smart tv.
this is my site refresh with the sound added:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
function update_site() {
$.ajax({
url: "test.html",
dataType: "html",
cache: false,
success: function(data) {
// Replace body with loaded site. You can do more checks here to check
// if the fetched content is all there.
var body_html = data.replace(/^[\S\s]*<body[^>]*?>/i, "")
.replace(/<\/body[\S\s]*$/i, "");
$('body').html(body_html);
$('.last_connect').css('background-color', 'blue');
$("#goldengun").get(0).play();
},
error: function(data) {
$('.last_connect').css('background-color', 'red');
}
});
}
// Run every 20 secs.
window.setInterval(function() {
update_site();
}, 20000);
</script>
<style>
.last_connect {
background-color: green;
position: fixed;
top: 0px;
right: 0px;
height: 4%;
width: 2%
}
</style>
</head>
<body>
<div class="last_connect">
</div>
<audio id='goldengun'>
<source src="test.mp3" type="audio/mpeg">
</audio>
<button type="button" onclick="update_site();">update site!</button>
</body>
</html>
like I said this works in my browsers but not on the smart tv, the window refreshes successfully but the sound does not get played. However if I make a single function which ONLY plays the audio and call that on my setinterval it works. If call that function from my update_site() function it doesn`t work. it seems to me this some kind of syncing issue where the browser has not yet loaded everything and it already request to play the sound.
Does anyone have an idea on how to fix this?
help would be greatly appreciated.
use Buzz ( http://buzz.jaysalvat.com/ ). I love it. It uses html5 audio and can play ogg, mp3, and wav as long as the browser supports in in js without creating an audio element.
Example:
function playSound(){
var mySound = new buzz.sound( "/sounds/sound", {
formats: [ "ogg", "mp3", "aac" ]
});
mySound.play();
}
or even simpler:
var sound = new buzz.sound('assets/audio/sound.mp3');
and then where you call the function, call sound.play();
Unless and maybe even if you are dynamically creating sound files, you should know the names. So load the body with jQuery's .load() like so:
$('body').load('newPage.html body');
now you can know when the load is complete instead of a refresh which one can't listen for.
So do:
var sound = new buzz.sound("/sounds/sound.mp3");
$('body').load('newPage.html body', function(){
sound.play();
});
So what this does is it defines the sound, then loads newPage.html's body into the current page's body and when that is done, it plays the sound.
I recommend having the new sound associated with the new page's name or store in a variable.
Suppose I need to load new page and play sound ' abc.mp3 ' on click of an element, I can do:
var sound = new buzz.sound('/sounds/sound.mp3');
$('.element').click(function(){
var pageToLoad = 'abc';
$('body').load(pageToLoad+'.html body', function(){
sound = new buzz.sound('sounds/'+pageToLoad+'.mp3');
sound.play();
});
});
What this does it defines the sound. Then on an event, in this case on click of anything with the class="element", it loads the body of page abc.html and then plays abc.mp3 once that loading is finished.
Unable to test, but perhaps something like this would work?
The following script in the test.html page:
<script type="text/javascript">
var aud = $('<audio>').attr('id', 'goldengun');
var src = $('<source>').attr('src', 'test.mp3').attr('type', 'audio/mpeg');
aud.append(src);
</script>
The following function in caller page:
function update_site() {
$.ajax({
url: "test.html",
dataType: "html",
cache: false,
success: function(data) {
// Replace body with loaded site. You can do more checks here to check
// if the fetched content is all there.
var body_html = data.replace(/^[\S\s]*<body[^>]*?>/i, "")
.replace(/<\/body[\S\s]*$/i, "");
$('body').html(body_html);
$('.last_connect').css('background-color', 'blue');
$('body').append(aud);
aud.get(0).play();
},
error: function(data) {
$('.last_connect').css('background-color', 'red');
}
});
}
window.setInterval(function() {
update_site();
}, 1000);
Or just try:
function update_site() {
$.ajax({
url: "test.html",
dataType: "html",
cache: false,
success: function(data) {
// Replace body with loaded site. You can do more checks here to check
// if the fetched content is all there.
var body_html = data.replace(/^[\S\s]*<body[^>]*?>/i, "")
.replace(/<\/body[\S\s]*$/i, "");
$('body').html(body_html);
$('#goldengun', body_html).get(0).play();
$('.last_connect').css('background-color', 'blue');
},
error: function(data) {
$('.last_connect').css('background-color', 'red');
}
});
}
It's quite likely that the browser itself under Android is disallowing .play() calls in a timed loop.

How To Call Function on page Loading

I'm Using Web service using AJAX Call In My HTML Page . Web Service Returning Data Nearly 30 to 40 second's .
During This Loading Time I Need to Use Some Loading Gif Images After Data Completely Received Form Web Service The Loading Image Must Be Hide.
I'm Using Only HTML,JAVASCRIPT,CSS,J Query.
Any Idea Or Samples Needed.
I'm Using Following Code
$(document).ready(function () {
document.write('<img src="http://www.esta.org.uk/spinner.gif">');
});
$( window ).load(function() {
//This following Function Related To My Design
jQuery(".chosen").data("placeholder", "Select Frameworks...").chosen();
var config = {
'.chosen-select': {},
'.chosen-select-deselect': { allow_single_deselect: true },
'.chosen-select-no-single': { disable_search_threshold: 10 },
'.chosen-select-no-results': { no_results_text: 'Oops, nothing found!' },
'.chosen-select-width': { width: "95%" }
}
for (var selector in config) {
$(selector).chosen(config[selector]);
}
});
In The Above Code My Problem Is On Page Load Gif Image Show But It's Not Hide Only Gif Image Only Showing.
Put a hidden image on your page and as soon as your ajax call is made, make that image visible
$('#image').show();
$.ajax({
complete: function(){
$('#image').hide();
}
});
and hide that image again on Complete of Ajax call.
Use your ajax request callback (on success/failure) instead of page load.
When sending the request just show a gif animation by setting the Display to block
then when you have the data set the display to none
or use jquery
function showHourGlass()
{
$("#gifimage").show();
}
function hideHourGlass()
{
$("#gifimage").hide();
}
You ask for ideas, I have one sample -
http://www.myntra.com/shoes
load scroll down fastly this is the ajax jquery request which is exact output which you have mentioned in your question
Check source code
Jquery Ajax loading image while getting the data
This what the html looks like:
<button id="save">Load User</button>
<div id="loading"></div>
and the javascript:
$('#save').click(function () {
// add loading image to div
$('#loading').html('<img src="http://preloaders.net/preloaders/287/Filling%20broken%20ring.gif"> loading...');
// run ajax request
$.ajax({
type: "GET",
dataType: "json",
url: "https://api.github.com/users/jveldboom",
success: function (d) {
// replace div's content with returned data
// $('#loading').html('<img src="'+d.avatar_url+'"><br>'+d.login);
// setTimeout added to show loading
setTimeout(function () {
$('#loading').html('<img src="' + d.avatar_url + '"><br>' + d.login);
}, 2000);
}
});
});
I hope this will help you.

Categories

Resources