Friday, 14 June 2019

Mute Video + Transform Video Using single export operation of AVAssetExportSession

I have following code to fix Tranform of video

    - (AVVideoComposition *)squareVideoCompositionFor:(AVAsset *)asset {

    AVAssetTrack *track = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;

    CGFloat length = MAX(track.naturalSize.width, track.naturalSize.height);

    CGSize size = track.naturalSize;

    CGFloat scale = 0;

    CGAffineTransform transform = track.preferredTransform;

    if (transform.a == 0 && transform.b == 1 && transform.c == -1 && transform.d == 0) {
        scale = -1;
    }
    else if (transform.a == 0 && transform.b == -1 && transform.c == 1 && transform.d == 0) {
        scale = -1;
    }
    else if (transform.a == 1 && transform.b == 0 && transform.c == 0 && transform.d == 1) {
        scale = 1;
    }
    else if (transform.a == -1 && transform.b == 0 && transform.c == 0 && transform.d == -1) {
        scale = -1;
    }

    transform = CGAffineTransformTranslate(transform, scale * -(size.width - length) / 2, scale * -(size.height - length) / 2);




    AVMutableVideoCompositionLayerInstruction *transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:track];
    [transformer setTransform:transform atTime:kCMTimeZero];

//    CGAffineTransform finalTransform = t2;
//    [transformer setTransform:finalTransform atTime:kCMTimeZero];

    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, kCMTimePositiveInfinity);
    instruction.layerInstructions = @[transformer];


    AVMutableVideoComposition *composition = [AVMutableVideoComposition videoComposition];
    composition.frameDuration = CMTimeMake(1, 30);
    composition.renderSize =  CGSizeMake(length, length);
    composition.instructions = @[instruction];
    composition.renderScale = 1.0;


    return composition;
    }

And Following code for Mute Audio

- (AVMutableComposition *) removeAudioFromVideoFileFor:(AVAsset *)asset  {
    AVMutableComposition *composition_Mix = [AVMutableComposition composition];
    AVMutableCompositionTrack *compositionVideoTrack = [composition_Mix addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

    BOOL ok = NO;

    AVAssetTrack * sourceVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

    CMTimeRange x = CMTimeRangeMake(kCMTimeZero, [asset duration]);
    NSError *error;
    ok = [compositionVideoTrack insertTimeRange:x ofTrack:sourceVideoTrack atTime:kCMTimeZero error:&error];

    return composition_Mix;
}

Here how i call the function

    AVAsset *asset = [AVAsset assetWithURL:inputURL];

    AVMutableComposition *composition = [self  removeAudioFromVideoFileFor:asset];

    AVAssetExportSession *session = [AVAssetExportSession exportSessionWithAsset:composition presetName:AVAssetExportPresetHighestQuality];
    session.videoComposition = [self squareVideoCompositionFor:asset];
    session.outputURL = outputURL;
    session.outputFileType = AVFileTypeMPEG4;
    session.shouldOptimizeForNetworkUse = true;
    session.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);

But it shows error if I used both composition and [self squareVideoCompositionFor:asset]

Error Domain=AVFoundationErrorDomain Code=-11841 "Operation Stopped" UserInfo={NSLocalizedDescription=Operation Stopped, NSLocalizedFailureReason=The video could not be composed.}

If I omit one then it is working fine means One AVAssetExportSession can either mute audio from video or squareVideo

Is there a way I can achieve both using single progress of export of AVAssetExportSession ?



from Mute Video + Transform Video Using single export operation of AVAssetExportSession

No comments:

Post a Comment