在iOS上使用HEVC编码器输出视频大小巨大

在iOS上使用HEVC编码器输出视频大小巨大,ios,swift,avfoundation,avassetwriter,hevc,Ios,Swift,Avfoundation,Avassetwriter,Hevc,我有一个项目,目前使用H.264编码器在iOS上录制视频。我想尝试在iOS 11中使用新的HEVC编码器来减少文件大小,但发现使用HEVC编码器会导致文件大小急剧膨胀 AVFoundation类的设置如下所示: class VideoWriter { var avAssetWriterInput: AVAssetWriterInput var avAssetWriter: AVassetWriter init() { if #available(iOS 1

我有一个项目,目前使用H.264编码器在iOS上录制视频。我想尝试在iOS 11中使用新的HEVC编码器来减少文件大小,但发现使用HEVC编码器会导致文件大小急剧膨胀

AVFoundation类的设置如下所示:

class VideoWriter {
    var avAssetWriterInput: AVAssetWriterInput
    var avAssetWriter: AVassetWriter
    init() {
        if #available(iOS 11.0, *) {
            avAssetWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: [AVVideoCodecKey:AVVideoCodecType.hevc, AVVideoHeightKey:720, AVVideoWidthKey:1280])
        }
        avAssetWriterInput.expectsMediaDataInRealTime = true
        do {
            let url = directory.appendingPathComponent(UUID.init().uuidString.appending(".hevc"))
            avAssetWriter = try AVAssetWriter(url: url, fileType: AVFileType.mp4)
            avAssetWriter.add(avAssetWriterInput)
            avAssetWriter.movieFragmentInterval = kCMTimeInvalid
        } catch {
            fatalError("Could not initialize AVAssetWriter \(error)")
        }
    }
...
    func write(sampleBuffer buffer: CMSampleBuffer) {
        if avAssetWriter.status == AVAssetWriterStatus.unknown {
            avAssetWriter.startWriting()
            avAssetWriter.startSession(atSourceTime: CMSampleBufferGetPresentationTimeStamp(buffer))
         }
        if avAssetWriterInput.isReadyForMoreMediaData {
            avAssetWriterInput.append(buffer)
        }
    }
然后帧被写成这样:

class VideoWriter {
    var avAssetWriterInput: AVAssetWriterInput
    var avAssetWriter: AVassetWriter
    init() {
        if #available(iOS 11.0, *) {
            avAssetWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: [AVVideoCodecKey:AVVideoCodecType.hevc, AVVideoHeightKey:720, AVVideoWidthKey:1280])
        }
        avAssetWriterInput.expectsMediaDataInRealTime = true
        do {
            let url = directory.appendingPathComponent(UUID.init().uuidString.appending(".hevc"))
            avAssetWriter = try AVAssetWriter(url: url, fileType: AVFileType.mp4)
            avAssetWriter.add(avAssetWriterInput)
            avAssetWriter.movieFragmentInterval = kCMTimeInvalid
        } catch {
            fatalError("Could not initialize AVAssetWriter \(error)")
        }
    }
...
    func write(sampleBuffer buffer: CMSampleBuffer) {
        if avAssetWriter.status == AVAssetWriterStatus.unknown {
            avAssetWriter.startWriting()
            avAssetWriter.startSession(atSourceTime: CMSampleBufferGetPresentationTimeStamp(buffer))
         }
        if avAssetWriterInput.isReadyForMoreMediaData {
            avAssetWriterInput.append(buffer)
        }
    }

当它们进入
AVCaptureVideoDataOutputSampleBufferDelegate
时。在我录制的质量(720p或1080p)下,HEVC编码视频的文件大小应该是相同H.264编码视频的40-60%,当我在iOS上使用默认的摄像头应用程序时,我看到了这一点,但当我如上所述使用AVAssetWriter时(或在上面链接的项目中)我看到HEVC的文件大小大约是H.264的三倍。要么我做错了什么,要么HEVC编码器工作不正常。我是否遗漏了一些东西,或者是否有一种解决方法可以让HEVC通过AVFoundation工作?

您是否尝试指定比特率等。? 详情如下:

NSUInteger bitrate = 50 * 1024 * 1024;  // 50 Mbps
NSUInteger keyFrameInterval = 30;
NSString *videoProfile = AVVideoProfileLevelH264HighAutoLevel;
NSString *codec = AVVideoCodecH264;
if (@available(iOS 11, *)) {
    videoProfile = (NSString *)kVTProfileLevel_HEVC_Main_AutoLevel;
    codec = AVVideoCodecTypeHEVC;
}

NSDictionary *codecSettings = @{AVVideoAverageBitRateKey: @(bitrate),
                              AVVideoMaxKeyFrameIntervalKey: @(keyFrameInterval),
                              AVVideoProfileLevelKey: videoProfile};
NSDictionary *videoSettings = @{AVVideoCodecKey: codec,
                              AVVideoCompressionPropertiesKey: codecSettings,
                              AVVideoWidthKey: @((NSInteger)resolution.width),
                              AVVideoHeightKey: @((NSInteger)resolution.height)};

AVAssetWriterInput *videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
...

据我所知,在相同的比特率下,H264和HEVC的文件大小应该相同,但HEVC的质量应该更好。

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


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

我从苹果得到了类似的回复。显然,H.264的默认比特率是5mbit,HEVC是30mbit。我会报告回来,并接受你的回答,如果我尝试了这一点,它的工作@我要是早点发现就好了。违约率的差异是惊人的。您不会认为简单地更改编解码器标志会导致与预期相反的结果。我可以通过提高比特率来利用h265看到相同的输出大小是合理的,但是如果你不密切关注,这会让你非常恼火。大家好,我正在尝试同样的事情(除了Swift),奇怪的是,当使用h.264时,我可以得到一个特定的视频文件(1分钟)降低到10MB,而使用hevc时,无论比特率有多低,它都不会低于19MB。对于h.264,它将下降到6MB,之后比特率不再降低文件大小。在hevc/h.265中,这种情况发生得非常早。有办法吗?