2014-03-03 53 views
1

我從ALASSET獲得了視頻URL,然後convertVideoToLowQuailtyWithInputURL函數來壓縮視頻,但它不能工作。我壓縮後看到,視頻的大小始終爲0無法在iOS中壓縮來自ALASSET URL的視頻?

這是函數從ALASSET獲得視頻網址:

ALAsset *alasset = [allVideos objectAtIndex:i]; 
      ALAssetRepresentation *rep = [alasset defaultRepresentation]; 
      NSString * videoName = [rep filename]; 

      //compress video data before uploading 
      NSURL *videoURL = [rep url]; 
      NSLog(@"videoURL is %@",videoURL); 


      NSURL *uploadURL = [NSURL fileURLWithPath:[[NSTemporaryDirectory() stringByAppendingPathComponent:videoName] stringByAppendingString:@".mov"]]; 
      NSLog(@"uploadURL temp is %@",uploadURL); 

      // Compress movie first 
      [self convertVideoToLowQuailtyWithInputURL:videoURL outputURL:uploadURL handler:^(AVAssetExportSession *session) 
      { 
       if (session.status == AVAssetExportSessionStatusCompleted) 
       { 
        // Success 
       } 
       else 
       { 
        // Error Handing 

       } 
      }]; 

      NSString *path = [uploadURL path]; 
      NSData *data = [[NSFileManager defaultManager] contentsAtPath:path]; 
      NSLog(@"size after compress video is %d",data.length); 
     } 

功能壓縮視頻:

- (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL 
            outputURL:(NSURL*)outputURL 
            handler:(void (^)(AVAssetExportSession*))handler 
{ 
    [[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil]; 
    AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:inputURL options:nil]; 
    AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset: urlAsset presetName:AVAssetExportPresetLowQuality]; 
    session.outputURL = outputURL; 
    session.outputFileType = AVFileTypeQuickTimeMovie; 
    [session exportAsynchronouslyWithCompletionHandler:^(void) 
    { 
     handler(session); 

    }]; 
} 

當我打電話convertVideoToLowQuailtyWithInputURL功能,我沒有看到它觸發到handler(session);

NSLog(@"size after compress video is %d",data.length);總是打印「尺寸爲0」。 我哪裏出錯了?請給我一些建議。提前致謝。

回答

2

convertVideoToLowQuailtyWithInputURL是一個異步方法,這就是爲什麼它需要一個完成處理程序塊。您當前的日誌記錄代碼不在完成處理程序塊中,但是在convertVideoToLowQuailtyWithInputURL的調用之後 - 這將在convertVideoToLowQuailtyWithInputURL完成之前運行,因此您將永遠不會得到結果。

將壓縮視頻的記錄(和使用)移動到完成塊中。

2
ALAssetRepresentation* representation = [asset defaultRepresentation]; 
NSString *fileName = [NSString stringWithFormat:@"VGA_%@",representation.filename]; //prepend with _VGA to avoid overwriting original. 
NSURL *TempLowerQualityFileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName] ]; 
NSURL *gallery_url = representation.url; 
NSLog(@" \r\n PRE-CONVERSION FILE %@ Size =%lld ; URL=%@\r\n",fileName, representation.size,representation.url); 
[self convertVideoToLowQuailtyWithInputURL:representation.url outputURL:TempLowerQualityFileURL handler:^(AVAssetExportSession *session) 
{ 
     if (session.status == AVAssetExportSessionStatusCompleted) 
     { 
      NSLog(@"\r\n CONVERSION SUCCESS \r\n"); 
      NSString *path = [TempLowerQualityFileURL path]; 
      NSData *data = [[NSFileManager defaultManager] contentsAtPath:path]; 
      NSLog(@" \r\n POST-CONVERSION TEMP FILE %@ Size =%d ; URL=%@\r\n",fileName, data.length, path); 

      ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init]; 
      [library writeVideoAtPathToSavedPhotosAlbum:TempLowerQualityFileURL completionBlock:^(NSURL *assetURL, NSError *error) 
      { 
       if (error) 
       { 
        NSLog(@"Error Saving low quality video to Camera Roll%@", error); 
       } 

       NSLog(@"\r\n temp low quality file exists before = %d", [self fileExistsAtPath:path]); 
       [[NSFileManager defaultManager] removeItemAtURL:TempLowerQualityFileURL error:nil]; 
       NSLog(@"\r\n temp low quality file exists after = %d", [self fileExistsAtPath:path]); 

       NSURL *NewAssetUrlInCameraRoll = assetURL; 
       [[VideoThumbManager sharedInstance] replaceLink:representation.url withNewLink:NewAssetUrlInCameraRoll]; 


       }];//end writeVideoAtPathToSavedPhotosAlbum completion block. 

     } 
     else 
     { 
      // Error Handing 
      NSLog(@"\r\n CONVERSION ERROR \r\n"); 

     } 
}];//end convert completion block 
0

SWIFT 3 MP4視頻壓縮

100%爲我工作

此代碼與URL壓縮視頻的12 MB(文檔目錄)至2 MB。 我用.mp4格式捕獲視頻,壓縮後的代碼以相同的格式返回視頻。

函數,其中壓縮舉行

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 // Don't change it to .mp4 format 
     exportSession.shouldOptimizeForNetworkUse = false 
     exportSession.exportAsynchronously {() -> Void in 
      handler(exportSession) 
     } 
    } 

爲目標網址代碼壓縮視頻

let filePath = URL(fileURLWithPath: strVideoPath) 
     var compressedURL : URL! 
     let fileManager = FileManager.default 
     do { 
      let documentDirectory = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:true) 
      compressedURL = documentDirectory.appendingPathComponent("Video.mp4") 
     } catch { 
      print(error) 
     } 
    //It is compulsory to remove previous item at same URL. Otherwise it is unable to save file at same URL.  
     do { 
      try fileManager.removeItem(at: compressedURL) 
      print("Removed") 
     } catch { 
      print(error) 
     } 

代碼爲呼叫

compressVideo(inputURL: filePath , outputURL: compressedURL) { (exportSession) in 
       guard let session = exportSession else { 
        return 
       } 

       switch session.status { 
       case .unknown: 
        break 
       case .waiting: 
        break 
       case .exporting: 
        break 
       case .completed: 
        print(compressedURL) 
        let newData : Data! 
        do { 
         newData = try Data(contentsOf: compressedURL) as Data? 
         print("File size after compression: \(Double((newData?.count)!/1048576)) mb") 
        } catch { 
         return 
        } 

       case .failed: 
        print(exportSession?.error.debugDescription) 
        break 
       case .cancelled: 
        break 
       } 
      }