Javascript causes Chromium to run out of memory - javascript

I have a chunk of code that causes a graph that monitors a graph to update periodically and is displayed with a raspberry pi, but the problem I'm having is because of the Pi's limited memory, Chromium dies because it run out of memory. I think this is because when the image updates, it saves the older images somewhere. I've tried using JS to delete the image and create a new one with an updated image, but it didn't work. I'm not too familiar with Javascript so I wasn't sure if I was making a rookie mistake or something. Here is the code:
<script type= "text/javascript">
var graph = "http://www.example.com";
function preload()
{
try
{
var buffer = new Image();
buffer.src = graph;
buffer.onload = function()
{
while (1)
{
setTimeout(preload, 1000);
document.getElementById('graph').src = buffer.src;
}
}
}
catch(err)
{
txt = "Error\n" + err.message;
alert(txt);
}
}
preload()
</script>
And the HTML for the image is:
<img src= "http://www.example.com" id=graph width=1015
height=275 frameborder="0" onload="preload()" style="display: block;
margin-left: auto; margin-right: auto;" align="bottom"/>

Here is a vastly simplified script for you - your loop made no sense at all and there is no Ajax in your code
var graph = "https://zabbix.tulsahpc.org/signage/sign.png",tId;
window.onload=function() {
tId=setInterval(function() {
document.getElementById('graph').src = graph+new Date().getTime();// avoid cache
},10000);// reload every 10 secs
}

Related

Loading scripts before a function does not work in Chrome or Edge but it does in Firefox

Due to a client's request I have had to create a banner whose html content and Javascript code are loaded directly from a database (the modal comes empty and through a rest service I retrieve the html that is stored in the table).
The case is that in the code that is loaded from the database, there are 2 scripts, which are hosted in different places.
The first, createJS does not give problems, but the second, hosted on another client server (because it does not want us to upload it to the same project from which it is loaded) does not always load well and because of this, the main script does not work correctly.
To solve this problem, in the script that comes in the DB I have added a promise that will be executed after the loading of said script. This method has worked for me correctly for Firefox, but for Chrome I still get the same problem.
I leave here the code with the important parts.
This is the code stored in the database:
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script>
var canvas, stage, exportRoot, anim_container, dom_overlay_container, fnStartAnimation;
function initSol() {
canvas = document.getElementById("canvas");
anim_container = document.getElementById("animation_container");
dom_overlay_container = document.getElementById("dom_overlay_container");
var comp=AdobeAn.getComposition("XXXXXX");
var lib=comp.getLibrary();
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", function(evt){handleFileLoad(evt,comp)});
loader.addEventListener("complete", function(evt){handleComplete(evt,comp)});
var lib=comp.getLibrary();
loader.loadManifest(lib.properties.manifest);
}
function handleFileLoad(evt, comp) {
//some stuff
}
function handleComplete(evt,comp) {
//some stuff
}
function loadJs(src) {
return new Promise(function(resolve, reject) {
let scrp = document.createElement('script');
scrp.src = src;
scrp.onload = () => resolve(scrp);
document.body.append(scrp);
});
}
var prom = loadJs("https://www.customerweb.com/resources/popup-withdadobeancode.js?12345678");
prom.then(
scrp => initSol()
);
var urlCheck = "check";
var urlClose = "close";
</script>
<div id="animation_container" style="background-color:rgba(255, 255, 255, 0.00); width:910px; height:512px">
<canvas id="canvas" width="910" height="512" style="position: absolute; display: block; background-color:rgba(255, 255, 255, 0.00);"></canvas>
<div id="dom_overlay_container" style="pointer-events:none; overflow:hidden; width:910px; height:512px; position: absolute; left: 0px; top: 0px; display: block;">
</div>
</div>
Error messages (only in Chrome and Edge, Firefox works fine):
Uncaught TypeError: cjs.Bitmap is not a constructor at popup-withdadobeancode.js?12345678:14 at popup-withdadobeancode.js?12345678:1288 VM72:2
Uncaught (in promise) TypeError: AdobeAn.getComposition is not a function at initSol (:2:290) at :2:2103
In my opinion, I think the problem is loading the scripts. In Chrome, the code that requires the method AdobeAn.getComposition or cjs.Bitmap is executed before the script popup-withdadobeancode.js (which should be loaded first to avoid these errors), but I don't know how to make it run after loading.
Also, I can't load the script other than from the database as it doesn't depend on me...
You can use onLoad event to wait until all ressources are loaded,also you should try appending the script before resolving the promise.
var prom = loadJs("https://www.customerweb.com/resources/popup-withdadobeancode.js?12345678");
window.addEventListener('load', (event) => {
prom.then(
scrp => initSol()
);
});

