トップ «前の日記(2015-04-29) 最新 次の日記(2015-06-26)» 編集

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|

2015-05-06 [iOS]動画を保存する(その二)

音声も動画も、同じデリゲートのメソッドで受けるようにしている。

書き込む動画の形式は、録画されたデータを受け取ってみないと分からないので、最初のサンプリング・データ受信に形式を取得している。

            if self.assetWriter == nil {
                let fileManager = NSFileManager()
                if fileManager.fileExistsAtPath(self.outputFilePath!) {
                    fileManager.removeItemAtPath(self.outputFilePath!, error: nil)
                }
                
                if captureOutput == self.videoDataOutput {
                }
                else if captureOutput == self.audioDataOutput {
                    let fmt = CMSampleBufferGetFormatDescription(sampleBuffer)
                    let asbd = CMAudioFormatDescriptionGetStreamBasicDescription(fmt)
                    
                    var outError: NSError? = nil
                    let url = NSURL(fileURLWithPath: self.outputFilePath!)
                    self.assetWriter = AVAssetWriter(URL: url, fileType: AVFileTypeQuickTimeMovie, error: &outError)
                    
                    let videoOutputSettings: Dictionary = [
                        AVVideoCodecKey : AVVideoCodecH264,
                        AVVideoWidthKey : self.width,
                        AVVideoHeightKey : self.height
                    ]
                    self.videoAssetWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: videoOutputSettings)
                    self.videoAssetWriterInput!.expectsMediaDataInRealTime = true
                    self.assetWriter!.addInput(self.videoAssetWriterInput)
                    
                    let audioOutputSettings: Dictionary = [
                        AVFormatIDKey : kAudioFormatMPEG4AAC,
                        AVNumberOfChannelsKey : Int(asbd.memory.mChannelsPerFrame),
                        AVSampleRateKey : asbd.memory.mSampleRate,
                        AVEncoderBitRateKey : 128000
                    ]
                    self.audioAssetWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: audioOutputSettings)
                    self.audioAssetWriterInput!.expectsMediaDataInRealTime = true
                    self.assetWriter!.addInput(self.audioAssetWriterInput)
                }
            }

録画したサンプリングデータの追記は、以下のコードで呼び出すだけだ。

                if captureOutput == self.videoDataOutput {
                    self.videoAssetWriterInput!.appendSampleBuffer(sampleBuffer)
                }
                else if captureOutput == self.audioDataOutput {
                    self.audioAssetWriterInput!.appendSampleBuffer(sampleBuffer)
                }

終了処理で書き込んだ動画ファイルをアルバムに保存している。

            captureSession.stopRunning()
            self.assetWriter?.finishWritingWithCompletionHandler({() -> Void in
                self.assetWriter = nil
                let assetsLib = ALAssetsLibrary()
                assetsLib.writeVideoAtPathToSavedPhotosAlbum(NSURL(fileURLWithPath: self.outputFilePath!), completionBlock: {(assetURL: NSURL!, error: NSError!) -> Void in
                })
            })

_ ソースコード

GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/SequenceGrabber - GitHub

_ 【Cocoa練習帳】

http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)

トップ «前の日記(2015-04-29) 最新 次の日記(2015-06-26)» 編集