问题
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