iPhone 12 mini runs out of memory when compressing 4k video
Samigos opened this issue · 5 comments
I've been using this library, which is great btw, on my app and I noticed that whenever I try to compress an 1-minute, 4k video, it crashes due to running out of memory. I've discovered that it starts compressing, it reaches 60-70% and then it crashes.
Here's my implementation:
class MediaToolVideoCompressionService: VideoCompressor {
private var task: CompressionTask?
func compressVideo(url: URL,
outputURL: @escaping (URL?) -> Void) {
task = nil
Task {
let outputTempURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("tempMovieVideo\(Date().timeIntervalSince1970)").appendingPathExtension("mp4")
task = await VideoTool.convert(
source: url,
destination: outputTempURL,
fileType: .mp4,
videoSettings: .init(
codec: .h264,
bitrate: .value(3 * 1_000_000),
size: .init(width: 1280, height: 720)
),
optimizeForNetworkUse: true,
skipSourceMetadata: false,
customMetadata: [],
copyExtendedFileMetadata: true,
overwrite: false,
deleteSourceFile: false,
callback: { state in
switch state {
case .started:
print("\(Date()) MediaToolVideoCompressionService Started")
case .progress(let progress):
print("Progress MediaToolVideoCompressionService: \(progress.fractionCompleted)")
case .completed(let info):
outputURL(info.url)
print("\(Date()) Done MediaToolVideoCompressionService: \(info.url.path)")
case .failed(let error):
print("\(Date()) Error MediaToolVideoCompressionService: \(error.localizedDescription)")
outputURL(url)
case .cancelled:
outputTempURL.deleteFile()
outputURL(nil)
print("\(Date()) Cancelled MediaToolVideoCompressionService")
}
})
}
}
func cancel() {
task?.cancel()
}
}
Am I doing anything wrong?
I compressed 4K video (80 seconds long) to your specs without an issue on iPhone X.
@Samigos, do you have enough storage on the device?
I compressed 4K video (80 seconds long) to your specs without an issue on iPhone X.
@Samigos, do you have enough storage on the device?
I have about 10 GBs free. How much storage does the processing need?
As I try different things, I realize that the issue is that as the processing happens, I also play the 4k video on screen, which ramps up the memory usage! The thing is, I can't have the user stare at a loading screen for 30"... they need to watch the video they selected, and have that video get compressed at the same time.
I know it turns out it's not an issue with the library, but I would appreciate any help!
@Samigos, you could try the Metal framework for the video player. And there is probably no need to display a full resolution on the mobile phone.
I also suggest you to try the Xcode Instruments to trace the memory leaks.
Additionally there is an option to access a video frames during the compression via Frame Processors, which can be used for displaying current sample/pixel buffer on the screen.
Finally VideoToolBox (used under the hood in library) process frames one-by-one without storing a big chunks in memory, so displaying the video or maintain the app UI should not be a problem.