Output Video Size Huge Using HEVC Encoder on iOS

大憨熊 提交于 2020-01-02 07:30:12

问题


I have a project that currently uses the H.264 encoder to record video on iOS. I wanted to try using the new HEVC encoder in iOS 11 to reduce file sizes, but have found that using the HEVC encoder causes file sizes to balloon enormously. Here's a project on GitHub that shows the issue - it simultaneously writes frames from the camera to files using the H.264 and H.265 (HEVC) encoders, and the resulting file sizes are printed to the console.

The AVFoundation classes are setup like this:

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)")
        }
    }
...

and then frames are written like this:

    func write(sampleBuffer buffer: CMSampleBuffer) {
        if avAssetWriter.status == AVAssetWriterStatus.unknown {
            avAssetWriter.startWriting()
            avAssetWriter.startSession(atSourceTime: CMSampleBufferGetPresentationTimeStamp(buffer))
         }
        if avAssetWriterInput.isReadyForMoreMediaData {
            avAssetWriterInput.append(buffer)
        }
    }

as they come in to the AVCaptureVideoDataOutputSampleBufferDelegate. At the qualities I'm recording (720p or 1080p) the file size of an HEVC-encoded video should be 40-60% of an identical H.264-encoded video, and I am seeing this when I use the default camera app on iOS, but when I use AVAssetWriter as above (or in the project linked above) I'm seeing file sizes be about three times larger with HEVC than with H.264. Either I am doing something wrong or the HEVC encoder is not working properly. Am I missing something or is there a workaround to get HEVC working through AVFoundation?


回答1:


Have you tried to specify the bitrate, etc.? As below:

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];
...

As far as I understand, with the same bitrate, the file size should be the same for H264 and HEVC, but the quality of the HEVC should be better.




回答2:


Use exportSession.fileLengthLimit = 1048576 * 10 //10 MB

10MB is hard coded number. Use according to your required bitrate.



来源:https://stackoverflow.com/questions/46778436/output-video-size-huge-using-hevc-encoder-on-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!