Swift転職なら=>【LevTech】
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

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

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

まとめ

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

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

presentViewControllerで画面遷移下からビョーン

下からビョーンとUIViewControllerを出す方法を記載します。この処理も多用していたのですがこのHPになかったので追記しました。 Navigationと連動させた横へシャーと移動するスライドの関数(pop)とは違うので注意です。

AppleWatchをNSFileCoordinatorとKeychainでデータ交換

前回の記事(ナターシャさんのサンプルデモを元に解説)の続きです。今記事はNSUserDefaultではなく、 NSFileCoordinatorとKeychain sharingを利用しての解説です。ナターシャさんのサンプルに関して前記事をご参照ください。

AppleWatchアプリの申請

AppleWatchアプリの申請が4月1日から始まりましたので、少しトライしてみました。ハマった箇所を共有です。 アプリをArchiveしてValidateしてから2パターンの不具合、あとはアップロードには成功したのですが、Itunesに反映されなかった 現象を共有です
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!