AVFoundation AutoExposure - camera

I'm developing camera app right now.
I finished most of important features but the most important feature left.
I want my app auto exposure mode.
Here is my sample.
do {
try camera.lockForConfiguration()
camera.focusMode = .continuousAutoFocus
camera.exposureMode = .continuousAutoExposure
camera.unlockForConfiguration()
} catch {
return
}
I made this setting between lockForConfiguration and unlockForConfiguration.
This lead to autoexposure, however it is different from native camera app.
Also, shutter speed does not go below 1/40.
It is always 1/40 whenever it is in dark environment.(where native camera app adjust shutter speed to 1/2 or even 1)
I found the answer here (https://developer.apple.com/forums/thread/26227)
But I don't understand this answer and even how to do that...
session.beginConfiguration()
defer {
session.commitConfiguration()
}
device = AVCaptureDevice.default(.builtInDualWideCamera, for: .video, position: .back)
guard let camera = device else {
set(error: .cameraUnavailable)
status = .failed
return
}
I set AVCapturedevice in this code. Also there is a session.
The answer says don't touch sessionpreset, so I did do anything by sessionPreset.
But how can I set the avcapturedevice by activeformat..?
This is very hard to understand.
Just to check if this is work, I added this codes just below above codes.
'''
var bestFormat: AVCaptureDevice.Format?
bestFormat = device!.formats[2]
print(self.device?.formats)
do {
try camera.lockForConfiguration()
camera.focusMode = .continuousAutoFocus
camera.exposureMode = .continuousAutoExposure
camera.activeFormat = bestFormat!
// camera.setExposureModeCustom(duration: CMTime(value: 1, timescale: 500), iso: 2000)
camera.unlockForConfiguration()
} catch {
return
}
'''
I believe this does not work because camera-resolution doesn't change.
even if device!.formats[2] is low resolution for me (I checked it)

Related

Microbit music / scroll output corrupting memory?

My son and I are trying to implement one of the fun-science.org microbit tutorials - building a "tug of war" game. Essentially, 10 presses on button A moves the sprite closer to that button and the same applies on button B. When you hit the edge of the screen, music plays and a message is scrolled on the screen before the game restarts.
We've got it fully working, but once the game has been won, it doesn't seem to reset properly. It works fine on the simulator, but not on the physical device (a microbit 2).
Once the game is won, the behaviour is erratic. It usually puts the sprite back in the middle, sometimes not, but frequently, one button doesn't work in the next game. Occasionally both stop working. In every situation, a restart fixes things.
Is there something wrong with the code? I've wondered whether the music / message is corrupting something and I need to put a wait in for it to complete. I've re-downloaded the hex file and re-flashed the microbit several times, so I think I've eliminated a corrupt code file.
Javascript version of code shown below, but it was actually built in blockly using the Microsoft MakeCode tool.
input.onButtonPressed(Button.A, function () {
sprite.change(LedSpriteProperty.X, -0.1)
})
input.onButtonPressed(Button.B, function () {
sprite.change(LedSpriteProperty.X, 0.1)
})
let sprite: game.LedSprite = null
sprite = game.createSprite(2, 3)
basic.forever(function () {
if (sprite.get(LedSpriteProperty.X) == 0) {
music.startMelody(music.builtInMelody(Melodies.Birthday), MelodyOptions.Once)
basic.showString("liverpool wins")
sprite.set(LedSpriteProperty.X, 2)
} else if (sprite.get(LedSpriteProperty.X) == 4) {
music.startMelody(music.builtInMelody(Melodies.Entertainer), MelodyOptions.Once)
basic.showString("rb leipzig wins")
sprite.set(LedSpriteProperty.X, 2)
}
})
I found it was more reliable if I did game.pause() and game.resume() while scrolling the text and playing the music at the end of the game:
input.onButtonPressed(Button.A, function () {
sprite.change(LedSpriteProperty.X, -0.1)
})
input.onButtonPressed(Button.B, function () {
sprite.change(LedSpriteProperty.X, 0.1)
})
let sprite: game.LedSprite = null
sprite = game.createSprite(2, 3)
basic.forever(function () {
if (sprite.get(LedSpriteProperty.X) == 0) {
game.pause()
music.startMelody(music.builtInMelody(Melodies.Birthday), MelodyOptions.Once)
basic.showString("liverpool wins")
game.resume()
sprite.set(LedSpriteProperty.X, 2)
} else if (sprite.get(LedSpriteProperty.X) == 4) {
game.pause()
music.startMelody(music.builtInMelody(Melodies.Entertainer), MelodyOptions.Once)
basic.showString("rb leipzig wins")
game.resume()
sprite.set(LedSpriteProperty.X, 2)
}
})
You can also take a look at the following version of the game that does not use the game rendering engine https://makecode.microbit.org/projects/tug-of-led to see if that makes a difference.

WebRTC: Switch from Video Sharing to Screen sharing during call

Initially, I had two different webpages:
One was to do Video Call and
Other was to do Screen Sharing
Now, I want to do both of them in one page.
Here is the scenario:
During Live call, a user wants to stop sharing his/her video and start sharing screen.
Afterwards, again he/she wishes to turn off screen sharing and start video sharing.
For clarity, here are some questions I want to ask:
On Caller Side:
1) How can I change my local stream from video to screen and vice versa?
2) Once it is done, how can I assign it to the local video element?
On Callee Side:
1) How do I handle if the current stream I am receiving is changed from video to screen?
2) How do I handle if the stream I am receiving has stopped? I mean, now I can receive neither video nor screen (just audio)
Kindly, help me in this regards. If there are any open source codes available, kindly share their links too.
Just for your reference, I was trying to handle it using following code. (i know this is naive and won't work)
function handleUserMedia(newStream){
var localvideo = document.getElementById("localvideo");
localvideo.src = URL.createObjectURL(newStream);
localStream = newStream;
sendMessage('got user media');
if (isInitiator) {
maybeStart();
}
}
function handleUserMediaError(error){
console.log(error);
}
var video_constraints = {video: true, audio: true};
var screen_constraints = {video: { mandatory: { chromeMediaSource: 'screen' } }};
getUserMedia(video_constraints, handleUserMedia, handleUserMediaError);
//getUserMedia(screen_constraints, handleUserMedia, handleUserMediaError);
$scope.btnLabel = 'Share Screen';
$scope.toggleSelected = function () {
$scope.selected = !$scope.selected;
if($scope.selected)
{
getUserMedia(screen_constraints, handleUserMedia, handleUserMediaError);
$scope.btnLabel = 'Share Video';
}
else
{
getUserMedia(video_constraints, handleUserMedia, handleUserMediaError);
$scope.btnLabel = 'Share Screen';
}
};
Check this demo:
https://www.webrtc-experiment.com/demos/switch-streams.html
and the relevant tutorial:
https://www.webrtc-experiment.com/docs/how-to-switch-streams.html
simply renegotiate peer connections on both users' side!

Stop Video Capture programmatically in WinJS

I have a winJS where I am recording video. While I can make it work, I want to stop the camera recording automatically after 15 seconds. Currently the cam records more than 15 secs then trims out 15 secs from the video. I want the camera turned off/stop recording after 15secs automatically. I have the following code:
function captureVideo() {
WinJS.log && WinJS.log("", "sample", "status");
// Using Windows.Media.Capture.CameraCaptureUI API to capture a video
var dialog = new Windows.Media.Capture.CameraCaptureUI();
dialog.videoSettings.allowTrimming = true;
dialog.videoSettings.format = Windows.Media.Capture.CameraCaptureUIVideoFormat.mp4;
dialog.videoSettings.maxDurationInSeconds = document.getElementById("txtDuration").value;
dialog.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.video).done(function (file) {
if (file) {
var videoBlobUrl = URL.createObjectURL(file, {oneTimeOnly: true});
document.getElementById("capturedVideo").src = videoBlobUrl;
localSettings.values[videoKey] = file.path;
} else {
WinJS.log && WinJS.log("No video captured.", "sample", "status");
}
}, function (err) {
WinJS.log && WinJS.log(err, "sample", "error");
});
}
The CameraCaptureUI that you are using sacrifices power for the ease of use and standard interface. If you need more power such as the ability to start and stop the recording, you should use the MediaCapture object. See my mediacap demo in codeSHOW. In it I am using the MediaCapture for recording audio, but you can likely figure out how to record video instead and add your concept of timing.

