↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > タイマー撮影+常にフォアグランド

アプリを常にActiveにForegroundにした状態で写真を撮影できるか

写真は音をたてないと撮影できなかったり不便なことが多いのでできるのかよくわかりませんが、 トライしてみます

参考:iOSアプリ起動中にスリープしないようにする
参考:iOS taking photo programmatically
参考:AVCaptureStillImageOutput
参考:Swift : take photo from AVFondation

やってみた

まずアプリが勝手にスリープしない為にはidleTimerDiableをtrueに


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    UIApplication.sharedApplication().idleTimerDisabled = true
    return true
}

これで恐らく常にActiveな状態になったはずです


プログラムでカメラを撮影する


import UIKit
import AVFoundation

class ViewController: UIViewController{
    var stillImageOutput: AVCaptureStillImageOutput!
    var captureSession: AVCaptureSession!
    
    override func viewDidLoad() {
        takePhoto();
    }
    
    func takePhoto(){
        if let stillOutput = self.stillImageOutput {
            //スレッドで安全に利用してクラッシュしないように
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
                //ビデオコネクションを探す
                var videoConnection : AVCaptureConnection?
                for connecton in stillOutput.connections {
                    //入力ポートを探す
                    for port in connecton.inputPorts!{
                        if port.mediaType == AVMediaTypeVideo {
                            videoConnection = connecton as? AVCaptureConnection
                            break //ポート
                        }
                    }
                    if videoConnection  != nil {
                        break//接続
                    }
                }
                if videoConnection  != nil {
                    stillOutput.captureStillImageAsynchronouslyFromConnection(videoConnection){
                        (imageSampleBuffer : CMSampleBuffer!, _) in
                        let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
                        var pickedImage: UIImage = UIImage(data: imageDataJpeg)!
                    }
                    self.captureSession.stopRunning()
                }
            }
        }
    }

    
}

このあたりで画像を取得できそうです。

カスタマイズ

この二つを利用して、タイマー処理等で1秒間に一枚写真をとっていく検証を行います。(現在ケーブルがないのであとで検証。Bluetoothで検証できる ようにしてほしいです。なんだかXCode4だったらWireless Debugができたとかなんとか、、、、不便です)

以下、プログラムでの撮影は成功しましたが、NSTimerやNSThreadで撮影すると、captureStillImageAsynchronouslyFromConnectionのCMSampleBufferがnilで帰ってくる。。。


import UIKit
import AVFoundation

class ViewController: UIViewController{
    var stillImageOutput: AVCaptureStillImageOutput!
    var captureSession: AVCaptureSession!
    var videoconnection: AVCaptureConnection!
    
    override func viewDidLoad() {
    }
    override func viewDidAppear(animated: Bool) {
        configureCamera();
        takePhoto();
    }
    
    func configureCamera() -> Bool {
        // init camera device
        var captureDevice: AVCaptureDevice?
        var devices: NSArray = AVCaptureDevice.devices()
        
        // find back camera
        for device: AnyObject in devices {
            if device.position == AVCaptureDevicePosition.Back {
                captureDevice = device as? AVCaptureDevice
            }
        }
        
        if (captureDevice != nil) {
            // Debug
            println(captureDevice!.localizedName)
            println(captureDevice!.modelID)
        } else {
            println("Missing Camera")
            return false
        }
        
        var error: NSErrorPointer = nil
        var deviceInput: AVCaptureInput = AVCaptureDeviceInput.deviceInputWithDevice(captureDevice, error: error) as! AVCaptureInput
        
        self.stillImageOutput = AVCaptureStillImageOutput()
        
        // init session
        self.captureSession = AVCaptureSession()
        self.captureSession.sessionPreset = AVCaptureSessionPresetPhoto
        self.captureSession.addInput(deviceInput as AVCaptureInput)
        self.captureSession.addOutput(self.stillImageOutput)
        
        // layer for preview
        var previewLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer.layerWithSession(self.captureSession) as! AVCaptureVideoPreviewLayer
        previewLayer.frame = self.view.bounds
        self.view.layer.addSublayer(previewLayer)
        
        self.captureSession.startRunning()
        
        return true
    }
    
    func takePhoto(){
        if let stillOutput = self.stillImageOutput {
            //スレッドで安全に利用してクラッシュしないように
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
                //ビデオコネクションを探す
                //self.videoconnection = AVCaptureConnection()!
                for connecton in stillOutput.connections {
                    //入力ポートを探す
                    for port in connecton.inputPorts!{
                        if port.mediaType == AVMediaTypeVideo {
                            self.videoconnection = connecton as! AVCaptureConnection
                            break //ポート
                        }
                    }
                    if self.videoconnection  != nil {
                        break//接続
                    }
                }
                if self.videoconnection  != nil {
                    self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.videoconnection){
                        (imageSampleBuffer : CMSampleBuffer!, _) in
                        let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
                        var pickedImage: UIImage = UIImage(data: imageDataJpeg)!
                    }
                    self.captureSession.stopRunning()
                }
            }
        }
    }
}

TimerやThreadを利用しなければ成功するので、うーん。基本的なことなのかな。以下エラーに悩まされ中


2015-04-23 07:33:12.002 test3[2362:722823] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:] - NULL sample buffer.'
*** First throw call stack:
(0x1843b42d8 0x195b800e4 0x182c21408 0x100049b00 0x10003e094 0x10003e0c0 0x10003e118 0x182c20c44 0x18436c27c 0x18436b384 0x1843699a8 0x1842952d4 0x18dab36fc 0x188e5afac 0x10004aa00 0x1961fea08)
libc++abi.dylib: terminating with uncaught exception of type NSException

まとめ

まだ終わってないので保留です。

↓こんな記事もありますよ!


2021-05-14 14:21:41

WatchOSのwatchconnectivityのFiletransferの落とし穴。と、避け方。

AppleWatch 実機だと成功するんだけど、シュミレーターだと失敗するという、、、 昔作成してた時は成功してたのになーと思って調べると、どうやら昔は成功してたみたい。watchOS6以降は...

2021-05-06 14:04:37

LINEのアニメーションスタンプ制作の落とし穴、、、失敗談

ゴールデンウィークにLINEスタンプを作成してみました。 作り切って申請も通したんですが、意図したアニメーションと違う、、、、 LINEクリエーターの画面だと、アニメーションのプレビュー...

2021-05-01 18:05:35

久しぶりのAdmobをobjective-cに実装。コンパイルエラーだらけ。バーミッション不具合でエミュレータにインスコできない。

忘れないようにメモ エミュレータにアプリをインストールする際にパーミッション系のエラーがでた時、また、iphone実機にインストールする際にも権限系のエラーが出る場合。 ターゲット→ex...
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!