减少使用 AVAssetExportSession 导出的视频的大小 - iOS Swift

问题描述 投票:0回答:4

我目前正在通过以下方式导出视频:

   let exporter = AVAssetExportSession.init(asset: mixComposition, presetName: AVAssetExportPreset1280x720)
   exporter?.outputURL = outputPath
   exporter?.outputFileType = AVFileType.mp4
   exporter?.shouldOptimizeForNetworkUse = true
   exporter?.videoComposition = mainCompositionInst

一个 15 秒的视频消耗大约 20MB 的数据。与 Snapchat 的 2MB 视频相比,这个数字似乎完全不能接受。

我已经降低了导出和捕获会话 (1280x720) 的质量。

视频是用定制相机拍摄的。

UIImagePickerController
未使用。

AVAssetExportSession 使用默认设置。

有什么办法可以减小视频的大小? 非常感谢!

编辑1: 我尝试使用这个库:https://cocoapods.org/pods/NextLevelSessionExporter

不幸的是,这会造成尺寸问题并删除我的音频:

// Creating exporter
    let exporter = NextLevelSessionExporter(withAsset: mixComposition)
    exporter.outputURL = outputPath
    exporter.outputFileType = AVFileType.mp4
    exporter.videoComposition = mainCompositionInst

    let compressionDict: [String: Any] = [
        AVVideoAverageBitRateKey: NSNumber(integerLiteral: 2500000),
        AVVideoProfileLevelKey: AVVideoProfileLevelH264BaselineAutoLevel as String,
        ]

        exporter.videoOutputConfiguration = [
            AVVideoCodecKey: AVVideoCodecType.h264,
            AVVideoWidthKey: NSNumber(integerLiteral: 1280),
            AVVideoHeightKey: NSNumber(integerLiteral: 720),
            AVVideoScalingModeKey: AVVideoScalingModeResizeAspectFill,
            AVVideoCompressionPropertiesKey: compressionDict
        ]

        exporter.audioOutputConfiguration = [
            AVFormatIDKey: kAudioFormatMPEG4AAC,
            AVEncoderBitRateKey: NSNumber(integerLiteral: 128000),
            AVNumberOfChannelsKey: NSNumber(integerLiteral: 2),
            AVSampleRateKey: NSNumber(value: Float(44100))
        ]

swift avfoundation ios11 avassetexportsession avkit
4个回答
8
投票

要减小文件大小,请尝试使用这些属性来设置

HEVC
编解码器(使用 cocoa pod
NextLevelSessionExporter
):

let compressionDict: [String: Any] = [
AVVideoAverageBitRateKey: NSNumber(integerLiteral: 2500000), //lower it if you wish
AVVideoProfileLevelKey: AVVideoProfileLevelH264BaselineAutoLevel as String,
]
exporter.videoOutputConfiguration = [
    AVVideoCodecKey : AVVideoCodecType.hevc,
    AVVideoWidthKey : NSNumber(integerLiteral: 1280),
    AVVideoHeightKey: NSNumber(integerLiteral: 720),
    AVVideoScalingModeKey: AVVideoScalingModeResizeAspectFill,
    AVVideoCompressionPropertiesKey: compressionDict
]

您需要升级到

macOS High Sierra
iOS 11
才能使用
HEVC
视频编解码器。但是,如果由于某种原因您不能使用
HEVC
,请使用较低比特率的常规
H.264

AVVideoCodecKey : AVVideoCodecType.h264:

另外,看看这个 SO 关于 iOS 中视频比特率的帖子


6
投票

终于破解了这个。

使用

exportSession.fileLengthLimit = 1048576 * 10 //10 MB

10MB 是硬编码数字。根据您需要的比特率使用。

fileLengthLimit /* 表示输出的文件长度 会话不应超过。取决于来源的内容 资产,输出可能会略微超过文件 长度限制。如果您应该测试输出文件的长度 要求在使用之前遵守严格的限制 输出。另请参见 maxDuration 和 timeRange。 */


2
投票

Lalit Kumar 的回答非常有效。在他的解决方案之上,我写了一个 AVAsset 扩展,这样我就可以轻松地设置比特率,而不是文件大小。

preferredBitrate
方法中的方程式是我原创的。您可以改用硬编码表。

extension AVAsset {
    private var preferredBitRate: Float {
        //          720p   1080p
        //  30fps:   5.0    11.3
        //  60fps:   7.5    16.9
        // 120fps:  11.3    25.3
        // 240fps:  16.9    38.0 (Mbps)
        guard let videoTrack = self.tracks(withMediaType: .video).first else {
            return .zero
        }
        let size = Float(min(videoTrack.naturalSize.width, videoTrack.naturalSize.height))
        let frameRate = videoTrack.nominalFrameRate
        return pow(1.5, log2(frameRate / 30)) * pow(size / 720, 2) * 5
    }

    private var preferredFileLength: Int64 {
        // 1 Mbit := 125000 bytes
        return Int64(self.duration.seconds * Double(self.preferredBitRate)) * 125000
    }
}

0
投票

如果设置了fileLengthLimit值,则exportSession生成的文件的视频码率值会发生变化。 这正是我想要的。 如果要设置AVExportSession的视频码率值,计算并设置AVExportSession的fileLengthLimit值

像这样, exportSession.fileLengthLimit = Int64(Double(preferredBitrate / 8) * video duration)

谢谢 Lalit Kumar。

© www.soinside.com 2019 - 2024. All rights reserved.