Dynamic timed text track for captions on canvas video

I have researched and experimented my brains out on this one. I have built a working application that uses the HTML5 canvas to play videos and interact with users through a web page (a game, sort of). Works like a charm, but I want to add captions to the video to make it more accessible. I don't even seem to be able to get the WebVTT file to load and I've reached the stage of voodoo programming by trying examples from the web and am making no progress. I have tried to distill the application down to its bare minimum here in hopes someone can provide some insight into what I'm doing wrong.
The video plays when I click on the canvas, the "...waiting for cuechange event..." message stays up while it plays, and then it goes to the "video complete ... reload to try again" message when done (kept it simple by requiring a page reload to try the test again), so the basic mechanics seem to be working. It never gets into the "load" function for the text track (never displays "... loaded text track ..."), and the updateSubtitle() function is never invoked. If I insert a trackElement.readyStatus() call, it always returns 0 (unsurprisingly). As a further note, if I add a testStatus.innerHTML = "...loaded metadata..."; statement in the "loadedmetadata" listener, it does get there.
var canvasContext, videoElement, intervalHandle, testStatus, trackElement;
function processFrame() {
canvasContext.drawImage(videoElement, 193, 50, 256, 194);
}
function videoEnded() {
clearInterval(intervalHandle);
testStatus.innerHTML = "video complete ... reload to try again";
}
var count = 0;
function updateSubtitle(event) {
count = count + 1;
testStatus.innerHTML = "count" + count;
}
function clickHandler(event) {
testStatus.innerHTML = "...waiting for cuechange event...";
videoElement.setAttribute("src", "start.ogg");
videoElement.load();
intervalHandle = setInterval(processFrame, 25);
videoElement.play();
}
function init() {
var canvasElement, textTrack;
canvasElement = document.createElement("canvas");
videoElement = document.createElement("video");
videoElement.addEventListener("loadedmetadata", function() {
trackElement = document.createElement("track");
trackElement.kind = "captions";
trackElement.label = "English";
trackElement.srclang = "en";
trackElement.src = "start_en.vtt";
trackElement.addEventListener("load", function() {
testStatus.innerHTML = "... loaded text track ...";
trackElement.mode = "showing";
});
videoElement.appendChild(trackElement);
trackElement.addEventListener("cuechange", updateSubtitle, false);
});
var mainDiv = document.getElementById("arghMainDiv");
canvasElement.setAttribute("id", "mediaScreen");
canvasElement.width = 640;
canvasElement.height = 480;
var firstChild;
if(mainDiv.hasChildNodes()) {
firstChild = mainDiv.firstChild;
mainDiv.insertBefore(canvasElement, firstChild);
} else {
firstChild = mainDiv.appendChild(canvasElement);
}
testStatus = document.createElement("p");
testStatus.setAttribute("id", "testStatus");
mainDiv.insertBefore(testStatus, firstChild);
testStatus.innerHTML = "click on canvas to test";
canvasContext = canvasElement.getContext('2d');
canvasElement.addEventListener("click", clickHandler);
videoElement.addEventListener("ended", videoEnded);
}
#fatalError {
color: red;
}
#arghMainDiv {
text-align: center;
}
#mediaScreen {
border: 5px solid #303030;
margin-left: auto;
margin-right: auto;
display: block;
cursor: default;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Problems With TextTrack Object</title>
<link rel="stylesheet" type="text/css" href="subargh.css">
<script src="subargh.js"></script>
</head>
<body onload="init()">
<div id="arghMainDiv">
</div>
</body>
</html>
If you want the video and WebVTT files I'm using (just a few seconds long), they are here and here (respectively). I should also mention that if I play the video using VLC, that it recognizes and plays the .vtt file as subtitles properly on the video (so it appears to be well-formed). I am running my tests on Firefox 57.0.4 (64-bit) on a Windows 7 system if that makes any difference (but I am under the impression that Firefox is mostly fixed where Timed Text Tracks are concerned now).

