2

我在iOS應用程序上測試了導出方法,它工作正常。但是當我將它移到命令行項目中時,exportAsynchronouslyWithCompletionHandler方法不起作用。Mac OS命令行工具句柄用於重新編碼的異步導出視頻(編輯並正在工作)

我知道可能的原因是命令行工具無法處理異步,因爲它立即返回。該方法非常簡單。它只是取得視頻的地址,指定質量,並將視頻輸出到輸出路徑。這是我的代碼。

void exportVideo(NSString *source, NSString *quality, NSString *filePath) { 

NSString *preset = nil; 

if ([quality isEqualToString:@"high"]) { 
    preset = AVAssetExportPreset960x540; // 16:9 recommended resolution for iPhone 4 
} else if ([quality isEqualToString:@"middle"]) { 
    preset = AVAssetExportPresetAppleM4VWiFi; // 16:9 recommended resolution for iPhone 3GS 
} 

// Creat the asset from path 
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:source] options:nil];  
if (!asset) NSLog(@"There is no video in the asset"); 

//NSLog(@"Print all presets: %@", [AVAssetExportSession allExportPresets]); 
//NSLog(@"Print all presets compatible with the asset: %@", [AVAssetExportSession exportPresetsCompatibleWithAsset:asset]); 

NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:asset]; 
//NSLog(@"All available presets: %@", compatiblePresets); 

if ([compatiblePresets containsObject:preset]) { 
    // create export session 
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:preset]; 
    exportSession.outputURL = [NSURL fileURLWithPath:filePath]; // output path 
    if (preset == AVAssetExportPreset960x540) { 
     exportSession.outputFileType = AVFileTypeQuickTimeMovie; 
    } else if (preset == AVAssetExportPresetAppleM4VWiFi) { 
     exportSession.outputFileType = AVFileTypeAppleM4V; 
    } 

    dispatch_semaphore_t sema = dispatch_semaphore_create(0); // Add this line 

    // In command line tool, it doesn't execute this method 
    [exportSession exportAsynchronouslyWithCompletionHandler:^{ 
     if (exportSession.status == AVAssetExportSessionStatusCompleted) { 
      NSLog(@"AVAssetExportSessionStatusCompleted"); 
     } else if (exportSession.status == AVAssetExportSessionStatusFailed) { 
      NSLog(@"AVAssetExportSessionStatusFailed"); 
      NSLog (@"FAIL %@", exportSession.error); 
     } else { 
      NSLog(@"Export Session Status: %ld", exportSession.status); 
     } 
     dispatch_semaphore_signal(sema); // Add this line 
    }]; 
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); // Add this line 
    dispatch_release(sema); // Add this line 
} else { 
    NSLog(@"Requested quality is not available."); 
} 

}

int main(int argc, const char * argv[]) 
{ 

@autoreleasepool { 

    NSLog(@"Input the source file path:"); 
    char str[100]; 
    scanf("%s", str); 
    NSString *inputSource = [NSString stringWithUTF8String:str]; 
    NSLog(@"Print the input source: %@", inputSource); 

    NSLog(@"Input the output video quality:"); 
    scanf("%s", str); 
    NSString *quality = [NSString stringWithUTF8String:str]; 
    NSLog(@"Print the quality: %@", quality); 

    NSLog(@"Input the output file path:"); 
    scanf("%s", str); 
    NSString *outputPath = [NSString stringWithUTF8String:str]; 
    NSLog(@"Print the output path: %@", outputPath); 

    exportVideo(inputSource, quality, outputPath); 
} 
return 0; 
} 

** dispatch_semaphore_t的使用適用於我的情況。我從一個來自stackoverflow的答案中得到了這個想法。感謝大家的幫助,我分享了所有的代碼。

回答

2

這是正確的,你需要阻止你的主函數返回,直到異步方法完成。最簡單的方法是用等待標誌。要麼有一個靜態布爾值,要麼傳遞一個布爾指針到你的導出視頻函數。然後,當布爾值爲假時,休眠你的主要功能。儘管這是一個可怕的做法,並且只與這種小局面有關,因爲主要只做這一件事。一般不要這樣做。

+0

謝謝!我現在就試試! – 2012-07-09 07:15:11

+0

你能提供一些關於在哪裏以及如何睡眠線程的更多指導?謝謝! – 2012-07-09 07:29:00

+0

使用c函數'sleep()' – borrrden 2012-07-09 07:56:00