Download - 6秒動画アプリ Vineの作り方
![Page 1: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/1.jpg)
How to make “Vine” like app?
6秒動画アプリ Vineの作り方
iOS_LT #13 / @himara2
2014/05/28(Wed.)
![Page 2: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/2.jpg)
Vine・Twitter社の動画アプリ
・6秒動画アプリ
・画面を押してる間だけ撮影
・短い動画が連結される
特徴
・ループ再生される
![Page 3: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/3.jpg)
Vineっぽい機能を実装してみよう。
![Page 4: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/4.jpg)
Vineっぽい機能
・6秒動画アプリ・画面を押してる間だけ撮影・撮影した短い動画が連結される・ループ再生される
![Page 5: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/5.jpg)
Vineっぽい機能
・6秒動画アプリ・画面を押してる間だけ撮影・撮影した短い動画が連結される・ループ再生される
![Page 6: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/6.jpg)
AVFoundation framework をつかう。
![Page 7: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/7.jpg)
撮影編
![Page 8: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/8.jpg)
@tomonish くんが発表してたやつ
http://www.slidesharenet.org/ssuser9c7e21/avfoundation
![Page 9: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/9.jpg)
![Page 10: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/10.jpg)
①
②
③
![Page 11: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/11.jpg)
①AVCaptureSesison の準備
// セッションの作成 self.session = [[AVCaptureSession alloc] init]; _session.sessionPreset = AVCaptureSessionPresetHigh;
@property (nonatomic) AVCaptureSession *session;
![Page 12: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/12.jpg)
②入力デバイス(カメラ)の準備
// 入力デバイスの設定 AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; ! AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil]; ! [_session addInput:input];
![Page 13: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/13.jpg)
③出力デバイス(ファイル)の準備
// 出力デバイスの作成 self.output = [[AVCaptureMovieFileOutput alloc] init]; CMTime maxDuration = CMTimeMakeWithSeconds(60, 30); _output.maxRecordedDuration = maxDuration; _output.minFreeDiskSpaceLimit = 1024 * 1024; ! [_session addOutput:_output];
![Page 14: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/14.jpg)
これで準備はOK!
// セッションを開始 [_session startRunning];
セッションの開始
![Page 15: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/15.jpg)
NSString *outputPath = [[NSString alloc] initWithFormat:@“%@%@%d.mp4”, NSTemporaryDirectory(), @“output", outputIndex]; NSURL *fileURL = [NSURL fileURLWithPath:outputPath]; ! [_output startRecordingToOutputFileURL:fileURL recordingDelegate:self];
録画開始のタイミングで…
録画停止のタイミングで…
[_output stopRecording];
![Page 16: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/16.jpg)
#pragma mark - AVCaptureFileOutputRecordingDelegate !// 録画開始 - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections { NSLog(@"rec start."); } !!// 録画停止 - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error { NSLog(@"rec end."); // 出力ファイルを指定しておく [_outputPathes addObject:outputFileURL]; }
Delegate method
保存したファイルパスをArrayで保持しておく
![Page 17: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/17.jpg)
撮影開始 → 撮影終了 で.mp4
outputPathes (NSArray)
![Page 18: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/18.jpg)
合成編
![Page 19: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/19.jpg)
①コンポジションの準備
// コンポジション生成
self.composition = [AVMutableComposition composition]; AVMutableCompositionTrack *compositionVideoTrack = [_composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
![Page 20: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/20.jpg)
②動画の合成 CMTime startTime = kCMTimeZero; for (NSURL *url in _outputPathes) { // 動画アセットの取得 AVAsset *asset = [AVAsset assetWithURL:url]; AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:videoTrack atTime:startTime error:nil]; startTime = CMTimeAdd(startTime, asset.duration); }
![Page 21: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/21.jpg)
②動画の合成 CMTime startTime = kCMTimeZero; for (NSURL *url in _outputPathes) { // 動画アセットの取得 AVAsset *asset = [AVAsset assetWithURL:url]; AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:videoTrack atTime:startTime error:nil]; startTime = CMTimeAdd(startTime, asset.duration); }
![Page 22: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/22.jpg)
CMTime startTime = kCMTimeZero; for (NSURL *url in _outputPathes) { // 動画アセットの取得 AVAsset *asset = [AVAsset assetWithURL:url]; AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:videoTrack atTime:startTime error:nil]; startTime = CMTimeAdd(startTime, asset.duration); }
kCMTimeZero
asset.duration
asset1asset2
asset3
assetの終端に次のassetをinsertしていく
![Page 23: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/23.jpg)
③合成した動画の出力
// 出力する self.exporter = [[AVAssetExportSession alloc] initWithAsset:_composition presetName:AVAssetExportPresetHighestQuality]; _exporter.videoComposition = videoComposition; _exporter.outputURL=[NSURL fileURLWithPath:outputPath]; _exporter.outputFileType = AVFileTypeQuickTimeMovie; [_exporter exportAsynchronouslyWithCompletionHandler:^(void){ // export成功時の処理(カメラロールへの保存など) ! }];
![Page 24: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/24.jpg)
「撮影した短い動画の連結」完成!
※音声込みの動画にしたい場合は Audioも録音・合成する必要があります
![Page 25: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/25.jpg)
参考資料AVFoundationを使ったキャプチャ機能 - SlideShare
AVFoundationで動画の加工合成処理 - qiita
iOS4プログラミングブック - Amazon
・撮影に関するクラスの俯瞰に
・合成や編集に関するクラスの俯瞰に
・体系的におさえるならコレ
![Page 26: 6秒動画アプリ Vineの作り方](https://reader035.vdocuments.pub/reader035/viewer/2022081716/540d117c7bef0a84278b9913/html5/thumbnails/26.jpg)
おわり