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 ]; |
04 | NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset]; |
06 | if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) { |
07 | AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough]; |
09 | exportSession.outputURL = [ NSURL fileURLWithPath:videoPath]; |
11 | exportSession.outputFileType = AVFileTypeMPEG4; |
13 | CMTime start = CMTimeMakeWithSeconds(0.0, 600); |
15 | CMTimeRange range = CMTimeRangeMake(start, [avAsset duration]); |
17 | exportSession.timeRange = range; |
19 | [exportSession exportAsynchronouslyWithCompletionHandler:^{ |
21 | switch ([exportSession status]) { |
23 | case AVAssetExportSessionStatusFailed: |
24 | NSLog (@ "Export failed: %@" , [[exportSession error] localizedDescription]); |
27 | case AVAssetExportSessionStatusCompleted: |
28 | NSLog (@ "Export Success" ); |
31 | case AVAssetExportSessionStatusCancelled: |
33 | NSLog (@ "Export canceled" ); |
43 | [exportSession release]; |
이 중에서 초기화 부분이 중요한데 presetName 에
아래처럼 AVAssetExportPresetPassthrough 를 지정해 주어야 다른 포멧으로 변환이 가능하다
1 | [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough]; |
아래와 같이 AVAssetExportPresetMediumQuality 와 같은 파라미터를 주고 outputFileType를 AVFileTypeMPEG로 주게 되면 SIGNAL ABORT가 발생하고 죽게 된다.
1 | AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset AVAssetExportPresetMediumQuality]; |
3 | exportSession.outputFileType = AVFileTypeMPEG4; |
해당 AVAssetExportSession 의 지원되는 output 포멧을 확인하고 싶을때는 AVAssetExportSession 의 supportedFileTypes propert를 통해서 확인해 볼 수가 있다.
추가로 유의 할 것은 이 방식은 asynchronous 이다.
그렇기 때문에 위와 같이 변환을 한 이후에 바로 이를 이용할수 있는것이 아니다
01 | [exportSession exportAsynchronouslyWithCompletionHandler:^{ |
03 | switch ([exportSession status]) { |
05 | case AVAssetExportSessionStatusFailed: |
06 | NSLog (@ "Export failed: %@" , [[exportSession error] localizedDescription]); |
09 | case AVAssetExportSessionStatusCompleted: |
10 | NSLog (@ "Export Success" ); |
13 | case AVAssetExportSessionStatusCancelled: |
15 | NSLog (@ "Export canceled" ); |
25 | [exportSession release]; |
당황하지 않길 바란다 이 소스는 위에 있는 전체 소스의 일부분이다.
따라서 위 소스와 같이 exportAsynchronouslyWithCompletionHandler 를 등록하여 "AVAssetExportSessionStatusCompleted"를 확인해야 한다.