Is it possible to detect when the camera is on/ready with getUserMedia? - ng-file-upload

I am successfully using webcam.js with an angular app to allow users to capture a picture of themselves. However I'm having a problem where some users are uploading blank - all white or all black photos. I suspect that some cameras start up more slowly than others which is allowing users to take pictures of themselves that are blank before the camera is really working.
I would like to be able to detect when the camera is actually on and streaming so I could wait until then to make the Take Photo button available. Normally after you go through the security step of allowing the camera, the video element is blank for half a second while the camera is turning on or the source is being loaded or whatever is happening. On my computer if I move fast I can just barely click the take picture button before the video steam is loaded and it will take a picture that shows as all black. I'm guessing on some computers that the half a second could be longer, possibly enough so that people are trying to take pictures before they see themselves on the screen.
We're also trying to solve this with some better UX, but it would be great if there was a way to prevent people from taking pictures before the camera is ready. I haven't been able to find anything so far about detecting when the camera is on, but have thought about the possibility of detecting the dominant color of a picture that's been taken and if it's all black or white tell the user to take it again, using something like this: Get average color of image via Javascript. Obviously not ideal to have the user go through that loop though if we could wait to show the take picture button.
Thank you in advance!

Using video.onplaying worked for me (https fiddle for Chrome):
var snap = () => navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => {
video.srcObject = stream;
return new Promise(resolve => video.onplaying = resolve);
})
.then(() => canvas.getContext('2d').drawImage(video, 0, 0, 160, 120))
.catch(log);
var log = msg => div.innerHTML += "<br>" + msg;
<button onclick="snap()">Snap!</button><div id="div"></div>
<video id="video" width="160" height="120" autoplay></video>
<canvas id="canvas" width="160" height="120"></canvas>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

Related

How to make video captured by front camera not being inverse Android?