Device check in sencha touch 2

I'm sure I'm just overlooking this question but I cant seem to find how to check the device.
I want to check whether the device is either a phone, a tablet in landscape mode, a tablet in portrait mode or a other device (computer).
What I have is this:
if (Ext.platform.isPhone) {
console.log("phone");
}
if (Ext.platform.isTablet) {
console.log("tablet");
}
var x = Ext.platform;
But platform is undefined (probably because this is the way of Sencha Touch 1).
Does anyone know the correct place for me to access the device check?
Sencha Environment Detection offers a large spectrum through simple means.
Instead of Ext.os.is.Tablet, you can make life easier via Ext.os.deviceType which will return:
Phone
Tablet
Desktop
NB: this value can also be fudged by adding "?deviceType=" to the url.
http://localhost/mypage.html?deviceType=Tablet
Ext.os.name is the singleton returning:
iOS
Android
webOS
BlackBerry
RIMTablet
MacOS
Windows
Linux
Bada
Other
The usual ability of browser detection is available through Ext.browser.name.
Something I've only recently encountered, which I love is feature detection - allowing coding similar to Modernizr / YepNope based off ability of device. Ext.feature offers:
Ext.feature.has.Audio
Ext.feature.has.Canvas
Ext.feature.has.ClassList
Ext.feature.has.CreateContextualFragment
Ext.feature.has.Css3dTransforms
Ext.feature.has.CssAnimations
Ext.feature.has.CssTransforms
Ext.feature.has.CssTransitions
Ext.feature.has.DeviceMotion
Ext.feature.has.Geolocation
Ext.feature.has.History
Ext.feature.has.Orientation
Ext.feature.has.OrientationChange
Ext.feature.has.Range
Ext.feature.has.SqlDatabase
Ext.feature.has.Svg
Ext.feature.has.Touch
Ext.feature.has.Video
Ext.feature.has.Vml
Ext.feature.has.WebSockets
To detect fullscreen/app/homescreen browser mode on iOS:
window.navigator.standalone == true
Orientation Ext.device.Orientation and orientation change:
Ext.device.Orientation.on({
scope: this,
orientationchange: function(e) {
console.log('Alpha: ', e.alpha);
console.log('Beta: ', e.beta);
console.log('Gamma: ', e.gamma);
}
});
Orientation is based on Viewport. I usually add a listener which is more reliable:
onOrientationChange: function(viewport, orientation, width, height) {
// test trigger and values
console.log('o:' + orientation + ' w:' + width + ' h:' + height);
if (width > height) {
orientation = 'landscape';
} else {
orientation = 'portrait';
}
// add handlers here...
}
Use Ext.env.OS's is() method.
Note that only major component and simplified value of the version are
available via direct property checking. Supported values are: iOS,
iPad, iPhone, iPod, Android, WebOS, BlackBerry, Bada, MacOS, Windows,
Linux and Other
if (Ext.os.is('Android')) { ... }
if (Ext.os.is.Android2) { ... } // Equivalent to (Ext.os.is.Android && Ext.os.version.equals(2))
if (Ext.os.is.iOS32) { ... } // Equivalent to (Ext.os.is.iOS && Ext.os.version.equals(3.2))
Alternatively, you can also use PhoneGap Device API
I found the answer to it:
What seems to be the case is that Ext.os.is.(tablet/phone or something else) is true or undefined. If it is not the case it will be undefined.
I.a. Ext.os.is.Tablet is true when on a tablet and undefined when not.
So this is the answer I was looking for
if(Ext.os.is.Tablet){
this._bIsTablet = true;
}else if(Ext.os.is.Phone){
this._bIsPhone = true;
}else{
this._bIsOther = true;
}

