Create live video of jpeg snapshots using Gstreamer and JavaScript setTimeout() - javascript

I am trying to create a live "video" stream using an tag on a web page.
A Gstreamer pipeline continually overwrites a file "snapshot.jpeg" with a new frame grabbed from a webcam using video4linux2 with a framerate of 15 fps.
A web page renders the image without caching every 100 ms.
The problem is that I get ERR_CONTENT_LENGTH_MISMATCH (in browser console) for the image source on many frames. This is shown as a broken link in the browser.
GStreamer 0.10 syntax
gst-launch v4l2src ! video/x-raw-yuv, width=640, height=480, framerate=15/1 ! jpegenc ! multifilesink location=/var/www/video/snapshot.jpeg
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<img id="snapshot" src="snapshot.jpeg"/>
</body>
</html>
JavaScript
$(function() {
function refreshImage(){
$("#snapshot").attr("src", 'snapshot.jpeg?' + Math.random());
setTimeout(refreshImage, 100);
}
refreshImage();
})

Try to hook setTimeout to Image.onload:
$(function() {
function refreshImage(){
$("#snapshot").attr("src", 'snapshot.jpeg?' + Math.random());
}
$("#snapshot").onload = function(){
setTimeout(refreshImage, 100);
}
refreshImage();
})

Related

How do I get a jpg of a webpage (video element only not the entire screen) of a webpage using WebView2?

I am trying to grab the video element of a webpage and save the image locally.
In my code I have in my C# project:
this.webView.Source = new Uri( localhost:4000/watcher.html );
I'm running a local node server with javascript to display a video of a camera feed and in my watcher.html it looks like this:
<!DOCTYPE html>
<html>
<head>
<title>Viewer</title>
<meta charset="UTF-8" />
<link href="styles.css" rel="stylesheet">
</head>
<body>
<div class="controls">
<button id="button" onClick="changeCamera(0)">Camera One</button>
<button id="button2" onClick="changeCamera(1)">Camera Two</button>
</div>
<video playsinline autoplay muted></video>
<script src="/socket.io/socket.io.js"></script>
<script src="watch.js"></script>
</body>
</html>
My c# project loads the webpage fine, but How can I grab a picture of the video element and not get the entire screen? I created the following function below to take a picture of the entire screen just to test, it works, but I have no clue on how I can manipulate the webView2 to get my image. Any input on how to achieve this would be amazing. Thanks.
private void TakePicture(string fileName)
{
Bitmap screenGrab = new Bitmap( Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb );
Graphics g = Graphics.FromImage( screenGrab );
g.CopyFromScreen( Screen.PrimaryScreen.Bounds.Left, Screen.PrimaryScreen.Bounds.Top, 0, 0, screenGrab.Size, CopyPixelOperation.SourceCopy );
screenGrab.Save( fileName + ".jpg", ImageFormat.Jpeg );
}
P.S. I already explored trying to export the jpeg directly from my node server, I spent many many hours trying to get it to work and now I'm exploring other options.

Refresh page every couple minutes

I need to open 192.168.1.1 every couple of minutes. I have the following code but doesn't work:
<html>
<head>
<meta charset="UTF-8">
<title>Untitled Document</title>
</head>
<body>
<script>
setInterval(function() {
location.replace("http://192.168.1.1")
}, 60 * 1000);
</script>
</body>
</html>
Adding to the iframe solution, in case you want it to open in a new tab
<script>
var URL = "http://example.com";
setInterval(function() {
var win = window.open(URL, "_blank");
/* uncomment if you want it to close
setInterval(function() {
win.close()
}, 1500);
*/
}, 2000);
</script>
like the iframe, not replacing the current tab ensures your code keeps running.
Your code won't work as you want it to, because once you change the location for the first time, it will load the router site and your code won't be executed anymore.
Since you can't control the router page code, you can load the router website into an iframe:
<iframe src="http://192.168.1.1"></iframe>
and put this in your <head> to refresh the site every 300 seconds:
<meta http-equiv="Refresh" content="300">
(adjust the number of seconds to your needs)

How can I change my code to be able to calculate different urls instead of the current page

