본문 바로가기
ios 뽀개기/objective-c

UIImagePickerController를 이용한 비디오

by 인생여희 2018. 12. 7.
반응형

UIImagePickerController를 이용한 비디오





뷰컨트롤러



#import <UIKit/UIKit.h>

#import "ImagePickerController.h"

#import "ListTableViewController.h"




@interface ViewController : UIViewController


@property(nonatomic,strong) ImagePickerController *imagePickerController;


- (IBAction)cameraBtn:(id)sender;


- (IBAction)librayBtn:(id)sender;


@end




#import "ViewController.h"


@interface ViewController ()


@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

}



- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


//카메라 띄우기

- (IBAction)cameraBtn:(id)sender {

    NSLog(@"ViewController - UIImagePickerController 선택되었습니다.");

    //UIImagePickerController 생성 + 초기화 하고

    self.imagePickerController = [ImagePickerController new];

    ImagePickerController *myCameraInstance = [_imagePickerController getCameraVC];

    

    [self presentViewController: myCameraInstance animated:YES completion:nil];

    

}


//라이브러리 띄우기

- (IBAction)librayBtn:(id)sender {

    

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

    ListTableViewController *viewController = [[ListTableViewController alloc]init];

    [self presentViewController:viewController animated:YES completion:nil];

    

}


@end


카메라컨트롤러

/*

 앱에서 비디오 캡쳐를 하는 가장 쉬운 방법은 UIImagePickerController 이용하는 것

 UIImagePickerController를 사용하려면

 <UINavigationControllerDelegate, UIImagePickerControllerDelegate>를 구현해야한다.

 */



#import <Foundation/Foundation.h>

#import <MobileCoreServices/MobileCoreServices.h>

#import <AssetsLibrary/AssetsLibrary.h>     //사진첩 관련 api

#import <UIKit/UIKit.h>                                 //카메라 api 관련 라이브러리


@interface ImagePickerController : NSObject <UINavigationControllerDelegate,UIImagePickerControllerDelegate,UIAlertViewDelegate>



@property(strong, nonatomic) NSURL* videoRecodUrl;



//UIImagePickerController 맴버 변수

@property (strong,nonatomic) UIImagePickerController *camera;



//UIImagePickerController리턴 해주는 메소드

-(UIImagePickerController *) getCameraVC;


@end


#import "ImagePickerController.h"


@implementation ImagePickerController




//초기화

-(id)init

{

    self = [super init];

    if (self) {

        NSLog(@"ImagePickerController 초기화 시작");

        _camera = [self setupImagePickController];

        NSLog(@"ImagePickerController 초기화 완료");

    }

    return self;

}





//초기화된 UIImagePickerController객체 던져주기

-(UIImagePickerController *) getCameraVC{

    return _camera;

}



/*

* UIImagePickerController객체를 만들고

* 카메라 롤에 카메라를 저장하고 카메라를 닫는 기능 등.. 기록 된 비디오를 추가로 처리하는 델리게이트를 정의

*/


//UIImagePickerController 객체 생성 및 초기화

-(UIImagePickerController *)setupImagePickController{

    NSLog(@"ImagePickerController - setupImagePickController 진입");

    UIImagePickerController *camera;

    //비디오 레코딩을 지원하는지 확인하고

    if ([self canVideoRecoding]) {

        camera = [UIImagePickerController new];

        camera.sourceType = UIImagePickerControllerSourceTypeCamera;

        camera.mediaTypes = @[(NSString *)kUTTypeMovie];

        camera.delegate = self;

        NSLog(@"ImagePickerController - UIImagePickerController 객체 생성 + 소스타입 + 미디어 타입 + 델리게이트 설정");

    }

    return camera;

}





//카메라를 인스턴스화 하기 전에 먼저 장치에서 비디오 녹화가 지원되는지 확인


-(BOOL)canVideoRecoding

{

     NSLog(@"ImagePickerController : canVideoRecoding - 진입");

 BOOL checkCamera =  [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];

    

    NSLog(@"ImagePickerController : checkCamera : %s", checkCamera ? "true" : "false");

    //true

    

    if (checkCamera) {

       

        NSArray *canMediaType =  [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];

    

        NSLog(@"ImagePickerController : canMediaType : %@ " , canMediaType);

        //("public.image","public.movie")


        

        if ([canMediaType containsObject:(NSString *)kUTTypeMovie]) {

            NSLog(@"ImagePickerController : canVideoRecoding - 비디오 레코딩 지원됩니다.");

            return YES;

        }

        

    }

    return NO;

}



#pragma camera config Method -  참고

//카메라 구성(cameraDevice속성 을 설정)

//설정하려는 카메라가 사용가능한지 확인

- (BOOL)checkFrontCameraPicker:(UIImagePickerController *)picker

{

    NSLog(@"ImagePickerController - checkFrontCameraPicker 카메라 구성(cameraDevice속성 을 설정");

    if([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront]){

        [picker setCameraDevice:UIImagePickerControllerCameraDeviceFront];

        return YES;

    }

    return NO;

}