ajax undefined after a thousand iterations

When creating an animation I try to use javascript for additional effects, namely snow being piled up and falling off the edges of the foreground. I figured that the javascript could do the "calculations" on a <canvas> that had the image, then send the "snow" to a php script that would create the png images. This is all placed on my local "server" because that is the only one that can write files.
<html>
<head>
<title>Making Snow</title>
</head>
<body bgcolor="black">
<canvas id="canvas" width="1920px" height="1080px"></canvas>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
var canvas;
var ctx;
var frame=-530;
var simg = new Image()
var dimg = new Image()
onload = function()
{
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
simg.src = "prodB/C/DGB.0530.png"
}
simg.onload = function()
{
var ipo=3;
// Initialize all pixels on the screen/page
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(simg,0,0);
document.title = "Making Snow " + (frame+530) + " / 7000";
snowdraw();
}
dimg.onerror = function()
{
dimg.src = "../imagewriting/snow" + zeroFill(frame+530,4) + ".png";
}
dimg.onload = function()
{
frame++;
if(frame<530)
simg.src = "prodB/C/DGB.0530.png"
else if(frame>4400)
simg.src = "prodB/C/DGB.4400.png"
else
simg.src = "prodB/C/DGB." + zeroFill(frame,4) + ".png"
}
var snowdraw = function()
{
var temp;
var canvasData = "";
// console.log(screen);
// Animation
// Choose a random pixel at the top of the screen
if(frame<7000)
{
for(ny=canvas.height-2; ny>=0; ny--)
{ // Iterate through all the pixels starting from the bottom right corner.
for(nx=canvas.width-2; nx>=0; nx--)
{
canvasData=canvasData+"1";
}
}
$.ajax({
method: "POST",
url: "makesnow.php",
data:{ imgData: canvasData, frame: (frame+530) }
})
.done(function( msg ) {
dimg.src = "../imagewriting/snow" + zeroFill(frame+530,4) + ".png";
});
}
else
{
document.title = "COMPLETE";
}
}
// http://stackoverflow.com/questions/1267283/how-can-i-create-a-zerofilled-value-using-javascript
// by Peter Bailey http://stackoverflow.com/users/8815
function zeroFill( number, width )
{
width -= number.toString().length;
if ( width > 0 )
{
return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
}
return number + ""; // always return a string
}
</script>
</html>
However, on the 1640th frame (or more precisely frame=1110) ajax is suddenly undefined. The image snow1640.png is created, but the browser tells me ajax is not defined and won't advance passed Making Snow 1640 / 7000. Because of the small random nature for each "snow flake" I can't just pick it up from where I left off, as the snow would jump from one frame to the next. Though I did try that at one point and ajax still stopped after that frame.
I first ran it on the local machine running Firefox (http://127.0.0.1/...) then moved onto another machine on the network which is more powerful running Chrome and both died on that same frame. Thought it might be a memory or file limit so I moved the complete frames out of there. Still nothing.
EDIT: Code now snippit of just the problem.
Also, console.log for data and ajax.responseText seem to be generally empty, both during successful "renders" and when it starts iterating ajax is not defined (every other line empty, every other error).
EDIT: New development! Turns out that the error ReferenceError: ajax is not defined anyways gets called between frames (and the 404 when asking dimg if image was created).
EDIT: By typing in console.log($.ajax) after onload and commenting out simg.src I got function ajax().
Error persists, this time I expanded it to reveal the following:
success http://127.0.0.1/ag/makesnowBC.html 197:7
j http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 2:27131
fireWith http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 2:27949
x http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 4:22242
b http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js 4:26298
EDIT: Changed the code to now use Synchronous ajax. This time there are no error messages what so ever, but it still stops at 1640.

2 or more async requests in javascript to load image or do anything else

Single request and response model at one time do not utilizes full network/internet bandwidth, thus resulting in low performance. (benchmark is of half speed utilization)
how to make this code use 2 or 3 or more async requests instead of one.(ajax)
or do i need multi threading? and is it possible in javascript?
(this is for making a video out of an ip )
every time the image changes on request. and yes i need to be async with multiple fetch requests (not single as i explained above) or you recomend threads?
<html>
<head> <script language="JavaScript">
// Global vars
img = 'http://pastebin.com/i/t.gif';
timeout = 1000;
next = 0;
function onLoad( ) {
setTimeout( 'reloadImage( )', timeout );
}
// Reloader
function reloadImage( ) {
next = ( new Date( ) ).getTime( ) + timeout;
document.images.dv.src = img + "?" + next;
}
</script>
</head>
<body>
<img src="img" name="dv" onLoad="onLoad( )">
</body>
</html>
and
<html>
<head>
</head>
<body>
<div id="container"></div>
<script language="JavaScript">
var canLoad = true;
var container = document.getElementById("container");
var image = document.createElement("img");
image.onload = function() {
canLoad = true;
console.log("Image reloaded.");
}
var imageUrl = "http://url/snapshot.jpg";
var fps = 2;
container.appendChild(image);
function loadImage() {
if (canLoad) {
canLoad = false;
var str = new Date().getTime();
image.setAttribute("src", imageUrl + "?" + str);
console.log("Reloaded now.");
} else {
console.log("Can't reload now.");
}
}
setInterval(loadImage, fps); // 30 fps
</script>
</body>
</html>
Not actually tested, and I think it'll very likely to cause a "stack overflow" eventually (if you directly implement it), but you may still give it a look:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(){
var img="/*url*/";
var interval=50;
var pointer=0;
function showImg(image,idx)
{
if(idx<=pointer) return;
document.body.replaceChild(image,document.getElementsByTagName("img")[0]);
pointer=idx;
preload();
}
function preload()
{
var cache=null,idx=0;;
for(var i=0;i<5;i++)
{
idx=Date.now()+interval*(i+1);
cache=new Image();
cache.onload=(function(ele,idx){return function(){showImg(ele,idx);};})(cache,idx);
cache.src=img+"?"+idx;
}
}
window.onload=function(){
document.getElementsByTagName("img")[0].onload=preload;
document.getElementsByTagName("img")[0].src="/*initial url*/";
};
})();
</script>
</head>
<body>
<img />
</body>
</html>
What it does:
When the initial image loads, preload() is called;
When preload() is called, it creates 5 image cache, and each attach its onload event to showImg();
When showImg() is called, it checks whether the current index is behind current pointer, and if it does, replace the current image with this new one, and call preload();
Back to 2.
If you really going to implement this, increase interval and decrease i<5. Also, a caching/queuing mechanic to check how many images in cache/queue before loading the next queue would be nice.
Also, notice that I didn't use getElementById to get the image, because there will be no stable ID.

