【问题标题】:Reducing the size of a video exported with AVAssetExportSession - iOS Swift减少使用 AVAssetExportSession 导出的视频的大小 - iOS Swift
【发布时间】:2018-11-06 17:25:10
【问题描述】:

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

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

【问题讨论】:

  • 不是重复的,上下文不同。我在这里使用 AVAssetExportSession。
  • 您是否尝试过其他导出预设选项 - 例如AVAssetExportPresetMediumQuality ?
  • @EvgenyKarkan 是的,但是质量差到无法接受。
  • @holex "AVAssetExportSession 与默认设置一起使用。" - 感谢您的有毒评论。
  • @dfi 这个问题与这个问题有关:stackoverflow.com/questions/50700076/…

标签: swift avfoundation ios11 avassetexportsession avkit


【解决方案1】:

要减小文件大小,请尝试使用这些属性设置 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:

另外,看看这个SO post about video bitrate in iOS

【讨论】:

  • 首先,非常感谢您对我的帮助!您的回答将大小从 20MB 减小到了惊人的 4MB。我爱你,伙计!你不知道我研究了多长时间来实现这一目标。 - 你是我的英雄。我无法使用 HEVC,所以我按照您的建议使用了 h264。非常感谢!
  • 检查 samplebuffer 中包含的数据类型。 stackoverflow.com/questions/23216610/…
  • 你好,安迪!经过几天的忙碌,我终于设法解决了我的问题。 iOS 11 中存在一个活跃的错误,该错误会导致镜像视频的大小问题。我手动镜像了视频,现在它工作得很好。祝福你的帮助!
  • 我正在获取 NextLevelSessionExporter,写入失败,Error Domain=AVFoundationErrorDomain Code=-11800 \"操作无法完成\" UserInfo={NSLocalizedFailureReason=发生未知错误 (-12780),NSLocalizedDescription=操作无法完成,NSUnderlyingError=0x282fb4570 {Error Domain=NSOSStatusErrorDomain Code=-12780 \"(null)\"}}" 一直存在..任何人都遇到过这个问题
  • 我不知道为什么。我在 Xcode 9 中尝试过,一切正常。
【解决方案2】:

终于破解了。

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2019-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-21
      • 2013-07-01
      • 1970-01-01
      • 2012-02-23
      相关资源
      最近更新 更多