【问题标题】:AVAssetExportSession -how to trim millisecond from video durationAVAssetExportSession - 如何从视频持续时间中修剪毫秒
【发布时间】:2021-01-17 18:15:08
【问题描述】:

使用 AVAssetExportSession 时如何从 videoUrl 中修剪毫秒数?我正在使用下面的代码,根据资产的数量及其时间范围,最终视频的持续时间为 15.233333334 秒或 17.9333333334 秒。将它们全部加在一起后,我想将 mixComposition 修剪为 15 秒、17 秒等。

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

// ...

【问题讨论】:

  • 您真的要丢帧吗?或者您只是想在呈现时舍入持续时间?
  • 我没有丢几帧。如果我将它四舍五入到最高数字,例如 17.933333 将是 18,会显示什么 - 黑屏?
  • 如果您的意图只是修剪输出,您只需要更改范围的持续时间。
  • 我从链接中使用了您的 CMTime 扩展。谢谢!

标签: ios swift avfoundation


【解决方案1】:

我发现这样做很容易。有一个名为 trunc() 的内置方法会截断任何余数,只留下一个整数。

如果使用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

如果使用照片库中的网址:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多