Reputation: 490
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
Reputation: 437
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
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