http://hagulu.com/134?TSSESSIONhagulucom=61b070e13499ee1c53a5876e284219c8


안드로이드와 호환이 되는 파일 전송을 구현하다 보니 동영상 전송에 문제가 발생했다.

 
일반적으로 아이폰 비디오 레코더를 이용을 하게되면,
mov라를 확장자의 quickTimeMovie라는 방식으로 저장이 되어 진다.
이 파일을 그대로 안드로이드에 전송을 했더니
안드로이드에서는 하드웨어 코덱을 통해서는 재생을 할수가 없었다.
quick time movie 와  mpeg-4는 외부 포멧만 다를뿐 내부의 영상과 음성 코덱은 유사하다.
따라서 빠르게 변환이 가능한 방법이 있지 않을까 하고 찾다가 방법을 찾게 되었다.
바로 iOS 4 부터 지원되는 AssetLibrary를 이용하는 방법이다
이를 통해서 아래와 같이 구현해 보았다.
변환을 원하는 파일의 NSURL 과 저장을 원하는 파일 path의 NSString 을 주면 해당 path에 저장이 되게 된다.
01+ (void) convertVideoQtimeToMpeg4:(NSURL *) videoURL withPath:(NSString*)videoPath {
02    AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
03     
04    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
05 
06    if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) {
07        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
08         
09        exportSession.outputURL = [NSURL fileURLWithPath:videoPath];
10         
11        exportSession.outputFileType = AVFileTypeMPEG4;
12         
13        CMTime start = CMTimeMakeWithSeconds(0.0, 600);
14         
15        CMTimeRange range = CMTimeRangeMake(start, [avAsset duration]);
16         
17        exportSession.timeRange = range;
18         
19        [exportSession exportAsynchronouslyWithCompletionHandler:^{
20             
21            switch ([exportSession status]) {
22                     
23                case AVAssetExportSessionStatusFailed:
24                    NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
25                    break;
26 
27               case AVAssetExportSessionStatusCompleted:
28                     NSLog(@"Export Success");
29                     break;
30                     
31                case AVAssetExportSessionStatusCancelled:
32                     
33                    NSLog(@"Export canceled");
34                     
35                    break;
36                     
37                default:
38                     
39                    break;
40                     
41            }
42             
43            [exportSession release];
44             
45        }];
46         
47    }
48}
이 중에서 초기화 부분이 중요한데 presetName 에
아래처럼 AVAssetExportPresetPassthrough 를 지정해 주어야 다른 포멧으로 변환이 가능하다
 
1[[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
아래와 같이 AVAssetExportPresetMediumQuality 와 같은 파라미터를 주고 outputFileType를 AVFileTypeMPEG로 주게 되면 SIGNAL ABORT가 발생하고 죽게 된다.
 
1AVAssetExportSession *exportSession  = [[AVAssetExportSession alloc]initWithAsset:avAsset AVAssetExportPresetMediumQuality];
2 
3exportSession.outputFileType = AVFileTypeMPEG4;
해당 AVAssetExportSession 의 지원되는 output 포멧을 확인하고 싶을때는 AVAssetExportSession 의 supportedFileTypes propert를 통해서 확인해 볼 수가 있다.


추가로 유의 할 것은 이 방식은 asynchronous 이다.

그렇기 때문에 위와 같이 변환을 한 이후에 바로 이를 이용할수 있는것이 아니다
01[exportSession exportAsynchronouslyWithCompletionHandler:^{
02       
03      switch ([exportSession status]) {
04               
05          case AVAssetExportSessionStatusFailed:
06              NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
07              break;
08 
09         case AVAssetExportSessionStatusCompleted:
10               NSLog(@"Export Success");
11               break;
12               
13          case AVAssetExportSessionStatusCancelled:
14               
15              NSLog(@"Export canceled");
16               
17              break;
18               
19          default:
20               
21              break;
22               
23      }
24       
25      [exportSession release];
26       
27  }];
당황하지 않길 바란다 이 소스는 위에 있는 전체 소스의 일부분이다. 

따라서 위 소스와 같이 exportAsynchronouslyWithCompletionHandler 를 등록하여 "AVAssetExportSessionStatusCompleted"를 확인해야 한다.


      
Posted by k_ben