Blackberry.location API not working correctly

I am experimenting with making Blackberry widgets but having a little trouble.
My first trial involves displaying a button which, when clicked, calls a JavaScript function that should alert the phones latitude and longitude.
The function looks:
function whereAmI() {
var latitude = blackberry.location.latitude;
var longitude = blackberry.location.longitude;
alert("Lat: "+latitude+", Long: "+longitude);
}
But it only ever alerts "Lat: 0, Long: 0". I've checked and my GPS seems to be working ok.
I'm running OS 5.* on a Curve 8900.
Any help would be appreciated :)
I discovered that I wasn't signing my files properly - now that I have, everything works fine.
For kaban:
// called when location object changes
function locationCB()
{
alert("Latitude " + blackberry.location.latitude);
alert("Longitude " + blackberry.location.longitude);
return true;
}
// test to see if the blackberry location API is supported
if( window.blackberry && blackberry.location.GPSSupported)
{
document.write("GPS Supported");
// Set our call back function
blackberry.location.onLocationUpdate("locationCB()");
// set to Autonomous mode
blackberry.location.setAidMode(2);
//refresh the location
blackberry.location.refreshLocation();
}
else
{
document.write("This Device doesn't support the Blackberry Location API");
}
Does your widget have permission to use GPS? Go to Options->Applications, select your app, then "Edit Permissions". Make sure "Location Data" (in Connections) is set to Allow.