Virasio
Virasio

Reputation: 490

AVMutableComposition insertTimeRange: uses wrong range

I need trim many videos, and then show preview of their compilation. User can edit start time and end time for every video, and I show preview of current video (while user trim) with code:

AVPlayer *player = [AVPlayer playerWithURL:[NSURL URLWithString:video.fileURL]];
int32_t timeScale = player.currentItem.asset.duration.timescale;
float startTime = video.startTime;
float endTime = video.endTime > 0 ? video.endTime : video.duration;
player.currentItem.forwardPlaybackEndTime = CMTimeMakeWithSeconds(endTime, timeScale);
[player seekToTime:CMTimeMakeWithSeconds(startTime, timeScale)
   toleranceBefore:kCMTimeZero
    toleranceAfter:kCMTimeZero
 completionHandler:^(BOOL finished) {
     if (finished) {
         [self.player play];
     }
 }];

I use AVMutableComposition for compilation preview, because I need single AVPlayerItem for GPUImage. My code:

AVMutableComposition *composition = [[AVMutableComposition alloc] init];
for (Video *video in videos) {
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:video.fileURL] options:nil];
    int32_t timeScale = asset.duration.timescale;
    CMTime startTime = CMTimeMakeWithSeconds(video.startTime, timeScale);
    CMTime duration = CMTimeMakeWithSeconds(
            (video.endTime > 0 ? video.endTime : video.duration) - video.startTime,
            timeScale);

    [composition insertTimeRange:CMTimeRangeMake(startTime, duration)
                         ofAsset:asset
                          atTime:composition.duration error:nil];
}

AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:[composition copy]];

I see different ranges of videos on a screen. Where am I wrong?

Upvotes: 1

Views: 1865

Answers (2)

Amir Ardalan
Amir Ardalan

Reputation: 437

Swift 5.1

You have to get the latest timeRange from AVMutableComposition and insert a new AVAsset at the end of the range:

self.mutableComposition.tracks.last?.timeRange.end

this return your AVMutableComposition duration and if you want to add new use:

try mutableComposition.insertTimeRange(CMTimeRange(start: .zero, duration: media.duration), of: media, at: duration ?? .zero)

Upvotes: 0

KrisJones
KrisJones

Reputation: 188

This should sort out the issue with seeing the wrong time on screen, you can change the end time if you want to stop at an earlier point. Hope this helps.

CMTime startTime = CMTimeMake((int)(floor([@(video.startTime) floatValue] * 100)), 100);
CMTime stopTime = CMTimeMake((int)(ceil([@(video.duration) floatValue] * 100)), 100);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);

    // grab the portion of interest from the master asset WHOLE MASTER TRACK
    [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, masterAsset.duration)
                        ofTrack:[[masterAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
                         atTime:kCMTimeZero
                          error:&error];

Upvotes: 1

Related Questions