compressing a video in iOS
I have figured it out, thanks to this question (Swift version): IOS Video Compression Swift iOS 8 corrupt video file
I have the objective C version. Here is the method:
- (void)compressVideo:(NSURL*)inputURL
outputURL:(NSURL*)outputURL
handler:(void (^)(AVAssetExportSession*))completion {
AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:urlAsset presetName:AVAssetExportPresetMediumQuality];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
exportSession.shouldOptimizeForNetworkUse = YES;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
completion(exportSession);
}];
}
And calling the method:
NSURL* uploadURL = [NSURL fileURLWithPath:
[NSTemporaryDirectory() stringByAppendingPathComponent:@"temporaryPreview.mov"]];
[self compressVideo:self.movieURL outputURL:uploadURL handler:^(AVAssetExportSession *completion) {
if (completion.status == AVAssetExportSessionStatusCompleted) {
NSData *newDataForUpload = [NSData dataWithContentsOfURL:uploadURL];
NSLog(@"Size of new Video after compression is (bytes):%d",[newDataForUpload length]);
}
}];
This reduced the file size of my videos from 32 MB to 1.5 MB.
How to compress a video in swift?
I have looked at your code. Actually, you are compressing video in medium quality which will be around the same as the original video which you have. So, you have to change presetName
in export session initialization as follow:
exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetLowQuality)
You can pass AVAssetExportPresetMediumQuality
, So it's could be compressed as you expect.
There is the following list of format available to compress video.
1. Available from iOS 11.0
- AVAssetExportPresetHEVCHighestQuality
- AVAssetExportPresetHEVC1920x1080
- AVAssetExportPresetHEVC3840x2160
2. Available from iOS 4.0
- AVAssetExportPresetLowQuality
- AVAssetExportPresetMediumQuality
- AVAssetExportPresetHighestQuality
- AVAssetExportPreset640x480
- AVAssetExportPreset960x540
- AVAssetExportPreset1280x720
- AVAssetExportPreset1920x1080
- AVAssetExportPreset3840x2160
- AVAssetExportPresetAppleM4A
You can use above all format to compress your video based on your requirements.
I hope this will help you.
Swift - Compressing video files
This extension focuses on exporting it to a lower quality setting (in this case Medium) and uses an mp4
container, over the mov
container favored by iOS. This can result in a loss of quality, but you can experiment with higher output settings and different formats as you work to fine tune your output.
extension PreviewVideoViewController: AVCaptureFileOutputRecordingDelegate {
func fileOutput(_ output: AVCaptureFileOutput,
didFinishRecordingTo outputFileURL: URL,
from connections: [AVCaptureConnection],
error: Error?) {
guard let data = try? Data(contentsOf: outputFileURL) else {
return
}
print("File size before compression: \(Double(data.count / 1048576)) mb")
let compressedURL = NSURL.fileURL(withPath: NSTemporaryDirectory() + UUID().uuidString + ".mp4")
compressVideo(inputURL: outputFileURL as URL,
outputURL: compressedURL) { exportSession in
guard let session = exportSession else {
return
}
switch session.status {
case .unknown:
break
case .waiting:
break
case .exporting:
break
case .completed:
guard let compressedData = try? Data(contentsOf: compressedURL) else {
return
}
print("File size after compression: \(Double(compressedData.count / 1048576)) mb")
case .failed:
break
case .cancelled:
break
}
}
}
func compressVideo(inputURL: URL,
outputURL: URL,
handler:@escaping (_ exportSession: AVAssetExportSession?) -> Void) {
let urlAsset = AVURLAsset(url: inputURL, options: nil)
guard let exportSession = AVAssetExportSession(asset: urlAsset,
presetName: AVAssetExportPresetMediumQuality) else {
handler(nil)
return
}
exportSession.outputURL = outputURL
exportSession.outputFileType = .mp4
exportSession.exportAsynchronously {
handler(exportSession)
}
}
}
IOS Video Compression Swift iOS 8 corrupt video file
This answer has been completely rewritten and annotated to support Swift 4.0. Keep in mind that changing the AVFileType
and presetName
values allows you to tweak the final output in terms of size and quality.
import AVFoundation
extension ViewController: AVCaptureFileOutputRecordingDelegate {
// Delegate function has been updated
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
// This code just exists for getting the before size. You can remove it from production code
do {
let data = try Data(contentsOf: outputFileURL)
print("File size before compression: \(Double(data.count / 1048576)) mb")
} catch {
print("Error: \(error)")
}
// This line creates a generic filename based on UUID, but you may want to use your own
// The extension must match with the AVFileType enum
let path = NSTemporaryDirectory() + UUID().uuidString + ".m4v"
let outputURL = URL.init(fileURLWithPath: path)
let urlAsset = AVURLAsset(url: outputURL)
// You can change the presetName value to obtain different results
if let exportSession = AVAssetExportSession(asset: urlAsset,
presetName: AVAssetExportPresetMediumQuality) {
exportSession.outputURL = outputURL
// Changing the AVFileType enum gives you different options with
// varying size and quality. Just ensure that the file extension
// aligns with your choice
exportSession.outputFileType = AVFileType.mov
exportSession.exportAsynchronously {
switch exportSession.status {
case .unknown: break
case .waiting: break
case .exporting: break
case .completed:
// This code only exists to provide the file size after compression. Should remove this from production code
do {
let data = try Data(contentsOf: outputFileURL)
print("File size after compression: \(Double(data.count / 1048576)) mb")
} catch {
print("Error: \(error)")
}
case .failed: break
case .cancelled: break
}
}
}
}
}
Below is the original answer as written for Swift 3.0:
extension ViewController: AVCaptureFileOutputRecordingDelegate {
func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
guard let data = NSData(contentsOf: outputFileURL as URL) else {
return
}
print("File size before compression: \(Double(data.length / 1048576)) mb")
let compressedURL = NSURL.fileURL(withPath: NSTemporaryDirectory() + NSUUID().uuidString + ".m4v")
compressVideo(inputURL: outputFileURL as URL, outputURL: compressedURL) { (exportSession) in
guard let session = exportSession else {
return
}
switch session.status {
case .unknown:
break
case .waiting:
break
case .exporting:
break
case .completed:
guard let compressedData = NSData(contentsOf: compressedURL) else {
return
}
print("File size after compression: \(Double(compressedData.length / 1048576)) mb")
case .failed:
break
case .cancelled:
break
}
}
}
func compressVideo(inputURL: URL, outputURL: URL, handler:@escaping (_ exportSession: AVAssetExportSession?)-> Void) {
let urlAsset = AVURLAsset(url: inputURL, options: nil)
guard let exportSession = AVAssetExportSession(asset: urlAsset, presetName: AVAssetExportPresetMediumQuality) else {
handler(nil)
return
}
exportSession.outputURL = outputURL
exportSession.outputFileType = AVFileTypeQuickTimeMovie
exportSession.shouldOptimizeForNetworkUse = true
exportSession.exportAsynchronously { () -> Void in
handler(exportSession)
}
}
}
iOS File input for videos, video compressing terminates when screen not active anymore
It is not possible to continue an action in the background when the browser is not active. The only way to do this would be to use a native app instead of a web app. The documentation for the File API on mobile devices states https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications is going to be "further limited" on mobile devices.
The only way to continue an action in the background when the browser is not active would be to use a native app instead of a web app.
UIImagePickerController not compressing a video
It seems that the issue is within the simulator. I ran the app on my iPhone and it chooses and compresses the video without any problem.
Related Topics
Reading Long Characteristic Values Using Corebluetooth
Editing Screenshots in Itunes Connect After iOS App Was Approved
How to Rotate an Uiimageview by 20 Degrees
Nsurlsession "Http Load Failed Kcfstreamerrordomainssl, -9813 ; Self Signing Certificate
How to Define the Size of a Collectionview on Rotate
Does Firebase Cloud Messaging Support Voip Pushkit Services
Objc_Sync_Enter/Objc_Sync_Exit Not Working with Dispatch_Queue_Priority_Low
Show Uipickerview Text Field Is Selected, Then Hide After Selected
Uiwebview Random Crash at [Uiviewanimationstate Release]: Message Sent to Deallocated Instance
How to Use Avsamplebufferdisplaylayer in iOS 8 for Rtp H264 Streams with Gstreamer
Get Selected Index of Uitableview
"Interfaceorientation" Is Deprecated in iOS 8, How to Change This Method Objective C
Still Not Optimized for iPhone 6 and iPhone 6 Plus
Corelocation Heading Base on Back Camera (Augmented Reality)
Can't Find Pods.Modulemap - Looking in Wrong Directory
When Will Applicationwillterminate Be Called
How to Find the Purple Port for the Front Most Application in iOS 5 and Above
Ios5 What Does "Discarding Message for Event 0 Because of Too Many Unprocessed Messages" Mean