问题
So, at the moment I am using this to compress video:
func compressVideo(inputURL: NSURL, outputURL: NSURL, handler:(session: AVAssetExportSession)-> Void)
{
let urlAsset = AVURLAsset(URL: inputURL, options: nil)
let exportSession = AVAssetExportSession(asset: urlAsset, presetName: AVAssetExportPresetMediumQuality)
exportSession!.outputURL = outputURL
exportSession!.outputFileType = AVFileTypeQuickTimeMovie
exportSession!.shouldOptimizeForNetworkUse = true
exportSession!.exportAsynchronouslyWithCompletionHandler { () -> Void in
handler(session: exportSession!)
}
}
When I recorded a video in 2 seconds, the size was 4,3 MB and when I recorded a video in 6 seconds the file size was 9,3 MB.
Any tips to reduce the size?
回答1:
While these extensions both use the medium setting for compression, you can change it to low or high if you want to focus on quality or size.
I use these extensions based on Swift version:
For OP (Swift 2.2):
extension PreviewVideoViewController: AVCaptureFileOutputRecordingDelegate {
func captureOutput(captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAtURL outputFileURL: NSURL!, fromConnections connections: [AnyObject]!, error: NSError!) {
let data = NSData(contentsOfURL: outputFileURL)
print("File size before compression: \(Double(data!.length / 1048576)) mb")
let compressedURL = NSURL.fileURLWithPath(NSTemporaryDirectory() + NSUUID().UUIDString + ".m4v")
compressVideo(outputFileURL, outputURL: compressedURL) { (session) in
switch session.status {
case .Unknown:
break
case .Waiting:
break
case .Exporting:
break
case .Completed:
let data = NSData(contentsOfURL: compressedURL)
print("File size after compression: \(Double(data!.length / 1048576)) mb")
case .Failed:
break
case .Cancelled:
break
}
}
}
private func compressVideo(inputURL: NSURL, outputURL: NSURL, handler:(session: AVAssetExportSession)-> Void) {
let urlAsset = AVURLAsset(URL: inputURL, options: nil)
if let exportSession = AVAssetExportSession(asset: urlAsset, presetName: AVAssetExportPresetMediumQuality) {
exportSession.outputURL = outputURL
exportSession.outputFileType = AVFileTypeQuickTimeMovie
exportSession.shouldOptimizeForNetworkUse = true
exportSession.exportAsynchronouslyWithCompletionHandler { () -> Void in
handler(session: exportSession)
}
}
}
}
For someone who needs it in Swift 3.0:
extension PreviewVideoViewController: 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)
}
}
}
回答2:
func convertVideo(phAsset : PHAsset){
PHImageManager.default().requestAVAsset(forVideo: phAsset, options: PHVideoRequestOptions(), resultHandler: { (asset, audioMix, info) -> Void in
if let asset = asset as? AVURLAsset {
do {
let videoData = try Data.init(contentsOf: asset.url)
print(asset.url)
self.orginalVideo = asset.url
print("File size before compression: \(Double(videoData.count / 1048576)) mb")
let compressedURL = NSURL.fileURL(withPath: NSTemporaryDirectory() + NSUUID().uuidString + ".MP4")
print(compressedURL)
self.compressVideo(inputURL: asset.url , outputURL: compressedURL) { (exportSession) in
guard let session = exportSession else {
return
}
switch session.status {
case .unknown:
print("unknown")
break
case .waiting:
print("waiting")
break
case .exporting:
print("exporting")
break
case .completed:
do {
let compressedData = try Data.init(contentsOf: compressedURL)
self.compressVideo = compressedURL
print(compressedData)
print("File size AFTER compression: \(Double(compressedData.count / 1048576)) mb")
}
catch{
print(error)
}
case .failed:
print("failed")
break
case .cancelled:
print("cancelled")
break
}
}
} catch {
print(error)
//return
}
}
})
}
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 = AVFileType.mp4
exportSession.shouldOptimizeForNetworkUse = true
exportSession.exportAsynchronously { () -> Void in
handler(exportSession)
}
}
来源:https://stackoverflow.com/questions/40470637/swift-compressing-video-files