AVAssetExportSession的进度条

时间:2012-06-18 20:46:29

标签: iphone cocoa-touch uiprogressview avassetexportsession

我有一个应用程序将AVMutableComposition导出到.mov文件中,我希望用户能够以与您相同的方式查看导出状态如果你发了短信或上传了一个文件。

我知道如何在知道任务的持续时间(例如播放音频文件)时创建进度条,但由于导出没有设定的持续时间,我不确定如何继续。

我目前有一个活动指示器,但它没有提供最佳的用户体验。

有没有人有任何指示?

4 个答案:

答案 0 :(得分:34)

一段时间我想出了一个答案所以我会发布它,以防它可以帮助某人:

首先,在您拨打AVAssetExportSession的方法中,您必须设置一个计时器,以便在您启动导出后更新UIProgressView

//`AVAssetExportSession` code here
    self.exportProgressBarTimer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(updateExportDisplay) userInfo:nil repeats:YES];
...

然后,您需要一种方法来更新您的显示,同时考虑到AVAssetExportSession上的进度属性从0到1:

- (void)updateExportDisplay {
    self.exportProgressBar.progress = exportSession.progress;
    if (self.exportProgressBar.progress > .99) {
        [self.exportProgressBarTimer invalidate];
    }
}

答案 1 :(得分:2)

我在iOS 8.0中面临同样的问题,我使用dispatch quee

解决了这个问题
- (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL outputURL:(NSURL*)outputURL handler:(void (^)(AVAssetExportSession*))handler{

[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];

exportSession2 = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetLowQuality];
exportSession2.outputURL = outputURL;
exportSession2.outputFileType = AVFileTypeQuickTimeMovie;

[exportSession2 exportAsynchronouslyWithCompletionHandler:^(void)
 {
     handler(exportSession2);
 }];

 dispatch_async(dispatch_get_main_queue(), ^(void){

      self.exportProgressBarTimer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(updateExportDisplay) userInfo:nil repeats:YES];
 });

}

答案 2 :(得分:2)

快速3示例

使用通知中心将进度更新发送给侦听器

//`AVAssetExportSession` code above
var exportProgressBarTimer = Timer() // initialize timer
if #available(iOS 10.0, *) {
    exportProgressBarTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
    // Get Progress
    let progress = Float((exportSession?.progress)!);
    if (progress < 0.99) {
       let dict:[String: Float] = ["progress": progress]
       NotificationCenter.default.post(name: Notification.Name("ProgressBarPercentage"), object: nil, userInfo: dict)
    }
  }
}

// on exportSession completed
exportSession?.exportAsynchronously(completionHandler: {
   exportProgressBarTimer.invalidate(); // remove/invalidate timer
   if exportSession?.status == AVAssetExportSessionStatus.completed { 
      // [....Some Completion Code Here]
   }
})

然后在您想要使用

的任何位置设置通知中心监听器
NotificationCenter.default.addObserver(self, selector: #selector(self.statusUpdate(_:)), name: NSNotification.Name(rawValue: "ProgressBarPercentage"), object: nil)

答案 3 :(得分:0)

使用以下代码行。

AVAssetExportSession *session = [AVAssetExportSession exportSessionWithAsset:composition presetName:AVAssetExportPresetMediumQuality];
self.exportSession = session;

// 出力先(テンポラリファイル)の設定。
NSString *filePath = NSTemporaryDirectory();
filePath = [filePath stringByAppendingPathComponent:@"out.mov"];
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
session.outputURL = [NSURL fileURLWithPath:filePath];

// 出力タイプの設定。
session.outputFileType = AVFileTypeQuickTimeMovie;

// 非同期エクスポートの開始。
[session exportAsynchronouslyWithCompletionHandler:^{
    if (session.status == AVAssetExportSessionStatusCompleted) {
        // フォトアルバムへの書き込み。
        ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
        [library writeVideoAtPathToSavedPhotosAlbum:session.outputURL completionBlock:^(NSURL *assetURL, NSError *error){
            if (error) {
                self.resultLabel.text = [NSString stringWithFormat:@"アセット書き込み失敗\n%@", error];
            } else {
                self.resultLabel.text = [NSString stringWithFormat:@"完了\n%@", assetURL];
            }
        }];
        [library autorelease];
    } else if (session.status == AVAssetExportSessionStatusCancelled) {
        self.resultLabel.text = @"エクスポート中断";
    } else {
        self.resultLabel.text = [NSString stringWithFormat:@"エクスポート失敗\n%@", session.error];
    }
}];


dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    while (session.status == AVAssetExportSessionStatusExporting) {
        dispatch_sync(dispatch_get_main_queue(), ^{
            self.progressView.progress = session.progress;
        });
    }
});

参考链接:https://github.com/keijiro/iOS4BookSampleCode/blob/master/3.3.SimpleExport/Classes/SimpleExportViewController.m