I'm trying to calculate the load time and page size of different URLs/Pages similar to the developer tools performance tab but in javascript. But the current code only calculates its current page instead of a different URL. Is there any way for me to do this because with my research I have no luck.
<html>
<head>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<script type="text/javascript">
var start = new Date().getTime();
function onLoad() {
var now = new Date().getTime();
var latency = now - start;
alert("page loading time: " + latency+"\n"+"Start time:"+start+"\n"+"End time:"+now);
alert("Load_size:"+document.getElementsByTagName("html")[0].outerHTML.length + "KB");
}
</script>
</head>
<body onload="onLoad()">
<!- Main page body goes from here. -->
</body>
</html>
It will not be possible to read the runtime parameters of a page outside the page your javascript is running on.
Part of the security model is to avoid being able to inspect the runtime of other pages. This is called the "sandbox". You'll need to build a plugin that breaks the sandbox to inspect the domLoad / domReady and other performance events.
Good news though, you probably have one built in! The console for modern browsers shows all those events in the timeline tab.
If you're trying to make a service that attempts to evaluate the runtime of other pages, you'll need to load those in a virtual web browser on the server and interpret the results using selenium or something similar.
You can try this to calculate the load time of a page:
<script type="text/javascript">
$(document).ready(function() {
console.log("Time until DOMready: ", Date.now()-timerStart);
});
$(window).load(function() {
console.log("Time until everything loaded: ", Date.now()-timerStart);
});
</script>
edit: this will only work on pages where this JS code will run, so if you cant insert code onto the page you wont be able to run it.

simple play sound from soundcloud by clicking button

Trying to stream sound on page from soundcloud, as it said on API, but unfortunately there's no sound when I'm click on button.
Otherwise, when I "run" this code here or on jsfiddle - it works!
It must be problem that I'm trying to run it from local disc?
How can I solve it?
SC.initialize({
client_id: '53902af7a344bb0351898c47bc3d786f'
});
$("#stream").on("click", function(){
SC.stream("/tracks/49712607", function(sound){
sound.play();
});
});
<!DOCTYPE html>
<html>
<head>
<title>music</title>
<meta charset="windows-1251">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://connect.soundcloud.com/sdk-2.0.0.js"></script>
<script src="script.js"></script>
</head>
<body>
<div id='player'>player
<input type="button" href="#" id="stream" class="big button" value="Stream It Again, Sam" />
</div>
</body>
</html>
You need to execute your call to the SDK while your files are hosted on a web server. But you can have the web server running form your local machine.
The problem is trying to run things from the filesystem. When doing so, you get the error:
NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
To ensure you do have this error, please try the basic example from SoundCloud.
See also this question.
What technology to choose then depends on what you feel comfortable with...
For instance I do most of my local apps with Node.JS. Maybe the simplest way would be to use http-server as noted in your comment.
Launch it on the command line with: http-server <your-directory> -o. With -o your default browser will open and list the files in your-directory.
Notice that the SoundCloud docs are using the JQuery .live() function call but it is deprecated! That made their code work despite the DOM not being ready yet.
Here, you want to use the regular .on() function and have the binding of the click event handler done once the DOM is ready. For that you use $(document).ready(function() { ... });
Here's the code I used.
<!DOCTYPE html>
<html>
<head>
<title>music</title>
<meta charset="windows-1251">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="//connect.soundcloud.com/sdk-2.0.0.js"></script>
<script>
SC.initialize({
client_id: "53902af7a344bb0351898c47bc3d786f"
});
$(document).ready(function() {
$("#stream").on("click", function(){
SC.stream("/tracks/49712607", function(sound){
sound.play();
});
});
});
</script>
</head>
<body>
<div id='player'>player
<input type="button" href="#" id="stream" class="big button" value="Stream It Again, Sam" />
</div>
</body>
</html>

Get time of page loading start in JavaScript

In JavaScript it is possible to wait for onLoad which may be used to specify the time of page loading completion.
Every HTTP response is sent along with Date: header which contains the time server sent a response.
Is there a way in JavaScript to get the time of page started loading?
Something similar to response Date: header.
It would be useful for cases when JavaScript is injected into page after some delay.
new Date(performance.timing.connectStart) in chrome, firefox, IE9, etc (caniuse)
demo
console.log(new Date(performance.timing.connectStart));
Try storing a value from var d= new Date(); var requested = d.getTime(); and execute it when the page loads.
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
var loadDate;
</script>
</head>
<body onload="loadDate=new Date();">
<button onclick="alert(loadDate);">show load Date</button>
</body>
</html>
I would just pass a timestamp from the server-side script to the browser via a cookie or inline JS. E.g. in PHP:
<script>
var timestamp = new Date(<?php echo time(); ?>);
</script>

Categories