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

Reducing the size of a video exported with AVAssetExportSession - iOS Swift

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

   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))
        ]

要减小文件大小,请尝试使用这些属性来设置 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 SierraiOS 11 才能使用 HEVC 视频编解码器。但是,如果您出于某种原因不能使用 HEVC,请使用比特率较低的常规 H.264

AVVideoCodecKey : AVVideoCodecType.h264:

Also, look at this .

终于破解了。

使用exportSession.fileLengthLimit = 1048576 * 10 //10 MB

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

fileLengthLimit /* Indicates the file length that the output of the session should not exceed. Depending on the content of the source asset, it is possible for the output to slightly exceed the file length limit. The length of the output file should be tested if you require that a strict limit be observed before making use of the output. See also maxDuration and timeRange. */

Lalit Kumar 的回答非常有效。在他的解决方案之上,我写了一个 AVAsset 扩展,这样我就可以轻松地设置比特率,而不是文件大小。 preferredBitrate 方法中的方程式是我的原创。您可以改用硬编码 table。

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
    }
}