//UIImagePickerController는 완벽한 카메라 ui가 제공된다.

//하지만 기본 컨트롤러 위에 자신이 만든 커스텀 컨트롤러를 사용하기 원할때

- (void)configureCustomPicker:(UIImagePickerController *)picker

{

    NSLog(@"ImagePickerController - configureCustomPicker 커스텀 컨트롤러를 사용");

    

    UIView *cameraOverlay = [[UIView alloc] init];

    picker.showsCameraControls = NO;

    picker.cameraOverlayView = cameraOverlay;

}



#pragma mark - UIImagePickerControllerDelegateMethod - 카메라 델리게이트 메소드


//*참고*

//1. videoAtPathIsCompatibleWithSavedPhotosAlbum : 내가 지정한 동영상 소스의 포토 앨범에 저장 가능 여부

//2. writeVideoAtPathToSavedPhotosAlbum : 지정된 동영상 소스를 포토 앨범으로 복사

//3. completionBlock 메소드의 실행이 완료되고나서 성공 여부를 알려주는 콜백


//4.iOS 내에서 동영상 인코딩하고 포토앨범에 저장할때 사용한다.

//5.iOS 4.0 이상에서 사용 가능하다.

//6.반드시 AssetsLibrary framework 추가해야 한다.


//*저장할때 참고*

//UIImagePickerController 는 앨범열고 하나 선택해서 array 추가 다시 앨범열고 array 추가

// ALAssetsLibrary 통째로 다 가져올 수 있음



//카메라 촬영하고 자장을 눌렀을때 호출

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{

    NSLog(@"ImagePickerController - didFinishPickingMediaWithInfo 진입");

    

    //저장 위치와 카메라 객체는 맴버변수로 할당

    _videoRecodUrl = [info objectForKey:UIImagePickerControllerMediaURL];

    _camera = picker;

    

    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"저장위치" message:@"문서에 저장하시겠습니까?" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:@"NO", nil];

    [alert show];


}



//취소

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{

    NSLog(@"ImagePickerController - imagePickerControllerDidCancel");

     [picker dismissViewControllerAnimated:YES completion:nil];

}




//얼러트

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

{

    if (buttonIndex == 0)

    {

        //Code for OK button - 문서에 저장하기

        //문서위치

       NSString*documentdirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

        NSLog(@"ImagePickerController documentdirectory : %@ ", documentdirectory);

        

        //데이트 포멧으로 파일명 지정

       NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];

        [dateFormatter setDateFormat:@"yyyy-MM-dd_HH-mm-ss"];

         NSString *destinationPath= [documentdirectory stringByAppendingFormat:@"/my_test_video_%@.mov",[dateFormatter stringFromDate:[NSDate date]]];

        

        NSLog(@"ImagePickerController destinationPath : %@ ", destinationPath);

        

         NSError *error;

        

         //넘어온 url 위치에 있는 파일을 -> 새로 지정한 url 위치로 복사해라

        [[NSFileManager defaultManager] copyItemAtURL: _videoRecodUrl toURL:[NSURL fileURLWithPath:destinationPath] error:&error];

       

        if(error){

            NSLog(@"복사중에 에러가 발생했습니다! error copying file: %@", [error localizedDescription]);

        }

        

        //종료

         [_camera dismissViewControllerAnimated:YES completion:nil];

        

        

        

    }

    //사진첩에 저장하기

    if (buttonIndex == 1)

    {

        

        ALAssetsLibrary *libray = [[ALAssetsLibrary alloc]init];

        

        NSLog(@"ImagePickerController - videoRecodUrl  : %@" ,_videoRecodUrl);

        

        //내가 지정한 동영상 소스의 포토 앨범에 저장 가능 여부

        BOOL checkSaveVideo = [libray videoAtPathIsCompatibleWithSavedPhotosAlbum:_videoRecodUrl];

        NSLog(@"ImagePickerController : checkSaveVideo : %s", checkSaveVideo ? "true" : "false");

        

        if (checkSaveVideo) {

            [libray writeVideoAtPathToSavedPhotosAlbum:_videoRecodUrl completionBlock:^(NSURL *assetURL, NSError *error) {

                NSLog(@"assetURL : %@" , assetURL);

                

            }];

        }

        [_camera dismissViewControllerAnimated:YES completion:nil];

    }

}




@end

파일리스트


#import <UIKit/UIKit.h>

#import "VideoCell.h"

#import <MediaPlayer/MediaPlayer.h>


@interface ListTableViewController : UITableViewController{

MPMoviePlayerController *mp;

}

@property(strong,nonatomic) NSMutableArray * videoList;


@end



#import "ListTableViewController.h"


@interface ListTableViewController ()


@end


@implementation ListTableViewController

@synthesize videoList;




- (id)init

