2012-05-23 14 views
16

AVAssetExportSessionに問題がありますが、進行状況が上がるのをやめてもステータスはまだエクスポート中であると表示されます。これは実際には非常にまれな出来事ですが、99.99%の時間で完璧に動作しますが、とにかく問題を解決したいのです。AVAssetExportSessionが進行を停止します

だから私は、エクスポートを開始します。

exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetMediumQuality]; 
    exportSession.videoComposition = videoComposition; 
    exportSession.outputFileType = @"com.apple.quicktime-movie"; 
    exportSession.outputURL = outputURL; 
    [exportSession exportAsynchronouslyWithCompletionHandler:^{ 
     ... 
    }]; 

その後の進捗状況をチェックするタイマーがあります。

AVAssetExportSessionStatus status = [exportSession status]; 
    float progress = 0; 
    if (status == AVAssetExportSessionStatusExporting) { 
     progress = [exportSession progress]; 
    } else if (status == AVAssetExportSessionStatusCompleted) { 
     progress = 1; 
    } 
    NSLog(@"%d %f", status, progress); 
    [delegate processor:self didProgress:progress]; 

を、出力がのように見える終わる:

2012-05-23 14:28:59.494 **********[1899:707] 2 0.125991 
2012-05-23 14:28:59.994 **********[1899:707] 2 0.185280 
2012-05-23 14:29:00.494 **********[1899:707] 2 0.259393 
2012-05-23 14:29:00.994 **********[1899:707] 2 0.326093 
2012-05-23 14:29:01.494 **********[1899:707] 2 0.400206 
2012-05-23 14:29:01.995 **********[1899:707] 2 0.481729 
2012-05-23 14:29:02.495 **********[1899:707] 2 0.541019 
2012-05-23 14:29:02.997 **********[1899:707] 2 0.622542 
2012-05-23 14:29:03.493 **********[1899:707] 2 0.681832 
2012-05-23 14:29:03.995 **********[1899:707] 2 0.763355 
2012-05-23 14:29:04.494 **********[1899:707] 2 0.822645 
2012-05-23 14:29:04.994 **********[1899:707] 2 0.880082 
2012-05-23 14:29:05.493 **********[1899:707] 2 0.880082 
2012-05-23 14:29:05.994 **********[1899:707] 2 0.880082 
... 
2012-05-23 14:43:22.994 **********[1899:707] 2 0.880082 
2012-05-23 14:43:23.493 **********[1899:707] 2 0.880082 
2012-05-23 14:43:23.994 **********[1899:707] 2 0.880082 
2012-05-23 14:43:24.494 **********[1899:707] 2 0.880082 

(注:毎回同じパーセンテージで停止するわけではありません)。

タイムスタンプからわかるように、最初の88%を実行するのに5秒かかっていました。その後、別の13分(全ビデオ処理は通常10秒以上かかる)になります。進捗。

現在、私の唯一の選択肢は、進捗状況が最後のX秒間に変更されていないかどうかを確認し、失敗したことをユーザーに伝えて再試行することです。

誰もが考えている?

+0

エクスポートセッションに書き込もうとしているデータはどれですか? –

+0

ビデオを別のビデオの末尾に追加し、オーディオの一部をオーディオファイルの別の部分に置き換えます。ビデオコンポジションを使用して、開始時間にビデオの優先トランスフォームを設定します。 –

+0

同じ問題もあります。これについての進歩? –

答えて

3

私はそれを発見しました!

あなたは正しいlayerInstructions設定する必要があります。そうでなければ、それだけで立ち往生

AVMutableCompositionTrack *track = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 


AVMutableVideoCompositionLayerInstruction * layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:track]; 


AVMutableVideoCompositionInstruction * MainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
MainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, allTime); 
MainInstruction.layerInstructions = [NSArray arrayWithObject:layerInstruction]; 

を。

+0

これはまさに私のためのものです。私の輸出は0.005(基本的には何もない)に止まっていて、コールバックは決して発射されませんでした。ありがとう! –

2

タイマーとエクスポータが別のスレッドで終了すると、それがスレッド化の問題かどうか疑問に思っています。 (AVFoundationガイドには、輸出業者が特定のスレッドで動作することが保証されていないと記載されています)

タイマーの代わりにキー値観測を試しましたか?

ベアボーン例:あなたのプロセッサで次に

// register for the notification 
[exportSession addObserver:someProcessor forKeyPath:@"progress" options:NSKeyValueObservingOptionNew context:NULL]; 

