getmethod for retrieving source of video element - javascript

Is there a getMethod that will give me the video source so that I could set its width and height attributes from javascript.
<script>
document.addEventListener( "DOMContentLoaded", function() {
var video = document.getElementsBySource("videos/LugaMantanah.mp4")[0];
video.height = 300;
video.width = 700;
var sequence = Popcorn.sequence("container",
[
{
src: "video",
in: 0,
out: 30
},
{
src: "videos/LugaMantanahAreaCodes.mp4",
in: 25,
out: 55
},
]);
}, false);
</script>

you can get the width and height of the video after the event loadedmetadata fires:
video.addEventListener( "loadedmetadata", function (e) {
var width = this.videoWidth;
var height = this.videoHeight;
}, false );
edited after comment:
If you want to set the width of the video, you need to address the video tags (they get loaded inside the container by Popcorn).
An example to set the width and height of the first video below. You can just add it to your code after you define var sequence.
var video = document.getElementsByTagName("video")[0];
video.height = 150;
video.width = 100;

Related

javascript canvas capture screenshot of camera issue in Samsung Browser

Well, I'm having a very weird issue that's only happening on Samsung Browser. On Chrome and other browsers, this works well.
When I take a snapshot of a current frame of a video (Currently the mobile camera) on javascript I get the image with distortion and generally bad.
The code that takes the snapshot is:
function takeSnapshot() {
// Here we're using a trick that involves a hidden canvas element.
video.pause();
var hidden_canvas = document.createElement('canvas'),
context = hidden_canvas.getContext('2d');
var width = video.videoWidth,
height = video.videoHeight;
if (width && height) {
// Setup a canvas with the same dimensions as the video.
hidden_canvas.width = width;
hidden_canvas.height = height;
// Make a copy of the current frame in the video on the canvas.
context.drawImage(video, 0, 0, width, height);
// Turn the canvas image into a dataURL that can be used as a src for our photo.
return hidden_canvas.toDataURL('image/jpeg');
}
}
Do I'm missing something else to make it work in Samsung Browser? Or I just put a message that this is not compatible with this browser?
Currently tested on Samsung Galaxy S9, Android 10.
------------- Update
I found what is causing the image to be captured badly.
I'm using custom size for the image, in this case, is a horizontal rectangle.
I do this when init the video:
var w = 2000; // This renders the video as a horizontal rectangle, this does the issue.
var h = 1200;
var userAgent = (typeof navigator !== 'undefined' && navigator.userAgent) || '';
var isSamsungBrowser = userAgent.indexOf('SamsungBrowser') >= 0;
// Quick fix:
if(SamsungBrowser){ // If I render as vertical renctangle, the issue is gone.
w = 1200;
h = 2000;
}
navigator.getMedia(
{
video:
{
deviceId: videoSource ? { exact: videoSource } : undefined,
width: { ideal: h },
height: { ideal: w }
}
},
// Success Callback
function (stream) {
// Create an object URL for the video stream and
// set it as src of our HTLM video element.
try {
currentStream = stream;
video.srcObject = stream;
} catch (error) {
video.src = window.URL.createObjectURL(stream);
}
window.stream = stream;
// Play the video element to start the stream.
video.play();
video.onplay = function () {
showVideo();
};
}

How to fix element.videoHeight in js with WebRTC?

I need some serious help about my code which is driving me crazy !!
I'm trying to set the format of my video to match a square rendering but my js won't set the element.videoHeight to the value I've defined !
I feel like I tried everything : changing the video.height AND video.videoHeight in multiple places, trying the 'loadedmetadata' method, clearing all cookies and caches etc...
Here's my current code:
(function ()
{
let width = 0;
let height = 0;
let streaming = false;
let video = null;
let canvas = null;
function startup()
{
video = document.getElementById('webcam');
canvas = document.getElementById('transit');
width = video.offsetWidth;
video.width = width;
video.height = width;
document.getElementById('transit').width = width;
document.getElementById('result').width = width;
navigator.mediaDevices.getUserMedia({ video: { width: width, height: width }, audio: false })
.then(function(stream) {
video.srcObject = stream;
video.play();
})
.catch(function(err) {
console.log("An error occured: " + err);
});
video.addEventListener('canplay', function(ev){
if (!streaming) {
height = width;
video.setAttribute('width', width);
video.setAttribute('height', width);
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
streaming = true;
}
}, false);
window.addEventListener('load', startup, false);
})();
I want the video.videoWidth to be equal to video.videoHeight.
But event if I manage to change the video.videoWidth in my code (according to some console.log), the video.videoHeight stays the same !
The result is like if I put a div around my tag and the div is a square, but the video itself is still in some kind of 4/3 format !
And oddly enough, it works just fine on my personal computer, but it doesn't on some other one, both of them being Mac OSX... And with the same js version obviously.
Help ! :'(
videoHeight is a read-only property, see mdn.
To get a square rendering (even if the video is 4:3) use the CSS 'cover' object-fit combined with width and height.
Actually, thank you for your answer but I found the error : it was because the definition of the video can't exceed 720px in height !!
So I just added a condition stating that :
if (video.offsetHeight > 720)
width = 720;
else
width = video.offsetWidth;
So now I can have a square video rendering :)

HTML5 camera stretches the picture

I'm using the HTML5 camera for taking picture. I have noticed that after the picture is captured, the final image width and height are stretched though I'm applying the same width and height for both video as well as canvas.
Please refer this JSFIDDLE
var video = document.querySelector("#videoElement");
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({video: true}, handleVideo, videoError);
}
function handleVideo(stream) {
video.src = window.URL.createObjectURL(stream);
}
function videoError(e) {
// do something
}
var v,canvas,context,w,h;
var imgtag = document.getElementById('imgtag');
var sel = document.getElementById('fileselect');
//document.addEventListener('DOMContentLoaded', function(){
v = document.getElementById('videoElement');
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
w = canvas.width;
h = canvas.height;
//},false);
function draw(v,c,w,h) {
if(v.paused || v.ended) return false;
context.drawImage(v,0,0,w,h);
var uri = canvas.toDataURL("image/png");
imgtag.src = uri;
}
document.getElementById('save').addEventListener('click',function(e){
draw(v,context,w,h);
});
var fr;
sel.addEventListener('change',function(e){
var f = sel.files[0];
fr = new FileReader();
fr.onload = receivedText;
fr.readAsDataURL(f);
})
function receivedText() {
imgtag.src = fr.result;
}
Your code has hard-coded values for width and height, both for video and canvas elements.
Avoid setting absolute sizes in both directions as the dimension of the video element can vary. You can set the size by using just the width or just the height, or by using CSS style/rule.
For canvas you need to set the size based on the actual size of the video element. For this use the video element properties:
video.videoWidth;
video.videoHeight;
You can apply a scale to those as you want, for example:
scale = 300 / v.videoWidth;
w = v.videoWidth * scale;
h = v.videoHeight * scale;
canvas.width = w;
canvas.height = h;
context.drawImage(v, 0, 0, w, h);
Updated fiddle
Should someone still be facing this problem in 2021...
// init media navigator
navigator.mediaDevices.getUserMedia(constraints).then(stream => {
// get the actual settings of video element,
// which includes real video width and height
const streamSettings = stream.getVideoTracks()[0].getSettings();
// set the constrains to canvas element
canvasElement.width = streamSettings.width;
canvasElement.height = streamSettings.height;
}

Webcam Capture to <img>

Using javascript or Jquery I want to get the current image from the webcam feed on my page and put it in an tag.
I have a bit of script which generates tags dynamically with unique Id's so after generating one all I want to do is capture an image from the webcam at that exact moment and save the image in the generated tag. After taking the image I just want the webcam to carry until the next time it takes a picture.
I already have a webcam feed running using a library which does face tracking, however I want to extend this with this feature to create a gallery of captured images on the page.
The library I am using is ClmTracker
Creator of the library suggested calling getImageData(x,y,w,h) on the video element and I have tried this. also tried to implement tutorials I have seen on other websites but to no avail. It would seem the answer would need to be specific to my code. I have tried to use canvas instead of tags to put the image in to, but I kept getting errors due to them being created dynamically in the code.
var vid = document.getElementById('videoel');
var overlay = document.getElementById('overlay');
var overlayCC = overlay.getContext('2d');
/********** check and set up video/webcam **********/
function enablestart() {
var startbutton = document.getElementById('startbutton');
startbutton.value = "start";
startbutton.disabled = null;
}
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL || window.msURL || window.mozURL;
// check for camerasupport
if (navigator.getUserMedia) {
// set up stream
var videoSelector = {
video: true
};
if (window.navigator.appVersion.match(/Chrome\/(.*?) /)) {
var chromeVersion = parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10);
if (chromeVersion < 20) {
videoSelector = "video";
}
};
navigator.getUserMedia(videoSelector, function (stream) {
if (vid.mozCaptureStream) {
vid.mozSrcObject = stream;
} else {
vid.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
}
vid.play();
}, function () {
//insertAltVideo(vid);
alert("There was some problem trying to fetch video from your webcam. If you have a webcam, please make sure to accept when the browser asks for access to your webcam.");
});
} else {
//insertAltVideo(vid);
alert("This demo depends on getUserMedia, which your browser does not seem to support. :(");
}
vid.addEventListener('canplay', enablestart, false);
How can I capture an image from the webcam and put it in a div using the code above as a basis?
I'm not sure I can give any more details as I have not got the knowledge on how to do this.
First, draw it to a canvas:
var canvas = document.createElement('canvas');
canvas.height = video.height;
canvas.width = video.width;
canvas.getContext('2d').drawImage(video, 0, 0);
And now you can create the image:
var img = document.createElement('img');
img.src = canvas.toDataURL();
I cannot get to seem to get the screenshot porting working, but the webcam part is working fine, I'll update when complete.
JSFiddle
HTML
<div id="container">
<video autoplay="true" id="videoElement">dsasd</video>
<br>
<button onclick="snap()">Screenshot</button>
<canvas></canvas>
</div>
JS
var video = document.querySelector("#videoElement");
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({
video: true
}, handleVideo, videoError);
}
function handleVideo(stream) {
video.src = window.URL.createObjectURL(stream);
}
function videoError(e) {
// do something
}
// Get handles on the video and canvas elements
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
// Get a handle on the 2d context of the canvas element
var context = canvas.getContext('2d');
// Define some vars required later
var w, h, ratio;
// Add a listener to wait for the 'loadedmetadata' state so the video's dimensions can be read
video.addEventListener('loadedmetadata', function() {
// Calculate the ratio of the video's width to height
ratio = video.videoWidth / video.videoHeight;
// Define the required width as 100 pixels smaller than the actual video's width
w = video.videoWidth - 100;
// Calculate the height based on the video's width and the ratio
h = parseInt(w / ratio, 10);
// Set the canvas width and height to the values just calculated
canvas.width = w;
canvas.height = h;
}, false);
// Takes a snapshot of the video
function snap() {
// Define the size of the rectangle that will be filled (basically the entire element)
context.fillRect(0, 0, w, h);
// Grab the image from the video
context.drawImage(video, 0, 0, w, h);
}
CSS
container {
margin: 0px auto;
width: 500px;
height: 375px;
border: 10px #333 solid;
}
videoElement, canvas {
width: 500px;
height: 375px;
background-color: #666;
}

