AVAssetExportSession - 如何从视频持续时间中修剪毫秒

Posted

技术标签:

【中文标题】AVAssetExportSession - 如何从视频持续时间中修剪毫秒【英文标题】:AVAssetExportSession -how to trim millisecond from video duration 【发布时间】: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,会显示什么 - 黑屏? 如果您的意图只是修剪输出,您只需要更改范围的持续时间。 顺便说一句***.com/questions/54662047/… 我从链接中使用了您的 CMTime 扩展。谢谢! 【参考方案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

【讨论】:

以上是关于AVAssetExportSession - 如何从视频持续时间中修剪毫秒的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AVAssetExportSession 覆盖 iPhone/iPod 库中的歌曲?

使用 AVAssetExportSession 全屏导出视频

音频中的淡入淡出效果通过在ios中使用AVAssetExportSession

AVAssetExportSession始终无法导出

具有修改的分辨率设置的 AVAssetExportSession

AVAssetExportSession 总是无法导出