{

    self = [super initWithStyle:UITableViewStylePlain];

    

    if (self) {

        NSFileManager *fm = [NSFileManager defaultManager];

        //다큐먼트 폴더가 존재하는지 확인

        NSArray *DocumentDrectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        NSLog(@"DocumentDrectory : %@" , DocumentDrectory[0]);

        

        NSError *error;

        [fm contentsOfDirectoryAtPath:@"/" error:&error];

        NSLog(@"디렉토리 내용 : %@ ",   [fm contentsOfDirectoryAtPath: DocumentDrectory[0] error:&error]);

        

        videoList = [[NSMutableArray alloc]initWithArray: [fm contentsOfDirectoryAtPath: DocumentDrectory[0] error:&error]];

        

        NSLog(@"초기화 완료, 개수 : %lu" , [videoList count]);

        

    }

    

    return self;

}


- (void)viewDidLoad {

    [super viewDidLoad];

    NSLog(@"ListTableViewController -  viewDidLoad");

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


#pragma mark - Table view data source


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

#warning Incomplete implementation, return the number of sections

    return 1;

}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

#warning Incomplete implementation, return the number of rows

    return [videoList count];

}




- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    

    static NSString *CellIdentifier = @"VideoCell";

    

    // make a video cell object or reuse one

    VideoCell *cell = (VideoCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    

    if (cell == nil) {

        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"VideoCell" owner:self options:nil];

        cell = (VideoCell *)[nib objectAtIndex:0];

        

    }

    

    NSString *name  = [self.videoList objectAtIndex:indexPath.row];

    NSLog(@"file name: %@" , name);

    

    cell.textLabel.text = name;

    

    return cell;

}



//눌렀을때 재생

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

     NSString *name = [self.videoList objectAtIndex:indexPath.row];

     NSString *slash = @"/";

    

    NSString *newName= [slash stringByAppendingString:name];

    

    NSLog(@"newName : %@" , newName);

    

    //파일이 존재하는지 확인1

    NSFileManager *fm = [NSFileManager defaultManager];

    NSArray *DocumentDrectory2 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *path2 = DocumentDrectory2[0];

    NSString *videoFilePath = [path2 stringByAppendingString:newName];

    

    NSLog(@"오픈할 파일 경로 :  %@" , videoFilePath );

    //파일이 존재하는 지 확인2

    if ([fm fileExistsAtPath: videoFilePath]) {

        NSLog(@"파일이 존재합니다.");


        NSURL *videoURL = [NSURL fileURLWithPath:videoFilePath];

        mp = [[MPMoviePlayerViewController alloc] initWithContentURL: videoURL];

        [self presentMoviePlayerViewControllerAnimated:mp];

    }else{

        NSLog(@"파일이 존재하지 않습니다.");

    }

    

}


@end


테이블셀


#import <UIKit/UIKit.h>


@interface VideoCell : UITableViewCell


@end



#import "VideoCell.h"


@implementation VideoCell


- (void)awakeFromNib {

    [super awakeFromNib];

    // Initialization code

}


- (void)setSelected:(BOOL)selected animated:(BOOL)animated {

    [super setSelected:selected animated:animated];


    // Configure the view for the selected state

}


@end


로그


1. 뷰컨트롤러에 버튼 두개 만들기


2. info.plist 에 카메라, 오디오 녹음, 사진 라이브러리 관련 권한 주기


3. 라이브러리 추가하기 AssetsLibray, MobileCoreService, AVFoundation,MediaPlayer


4.이미지 피커 컨트롤러 생성


- 필요한 라이브러리 임포트

-델리게이트 상속


5. 뷰컨트롤러에서 버튼 만들고 카메라 컨트롤러 띄우기







**********************작동별 로그**************


<카메라를 열었을때>


ViewController - UIImagePickerController 선택되었습니다.



ImagePickerController 초기화 시작

ImagePickerController : canVideoRecoding - 진입 - 초기화 시작전 카메라 권한체크!


ImagePickerController : checkCamera : true

ImagePickerController : canMediaType : (

"public.image",

"public.movie"

)


ImagePickerController : canVideoRecoding - 비디오 레코딩 지원됩니다.


ImagePickerController - setupImagePickController 진입


ImagePickerController - UIImagePickerController의 객체 생성 + 소스타입 + 미디어 타입 + 델리게이트 설정


ImagePickerController 초기화 완료



<취소했을때>


ImagePickerController - imagePickerControllerDidCancel





<녹화후 저장했을 때>


ImagePickerController - didFinishPickingMediaWithInfo 진입


magePickerController - videoRecodUrl  : file:///private/var/mobile/Containers/Data/Application/3B7B8C2A-0432-4101-8D20-417999ED8AA8/tmp/56584213032__5440B498-E9B0-4A26-BB1F-5E6A489C1FD8.MOV


ImagePickerController : checkSaveVideo : true


assetURL : assets-library://asset/asset.MOV?id=DDFBBA97-C0F6-45B8-96A8-C7BB46ED031D&ext=MOV

UIImagePickerControllerExample.zip

예제파일



반응형

댓글