I built a camera app for auto capture. I want to keep the flash on as long as the camera is on. I set the following code :
cameraDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
if (cameraDevice.hasTorch) {
do {
try cameraDevice.lockForConfiguration()
if cameraDevice.isTorchActive {
cameraDevice.torchMode = AVCaptureTorchMode.on
} else {
// sets the torch intensity to 100%
try cameraDevice.setTorchModeOnWithLevel(0.8)
}
cameraDevice.unlockForConfiguration()
} catch {
print(error)
}
}
But when I run the app, it only flashes for one time and then goes off. How can I solve this problem?
Call this method
Inside your camera active/Open func or When device camera active -
func flashActive() {
if let currentDevice = AVCaptureDevice.default(for: AVMediaType.video), currentDevice.hasTorch {
do {
try currentDevice.lockForConfiguration()
let torchOn = !currentDevice.isTorchActive
try currentDevice.setTorchModeOn(level:1.0)//Or whatever you want
currentDevice.torchMode = torchOn ? .on : .off
currentDevice.unlockForConfiguration()
} catch {
print("error")
}
}
}
Related
I am working on a project where I start the camera and then capture images live to image processing. This project has guided me TensorFlow - Image Classification. One thing I can't figure out despite looking in the documentation and searching on Google is how to set the resolution of the camera.
Is it possible to either get it, or to set it programmatically? Here is the code where I create the camera:
private func addVideoDeviceInput() -> Bool {
/**Tries to get the default back camera.
*/
guard let camera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else {
return false
}
do {
let videoDeviceInput = try AVCaptureDeviceInput(device: camera)
if session.canAddInput(videoDeviceInput) {
session.addInput(videoDeviceInput)
return true
}
else {
return false
}
}
catch {
fatalError("Cannot create video device input")
}
}
Yes, check out sessionPreset.
session.sessionPreset = .photo /// here!
if session.canAddInput(videoDeviceInput) {
session.addInput(videoDeviceInput)
return true
}
I have a test project because I'm just trying to learn swift. So I wanted to try to do something with the torch, I made just a simple button to turn the torch on/off but I found out that when I change the device orientation it turns off the torch. And I was wondering if anyone had the same problem and found a solution so they can keep the torch on while changing screen orientation.
This is the code for the torch I found it on https://www.hackingwithswift.com/example-code/media/how-to-turn-on-the-camera-flashlight-to-make-a-torch
func toggleTorch(on: Bool)
{
guard let device = AVCaptureDevice.default(for: .video) else {return}
if device.hasTorch
{
do
{
try device.lockForConfiguration()
if on
{
device.torchMode = .on
} else
{
device.torchMode = .off
}
device.unlockForConfiguration()
} catch
{
print("Torch could not be used")
}
} else
{
print("Torch is not available")
}
}
I found a temporary fix. I have to use setTorchMode then adjust the level argument lower so it doesn't overheat and turn off. It still turns off but its on for a little longer than before
I'm using AVCaptureSession to capture video.
I want to light on the torch during the whole session, but once the session is started, the light turns automatically off.
There is a lot of posts here showing how to turn on the torch. It works, unless the capture session is started.
here's the way I start the session
guard let camera = AVCaptureDevice.default(for: .video) else { return }
self.captureSession.beginConfiguration()
let deviceInput = try AVCaptureDeviceInput(device: camera)
self.captureSession.addInput(deviceInput)
let videoOutput = AVCaptureVideoDataOutput()
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "com.axelife.axcapturer.samplebufferdelegate"))
self.captureSession.addOutput(videoOutput)
try camera.setLight(on: true)
self.captureSession.commitConfiguration()
DispatchQueue(label: "capturesession").async {
self.captureSession.startRunning()
}
And my code to turn on the light
extension AVCaptureDevice {
func setLight(on: Bool) throws {
try self.lockForConfiguration()
if on {
try self.setTorchModeOn(level: 1)
}
else {
self.torchMode = .off
}
self.unlockForConfiguration()
}
}
With that code, the light turns on during < 0.5 seconds, and turn back off automatically.
Ok, I figured out.
The torch simply must be lighted on after the session start.
So instead of:
try camera.setLight(on: true)
self.captureSession.commitConfiguration()
DispatchQueue(label: "capturesession").async {
self.captureSession.startRunning()
}
just do
self.captureSession.commitConfiguration()
DispatchQueue(label: "capturesession").async {
self.captureSession.startRunning()
try camera.setLight(on: true)
}
For me, the torch turns off when I change the videoOrientation of the capture preview layer. I turn it on again after that happens. (DispatchQueue.main.async is important, for some reason, it doesn't work if I leave it out)
previewConnection.videoOrientation = orientation
do {
try captureDevice.lockForConfiguration()
} catch {
print(error)
}
DispatchQueue.main.async { [weak self] in
self?.captureDevice.torchMode = .on
self?.captureDevice.unlockForConfiguration()
}
I'm trying to switch camera while recording video like 'Snapchat' and 'Facebook' behavior. Switch camera work fine before start record video, but need to handle it separately when recording.
Any help appreciate...
public func switchCamera() {
guard isVideoRecording != true else {
//TODO: Handle switch camera when recording in here
return
}
guard session.isRunning == true else {
return
}
switch currentCamera {
case .front:
currentCamera = .rear
case .rear:
currentCamera = .front
}
session.stopRunning()
sessionQueue.async { [unowned self] in
// remove and re-add inputs and outputs
for input in self.session.inputs {
self.session.removeInput(input as! AVCaptureInput)
}
// add new input
self.addInputs()
self.session.startRunning()
}
}
You can try to write your frames with AVAssetWriter. Here you can find an example.
I am having an issue creating a capture session in a custom UIView. I set the delegate like this
class Camera: UIView, AVCaptureFileOutputRecordingDelegate, AVAudioRecorderDelegate {
}
and then I set everything up and set the delegate like this
self.recordingDelegate? = self
captureSession.sessionPreset = AVCaptureSessionPresetHigh
let devices = AVCaptureDevice.devices()
for device in devices {
if (device.hasMediaType(AVMediaTypeVideo)) {
if(device.position == AVCaptureDevicePosition.Back) {
captureDevice = device as? AVCaptureDevice
if captureDevice != nil {
beginSession()
}
}
}
}
and all goes well. However, in the beginSession function:
func beginSession() {
let err : NSError? = nil
do {
self.captureSession.addInput(try AVCaptureDeviceInput(device: self.captureDevice!))
}
catch {
print("dang")
}
if err != nil {
print("error: \(err?.localizedDescription)")
}
...
The catch is thrown when I try to add the capture device input and there for it is not being added and I can not figure out why.
All of my code I am currently using was working fine before when I had it inside a UIViewController but when I switched it over to a subclass of UIView it stopped working. Any help would be appreciated if more code is needed let me know thank you!
I figured it out the iOS device I was using did not have the camera enabled for some reason there for the input could not be added which made the preview layer unable to capture any data