Lance Samaria
Lance Samaria

Reputation: 19592

AVAssetExportSession -how to trim millisecond from video duration

How can I trim milliseconds from a videoUrl when using AVAssetExportSession? I'm using the below code which gives the final video a duration like 15.233333334 seconds or 17.9333333334 seconds depending on the number of assets and their time frames. Once they are all added together, I want to trim the mixComposition to 15 seconds, 17 seconds, etc.

AVMutableComposition:

let mixComposition = AVMutableComposition()
        
let compositionVideoTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

let soundtrackTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

var insertTime = CMTime.zero
for videoAsset in videoAssets {
    do {

        let videoTrack = videoAsset.tracks(withMediaType: .video)
        try compositionVideoTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: videoAsset.duration), videoAsset.tracks(withMediaType: .video)[0], at: insertTime)

        let audioTrack = videoAsset.tracks(withMediaType: .audio)
        try soundtrackTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: videoAsset.duration), videoAsset.tracks(withMediaType: .audio)[0], at: insertTime)

        insertTime = CMTimeAdd(insertTime, videoAsset.duration)

    } catch {

    }
}

AVAssetExportSession:

guard let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) else { return }

let start = CMTimeMakeWithSeconds(.zero, preferredTimescale: 600)
let videoDuration = CMTimeMakeWithSeconds(mixComposition.duration, preferredTimescale: 600)
let range = CMTimeRangeMake(start: start, duration: videoDuration)
exporter.timeRange = range

// ...

Upvotes: 0

Views: 333

Answers (1)

Lance Samaria
Lance Samaria

Reputation: 19592

I found an easy was to do this. There is a built in method named trunc() that truncates any remainder and only leaves a whole number.

If using a AVMutableComposition():

let mixComposition = AVMutableComposition()
// ...

let videoDuration = CMTimeGetSeconds(mixComposition.duration)
let dub = Double(videoDuration)

let durationTruncated = trunc(dub)
print(".......truncate: ", durationTruncated)

let duration = CMTimeMakeWithSeconds(durationTruncated, preferredTimescale: 600)
let start = CMTimeMakeWithSeconds(.zero, preferredTimescale: 600)
let range = CMTimeRangeMake(start: start, duration: duration)
exporter.timeRange = range

If using a url from the photoLibrary:

let asset = AVURLAsset(url: yourLibraryUrl) // if this isn't a libraryUrl you will need to run it through asset.loadValuesAsynchronously and use the "duration" asset key to get the duration first
let videoDuration = CMTimeGetSeconds(asset.duration)

let dub = Double(videoDuration)
let durationTruncated = trunc(dub)
print(".......truncate: ", durationTruncated)

let duration = CMTimeMakeWithSeconds(durationTruncated, preferredTimescale: 600)
let start = CMTimeMakeWithSeconds(.zero, preferredTimescale: 600)
let range = CMTimeRangeMake(start: start, duration: duration)
exporter.timeRange = range

Upvotes: 0

Related Questions