:私の場合は

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    // add some checks here 
    NSNumber *processNumber = [change objectForKey:NSKeyValueChangeNewKey]; 
    float process = [processNumber floatValue]; 
    [delegate processor:self didProgress:progress]; 
} 
+2

この方法は、「進捗状況」プロパティがキー値ではないことがドキュメントに記載されているため、使用しないでください。 – aumanets

+0

@aumanetsあなたは他の方法を見つけましたか? –

+0

@PayalManiyar、それはずっと前に申し訳ありませんでした。私はこの問題をどのように売ったのか本当に覚えていません。 – aumanets

4

この問題は珍しい設定でエンコードされたMP4S茎から。しかし、最終的にはAppleのコードのバグが原因です。

特に私はFacebookでmp4を使っていました。フェイスブックで動画をエンコードすると、ビデオトラックの最初のフレームがドロップまたはシフトされるようです。 ffprobeとビデオを調べることが示された:

 "r_frame_rate": "722/25", 
     "avg_frame_rate": "722/25", 
     "time_base": "1/28880", 
     "start_pts": 1000, 
     "start_time": "0.034626", 

0.034626

が正確にフレーム2のオーディオトラックのための時間である、しかし、0で開始

残念ながら、AppleのAPIが正しくため、この開始時間を報告しません。トラック。 AVAssetTrackをAVAssetから取得し、timeRangeをチェックした後、開始時刻は0と報告されました。トラックとアセットタイミングの性質を誤解している可能性がありますが、これはバグのようです。

もちろん、エクスポートセッションのビデオコンポジションを構築するときは、間違ったトラック時間範囲を使用しました。私は、エクスポートセッションが時刻0のトラック内のデータを探して、混乱していないことを見つけたとき、見たように、ハングしてエラーを報告することさえしない - 別のバグだと思う。 videoCompositionWithPropertiesOfAssetを使用してコンポジションを作成することは役に立ちません。

私はAVAssetReaderとAVAssetWriterの代わりにAVAssetExportSessionを使用しようとはしていないので、同じ状況に遭遇するかどうかはわかりません。

CMTimeRange videoTimeRange = videoTrack.timeRange; 
videoTimeRange.start = CMTimeMake(1, ceil(videoTrack.nominalFrameRate)); 

は1つのまたは2のフレームに開始するトラックの挿入とビデオ手順については、使用する時間帯をリセットします。私は解決策として、このハックを作ってみたことを探索するためのより多くの時間を持つまで

明らかに、このハックは、ビデオトラックの開始時刻が0でない特定の状況にのみ適用されます。私は、このバグは、AVAssetExportSessionとその関連クラスが期待していない異常なメディアエンコーディングから発生すると考えています。

+0

あなたはこれに対してもっと良い解決策を見つけましたか?私はこれをやろうとしましたが、出発地をどこで変更するのかはわかりません。アセットをトラックに追加するとき、私は '[track insertTimeRange:CMTimeRangeMake(kCMTimeZero、asset.duration)... asset ..] 'あなたのCMTimeRangeメソッドを使用しようとすると、動作しません。実際には、それは後で何らかの理由でトラックのnaturalSizeを取得できないため、悪化します。しかし、フレームを間違った場所に置いている可能性がありますか?とにかく、このエラーの適切な解決策はずっと良いでしょう。 – Sti

+0

これに関する私の作業は、より良い解決策を見つける前に中止されました。あなたのケースではこれが動作するという保証はなく、一般的にAVFoundationを扱う際には多くの落とし穴があります。しかし、上記の行を使用して、トラック挿入に使用する調整範囲を作成します。例: '[track insertTimeRange:adjustedVideoTimeRange ofTrack:videoTrack atTime:kCMTimeZero error:&error]' – kball

+0

私が書いたように、私は運が無かったのでそれを試みました。それはまだ起こっている。私が使用しているすべてのビデオファイルは、AVAssetWriterを使用してアプリケーション自体に作成されています。同じ問題が発生しているかどうかはわかりません。私は今、失敗したファイルの1つでffprobeを使用/実行しようとしていますが、使用方法はわかりません。 (osx/terminal上で) './ffprobe test.mp4'を実行しているとき、私はそのファイルに関するメタデータの一部しか見ません。ドキュメントは変だけど、あなたの結果を得るために使うはずのオプションはありますか? – Sti

関連する問題