When using the AVCaptureSession to connect a AVCaptureDevice the device get's locked by the application and can not be released. The only way the device is truly released is after restarting the app.
We are using AVCaptureSession for previewing the camera and audio level meters. But once we start the actual capture we might need to switch to an alternative capture SDK (in this case DeckLink SDK). How ever the device remains locked by AVFoundation and we can't seem to free it in any way.... It all goes sideways as soon as wel call AVCaptureSession.addInput on the AVCaptureSession from the AVCaptureDevice. And simply iterating the inputs and using AVCaptureSession.removeInput does not seem work.
We setup the session like this:
do {
try self.selectedVideoDevice.lockForConfiguration()
try self.selectedAudioDevice?.lockForConfiguration()
self.cameraSession = AVCaptureSession()
self.cameraSession?.beginConfiguration()
self.cameraSession?.sessionPreset = AVCaptureSession.Preset.high
// Add some outputs... not relevant for the issue at hand?!
// Add audio input
if self.selectedAudioDevice != nil {
let deviceInputAudio = try AVCaptureDeviceInput(device: self.selectedAudioDevice!)
if self.cameraSession?.canAddInput(deviceInputAudio) ?? false {
self.cameraSession?.addInput(deviceInputAudio)
}
}
// Add video input
let deviceInputVideo = try AVCaptureDeviceInput(device: self.selectedVideoDevice)
if self.cameraSession?.canAddInput(deviceInputVideo) ?? false {
self.cameraSession?.addInput(deviceInputVideo)
}
self.cameraSession?.commitConfiguration()
self.cameraSession?.startRunning()
self.selectedVideoDevice.unlockForConfiguration()
self.selectedAudioDevice?.unlockForConfiguration()
} catch {
}
And try to release using something like this... one of the many tries...
self.cameraSession?.stopRunning()
for output in self.cameraSession?.outputs ?? [] {
self.cameraSession?.removeOutput(output)
}
for input in self.cameraSession?.inputs ?? [] {
self.cameraSession?.removeInput(input)
}
self.cameraSession = nil
How ever we can't get the device to be recognized in the DeckLink SDK after using in AVFoundation.
Any ideas would be great as cleaning up or setting the variables to nil doesn't seem to do anything...
We chose to implement the Desktop Video SDK from Blackmagic and do all captures from a Blackmagic device using that. This solves more issues when capturing using Blackmagic Mini Recorder (for example: audio sync) somehow AVFoundation does work with Blackmagic but not really well. And Blackmagic officially never answered the question "Do you support AVFoundation". So in order to make it work I would recommend the Desktop Video SDK that can be downloaded from their site under Support.
https://www.blackmagicdesign.com/support/
Also make sure you never load the video device into your AVFoundation workflow. It will get stuck and hold it. So first check if it's Blackmagic then continue to AVFoundation if not.
Hi I am trying to switch between the rear and front facing cameras if i start he session with the front facing camera it works but with the other way way round the AVCapturepreview layer is not visible and just presents a blank screen.
First stop the preview session.
When stopped (use the delegate for this) set the camera device you want and restart the preview session.
In code:
[[PBJVision sharedInstance] stopPreview];
//implement the following deluge ate
- (void)visionSessionDidStopPreview:(PBJVision *)vision{
vision.cameraDevice = PBJCameraDeviceFront;
[vision startPreview];
}
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()
Can I record a video without using UIImagePickerController?
Of course without needing to jailbreak or anything else that would cause the App Store to reject the app.
I think there is a way to access video device not using UIImagePickerController because these camera applications can record video and work on iPhone 2G/3G which utilizes ffmpeg:
iVideoCamera
iVidCam
I pick this code up by googling.
AVFormatParameters formatParams;
AVInputFormat *iformat;
formatParams.device = "/dev/video0";
formatParams.channel = 0;
formatParams.standard = "ntsc";
formatParams.width = 640;
formatParams.height = 480;
formatParams.frame_rate = 29;
formatParams.frame_rate_base = 1;
filename = "";
iformat = av_find_input_format("video4linux");
av_open_input_file(&ffmpegFormatContext,
filename, iformat, 0, &formatParams);
This code tell me how to open camera device, but I don't know device path of iPhone.
How do iVideoCamera and iVidCam record video?
Both of these use CoreSurface which is a private API. You can google it for more information. In iOS 4, there are new API's to get direct frame access from the camera.
Is this the proper way to detect which device a user is running?
NSString *currentModel = [[UIDevice currentDevice] model];
if ([currentModel isEqualToString:#"iPhone"]) {
// The user is running on iPhone so allow Call, Camera, etc.
} else {
// The user is running on a different device (iPod / iPad / iPhone Simulator) disallow Call.
}
It is not a general solution but Apple in many cases provides API calls to check wether specific feature is supported or not. Examples could be:
+isSourceTypeAvailable: and +availableMediaTypesForSourceType: in UIImagePickerController allowing you to check if camera is available for the current device.
+canSendMail in MFMailComposeViewController to check if device is configured to send mail.
-canOpenURL in UIApplication class to check if URL can be opened. For example it can be used to check if it is possible to make a phone call:
if (![[UIApplication sharedApplication] canOpenURL:
[NSURL URLWithString:#"tel://"]])
//We cannot make a call - hide call button here
If such API calls are available for your purpose I would use them rather then rely on hardcoded string identifiers.
I'm not sure I'd want to generalize that much (ie, there may eventually be an iPod with a camera, and I don't know that the iPhone will ALWAYS be called "iPhone"), but yes, this is the accepted way.