IE Copy Canvas in Pop-Up Window DOM Exception: TYPE_MISMATCH_ERR (17)

I don't know if there is a work around for this IE9 issue I ran into, but here's what I'm trying to do. I have an image in a canvas on my page. I want to copy this canvas image to another canvas, but in a pop-up window I create. What I'm encountering in this experiment is I can copy the canvas image into another dynamically created canvas on the same page, no problem. But when I try to do it in a pop-up window, IE gives me a DOM Exception: TYPE_MISMATCH_ERR (17). Sadly, this seems to be an IE thing, because I ran my same code in Chrome, and it worked...
So here's my code. You'll need to provide your own image though, I used a simple 640x480 jpeg file. You'll also need the console open, since I'm doing a console.error. I also tried this code as a file and running from localhost on my local IIS.
<!DOCTYPE html>
<html>
<head>
<title>Canvas Copy Test</title>
<style>
#mainSrc {
border:1px solid red;
}
#dest01 {
width:640px;
height:480px;
border:1px solid blue;
}
</style>
<script>
var destWin; // Destination Window
window.onload=function()
{
var testImg = new Image();
testImg.src = "me.jpg";
testImg.onload = function()
{
var mainCanvas = document.getElementById("mainSrc");
var mainCtx = mainCanvas.getContext("2d");
mainCtx.drawImage(testImg,0,0);
}
var copyBtn = document.getElementById("copyBtn");
var copyWinBtn = document.getElementById("copy2WinBtn");
copyBtn.addEventListener("click",copyImage,false);
copyWinBtn.addEventListener("click",copy2Win,false);
}
// Copy Canvas Image to Another on the same page.
function copyImage()
{
var mainCanvas = document.getElementById("mainSrc");
var destCanvas = document.createElement("canvas");
var destDiv = document.getElementById("dest01");
destCanvas.width = mainCanvas.width;
destCanvas.height = mainCanvas.height;
var dCtx = destCanvas.getContext("2d");
dCtx.drawImage(mainCanvas,0,0);
destDiv.appendChild(destCanvas);
}
// Copy Canvas to Popup Window
function copy2Win()
{
var mainCanvas = document.getElementById("mainSrc");
try {
destWin = window.open("","destWin");
var destWinDoc = destWin.document;
var destWinHTML = "<!DOCTYPE html><html><head><title>POPUP</title><body><div id='destWinDiv' style='width:640px; height:480px; border:1px solid red'></div></body></html>";
destWinDoc.write(destWinHTML);
var destCanvas = destWinDoc.createElement("canvas");
var destDiv = destWinDoc.getElementById("destWinDiv");
destCanvas.width = mainCanvas.width;
destCanvas.height = mainCanvas.height;
var dCtx = destCanvas.getContext("2d");
dCtx.drawImage(mainCanvas,0,0);
destDiv.appendChild(destCanvas);
}
catch (err)
{
console.error(err);
}
}
</script>
</head>
<body>
<canvas id="mainSrc" width="640" height="480"></canvas>
<p>
<input type="button" name="Copy" value="Copy" id="copyBtn" />
<input type="button" name="Copy2Win" value="Copy To New Window" id="copy2WinBtn" />
</p>
<div id="dest01"></div>
</body>
</html>
Well, after playing around a little more, I figured out that the tag can actually take in a base64 encoded image from the canvas toDataURL() and display it... So I was able to make this modification in my above copy2Win function to be this:
function copy2Win()
{
var mainCanvas = document.getElementById("mainSrc");
destWin = window.open("","destWin");
var destWinDoc = destWin.document;
var destWinHTML = "<!DOCTYPE html><html><head><title>POPUP</title><body><div id='destWin' style='width:640px; height:480px; border:1px solid red'><img src='" + mainCanvas.toDataURL() + "' alt='Copy!' /></div></body></html>";
destWinDoc.write(destWinHTML);
}
The thing to note is I'm writing out the img tag's src to be the canvas.toDataURL(), and this works. IE doesn't complain about this. Although the data isn't into another canvas, I'm able to get what I need, which is my image data pulled from my canvas and displayed in a new window. Interestingly, if you look at the generated source code the image is actually shown as the base64 encoded data in the src, so it seems the browser is decoding the src data for display; interesting.

Categories

Resources