Resizing a hidden-frame

I am trying to load a webpage into a hidden-frame (sdk/frame/hidden-frame) and then render a screenshot of it. I can get the screenshot just fine, but the frame is not properly sized. The screenshot is rendered by using the following code
var hiddenFrames = require("sdk/frame/hidden-frame");
let hiddenFrame = hiddenFrames.add(hiddenFrames.HiddenFrame({
onReady: function() {
this.element.contentWindow.location = "http://example.com";
let self = this;
this.element.addEventListener("DOMContentLoaded", function() {
var cnvs = self.element.contentDocument.createElement("canvas");
var width = self.element.contentDocument.body.clientHeight; //for some reason clientWidth is 0 for www.example.com
var height = self.element.contentDocument.body.clientHeight;
cnvs.width = width;
cnvs.height = height;
var ctx = cnvs.getContext("2d");
console.log(width+" "+height);
ctx.drawWindow(self.element.contentWindow, 0, 0, width, height, "rgb(255,255,255)");
console.log(cnvs.toDataURL());
}, true, true);
}
}));
I have tried changing the width and height of the iframe with
this.element.width = "1600";
this.element.height = "900";
changing the size of element.contentWindow with resizeTo(), and changing the size of the body. None of them seem to have an impact on the final screenshot, which looks like
Try adding this on the parent page after including the iframe (or script that includes the iframe).
$('iframe').load(function(){
$(this).css({
width: 1600,
height: 900
});
});

Categories