I recording video using MediaRecorder.When using back-camera,it working fine,but when using front camera,the video captured is being flipped/inverse.Means that the item in right,will appear on the left.The camera preview is working fine,just final captured video flipped.
Here is the camera preview looks like
But the final video appear like this(all the item in left hand side,appear on right hand side)
What I tried so far:
I tried to apply the matrix when prepare recorder,but it seems does change anything.
private boolean prepareRecorder(int cameraId){
//# Create a new instance of MediaRecorder
mRecorder = new MediaRecorder();
setCameraDisplayOrientation(this,cameraId,mCamera);
int angle = getVideoOrientationAngle(this,cameraId);
mRecorder.setOrientationHint(angle);
if(cameraId == Camera.CameraInfo.CAMERA_FACING_FRONT){
Matrix matrix = new Matrix();
matrix.preScale(1.0f,-1.0f);
}
//all other code to prepare recorder here
}
I already read for all this question below,but all this seems didnt solve my problem.For information,I using SurfaceView for the camera preview,so this question here doesn't help.
1) Android flip front camera mirror flipped video
2) How to keep android from inverting the image from the front facing camera?
3) Prevent flipping of the front facing camera
So my question is :
1) How to capture a video by front camera which the video not being inverse(exactly the same with camera preview)?
2) How to achieve this when the Camera preview is using SurfaceView but not TextureView ? (cause all the question I mention above,tell about using TextureView)
All possible solution is mostly welcome..Tq
EDIT
I made 2 short video clip to clarify the problem,please download and take a look
1) The video during camera preview of recording
2) The video of the final product of recording
So, if the system camera app produces video similar to your app, you didn't do something wrong. Now it's time to understand what happens to front-facing camera video recording.
The front facing camera is not different from the rear facing camera in the way it captures still pictures or video. There is a difference how the phone displays camera preview on the screen. To make it look more natural to the user, Android (and all other systems) mirrors the preview, so that you can see yourself as if in a mirror.
It is important to understand that this only applies to the way the preview is presented to you. If you pick up any video conferencing app, connect two devices that you hold in two hands, and look at yourself, you will see to your surprise that the two instances of yourself are flipped.
This is not a bug, this is the natural way to present the video to the other party.
See the sketch:
This is how you see the scene:
This is how your peer sees the same scene
Normally, recording of a video is done from the point if view of your peer, as in the second picture. This is the natural setup for, e.g., video conferencing.
But Snapchat and some other social apps choose to store the front-facing video clip as if you record it from the mirror (as if the recorder is in your hand on the first picture). Some people like this feature, others hate it (see https://forums.androidcentral.com/general-help-how/664539-front-camera-pics-mirrored-reversed-only-snapchat.html and https://www.reddit.com/r/nexus6/comments/3846ay/has_anyone_found_a_fix_for_snapchat_flipping)
You cannot use MediaRecorder for that. You can use the lower-level API of MediaCodec to record processed frames. You need to flip each frame 'manually', and this may be a significant performance hit, because normally the MediaRecorder 'connects' the camera to hardware encoder in a very efficient way, without need even to copy the pixels to user memory. This answer shows how you can manipulate the way camera is rendered to texture.
You can achieve this by recording video manually from surface view.
In such case preview and recording will match exactly.
I've been using this library for this purpose:
https://github.com/spaceLenny/recordablesurfaceview
Here is the guide how to use it (not with camera but with OpenGL drawing): https://withintent.uncorkedstudios.com/recording-screen-video-on-android-with-recordablesurfaceview-451c9daa213e

How to set poster image in JW player from flv file?

How can I set a poster image using particular video frame (flv)?
I don't have image file available, so I wonder if it's possible to set a poster image "in the fly" from the video source.
No, that's not possible with JW Player.
Edit: A little more explanation.... JW Player doesn't actually "play" or "process" the video in any way. It's just a steering and styling script - it feeds the video to the browser's <video> tag if the browser can handle it, or to the Flash plugin. The player provides its own control bar, advertising capabilities, and so on, but when it comes to the video file itself, the player isn't touching it. So, there's no way to do things like extracting certain frames. The player isn't ffmpeg.
Here is a little bit of a hack you can use:
<div id="myElement"></div>
<script>
jwplayer("myElement").setup({
file: "/uploads/myVideo.mp4",
autostart: true,
mute: true,
controls: false
});
</script>
<script>
setTimeout(function() {
jwplayer().pause();
jwplayer().setMute(false);
jwplayer().setControls(true);
},3000);
</script>
What this does is basically autostarts the player, muted, with no controls, then after a second, pauses the player, and sets the controls and volume back. Essentially it is grabbing the first frame. Keep in mind this is a bit of a hack and isn't great for bandwidth.

barcodereader sample application

I am using the barcodereader sample application provided in the cascades samples to embed a QRCode scanner into my application.
As it stands the sample is great, but I want the scanner to open as soon as the user navigates to my screen and I want to get rid of the opening slider images that are in the sample.
Firstly, I have tried removing the images and their animations and adding the action:
onCreationCompleted: {
camera.open()
}
to the Page. This opens the camera perfectly as expected, but for some reason, the bacrode just doesn't scan.
So, I wound back a step, and this time I just put the code in exactly as is and just changed the code to read:
onCreationCompleted: {
startupAnimation.play()
}
As expected, the screen open, plays the annimation, but still it fails to read barcodes, however, if I invoke the animation again (by tapping the screen), the animation plays again and the scanner reads the barcode without any issues at all.
All I can think of is that this is a timing issue and that I need some sort of delay after the screen has been created before the camera can be started as a barcode reader?
Anyone able to help?
Thanks,
Douglas
To get scanning right away at application launch, you need to make sure the camera is actually set up and initialized.
Basically, in onCreationComplete, open the camera. In onCameraOpened, start the viewfinder. In onViewfinderStarted, set the barcode detector camera to be the camera.

Prevent iOS mobile safari from going idle / auto-locking / sleeping?

In an iOS app you can set application.idleTimerDisabled = YES to prevent the phone from auto locking.
I need to do this in mobile safari for a game like Doodle Jump where the user may not touch the screen for an extended period of time. Is there any documented method or hack to do this?
(Update)
They seem to be doing it somehow in this site http://www.uncoveryourworld.com. Visit from your iphone and when you get to the buildings/street scene with music playing in the background just leave your phone alone. It never goes to sleep.
(Update 2)
I've spent some time taking a closer look at how they might be keeping the phone from going to sleep. I've done a barebones test and it seems that the way they are looping the audio in the street scene is what keeps it from going to sleep. If you'd like to test this just put a simple audio player that loops on your page and click play:
<audio src="loop.mp3" onended="this.play();" controls="controls" autobuffer></audio>
Everywhere I searched it is being said that this isn't possible, so it is nice to see there is at least some way to do it even if a bit of a hack. Otherwise a browser based game with doodle-jump style play would not be possible. So you could have a loop in your game/app if appropriate or just play a silent loop.
NoSleep.js seems to work in iOS 11 and it reportedly works on Android as well.
Old answer
This is a simple HTML-only method to do that: looping inline autoplaying videos (it might also work in Android Chrome 53+)
<video playsinline muted autoplay loop src="https://rawgit.com/bower-media-samples/big-buck-bunny-480p-30s/master/video.mp4" height=60></video>
See the same demo on CodePen (includes a stopwatch)
Notes
Avoid loading a big video just for this. Perhaps make a short, tiny, black-only video or use
To make it fully work, the videos needs to be always in the viewport or you need to start its playback via JS: video.play()
Edit: This work around no longer works. It is not currently possible to prevent the phone from sleeping in safari.
Yes, you can prevent the phone to sleep using an audio loop. The trick won't start automatically, you will have to play it when the visitor touches the screen.
<audio loop src="http://www.sousound.com/music/healing/healing_01.mp3"></audio>
Test page: tap play and the display will stay on but it will dim on some devices, like an iPhone with iOS 7.
Note: be careful using this trick because it will stop any music that the visitors might be using—and it will annoy them.
No, you can't do this, unfortunately. The only way to achieve this is by making a UIWebView-application and setting the variable you provided there.
https://stackoverflow.com/a/7477438/267892
[edit] random bug behavior, sometimes lockscreen media controls showing, sometimes not
Years later, updated my code
Easy steps :
unlock audio context
create silent sound
loop it and play forever
keep tab active
Working on Safari iOs 15.3.1, tab & browser in background, screen off
// unlock audio context
let ctx = null;
// create silent sound
let bufferSize = 2 * ctx.sampleRate,
emptyBuffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate),
output = emptyBuffer.getChannelData(0);
// fill buffer
for(let i = 0; i < bufferSize; i++)
output[i] = 0;
// create source node
let source = ctx.createBufferSource();
source.buffer = emptyBuffer;
source.loop = true;
// create destination node
let node = ctx.createMediaStreamDestination();
source.connect(node);
// dummy audio element
let audio = document.createElement("audio");
audio.style.display = "none";
document.body.appendChild(audio);
// set source and play
audio.srcObject = node.stream;
audio.play();
// background exec enabled
Even if this approach might not be suitable in every case, you can prevent your phone from locking by reloading the page using Javascript.
// This will trigger a reload after 30 seconds
setTimeout(function(){
self.location = self.location
}, 30000);
Please note that I tested this with iOS7 beta 3
You can stop sleeping and screen dimming in iOS Safari by faking a refresh every 20–30 seconds
var stayAwake = setInterval(function () {
location.href = location.href; //try refreshing
window.setTimeout(window.stop, 0); //stop it soon after
}, 30000);
Please use this code responsibly, don't use it "just because". If it's only needed for a bit, disable it.
clearInterval(stayAwake); //allow device sleep again when not needed
Tested in Safari iOS 7, 7.1.2, and 8.1, but it may not work in UIWebView browsers like Chrome for iOS or the Facebook app.
Demo: http://jsbin.com/kozuzuwaya/1
bfred.it's answer works if you replace the audio-tag with a enter code here -tag - but only if the page is open in iOS10+ Safari AND the user has started the video. You can hide the video with CSS.
Also, I suspect that this feature will also be removed at some point.
This is based on nicopowa's answer, which saves a PWA from being suspended by iOS. (Playing an infinite loop of nothing keeps the app running - even with the screen turned off.)
In order to also make sure that it's triggered by user interaction,
the only thing to change is instead of
let ctx = null
put
let ctx = new AudioContext()

Play a video whose URL is not known in advance - without reload - without extra tab

I have lots of buttons on a web page. Depending on which one is clicked, I want to play a different video.
A large number of <video> elements doesn't seem to work particularly quickly or reliably.
So far, I have tried to:
Create and play() the video element dynamically, after an image is clicked:
var video = document.createElement('video');
video.src = 'video.mp4';
document.body.appendChild(video.play);
video.play();
This works on iOS 4, but not on iOS 3.
Create the video element before, and just change the src.
Doesn't work either.
It seems like the video object must have already done "it's thing", before it can be played.
Use window.open() to open the video URL.
This will cause an annoying new tab to open, which will remain open after playback has completed.
Set window.location
This will cause the current page to be reloaded after playback has completed, which I'm trying to avoid.
Any more ideas?