今回は動画の拡大縮小を行ってみる。
元動画のサイズは1080x1920なので1/3である360x640に縮小する。
前回との違いは、元動画の一部を切り出すのではなく、360x640に動画が収まるようにすることだ。

処理イメージ
movie_shrink_ss1

ソースコードはこうなる。
const int kVideoFPS = 30;

- (void)shrinkMovie
{
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *inputPath = [[path stringByAppendingPathComponent:@"portrait1"] stringByAppendingPathExtension:@"mov"];
    NSString *outputPath = [[path stringByAppendingPathComponent:@"result"] stringByAppendingPathExtension:@"mov"];
    
    AVMutableComposition *composition = [AVMutableComposition composition];
    AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    NSError *error;
    
    NSURL *inputURL = [NSURL fileURLWithPath:inputPath];
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:inputURL options:nil];
    
    CMTimeRange range = CMTimeRangeMake(kCMTimeZero, asset.duration);
    
    AVAssetTrack *videoTrack = [asset tracksWithMediaType:AVMediaTypeVideo][0];
    AVAssetTrack *audioTrack = [asset tracksWithMediaType:AVMediaTypeAudio][0];
    
    [compositionVideoTrack insertTimeRange:range ofTrack:videoTrack atTime:kCMTimeZero error:&error];
    [compositionAudioTrack insertTimeRange:range ofTrack:audioTrack atTime:kCMTimeZero error:&error];
    
    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    instruction.timeRange = range;
    
    AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack];
    
    CGSize videoSize = videoTrack.naturalSize;
    CGAffineTransform transform = videoTrack.preferredTransform;;
    if (transform.a == 0 && transform.d == 0 && (transform.b == 1.0 || transform.b == -1.0) && (transform.c == 1.0 || transform.c == -1.0))
    {
        videoSize = CGSizeMake(videoSize.height, videoSize.width);
    }
    
    // 1
    videoSize = CGSizeMake(360, 640);
    transform = CGAffineTransformConcat(transform, CGAffineTransformMakeScale(1.0f/3.0f, 1.0f/3.0f));
    
    [layerInstruction setTransform:transform atTime:kCMTimeZero];
    instruction.layerInstructions = @[layerInstruction];
    
    AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
    videoComposition.renderSize = videoSize;
    videoComposition.instructions = @[instruction];
    videoComposition.frameDuration = CMTimeMake(1, kVideoFPS);
    
    NSFileManager *fm = [NSFileManager defaultManager];
    if ([fm fileExistsAtPath:outputPath])
    {
        [fm removeItemAtPath:outputPath error:&error];
    }
    
    AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetHighestQuality];
    session.outputURL = [NSURL fileURLWithPath:outputPath];
    session.outputFileType = AVFileTypeQuickTimeMovie;
    session.videoComposition = videoComposition;
    
    [session exportAsynchronouslyWithCompletionHandler:^{
        if (session.status == AVAssetExportSessionStatusCompleted)
        {
            NSLog(@"output complete!");
        }
        else
        {
            NSLog(@"output error! : %@", session.error);
        }
    }];
}

今回も前回のソースコードとほとんど変わらない。
変わっているのはほんの一行だけだ。

1.動画用の行列を設定する。
1080x1920→360x640とするので、x,yを1/3にする行列を使う。

たったこれだけだ。
これを実行すると、望み通り縮小された動画が出力される。

関連記事
[iOS] 動画を加工・編集する(1) 指定した時間の範囲を切り出す
[iOS] 動画を加工・編集する(2) エラーコード-11841に気をつける
[iOS] 動画を加工・編集する(3) 動画に音を合成する
[iOS] 動画を加工・編集する(4) 動画をクリッピングする
[iOS] 動画を加工・編集する(6) 複数の動画を連結する