7

AVFoundation でビデオを再生しようとしています。再生を 1 フレーム進めるボタンに次のコードを使用しています。

断続的に動作し、一部の実行では正しいことを実行して 1 フレーム進みますが、ほとんどの場合、フレームを進める前にボタンを 3 回または 4 回押す必要があります。

これは、ある種の精度の問題だと思いますが、それが何であるかはわかりません。実行されるたびに、新しい CMTime は同じ量だけ進んでいるように見えます。

私の他の理論は、 currentTime がフレームレートで正確なフレーム境界に設定されていないことが原因である可能性があります(ビデオをシークすることが原因です)。しかし、自分のフレーム レートで最も近いフレームに「スナップ」する方法がわかりません。

AVAssetTrack *videoTrack = ...;
Float64 frameRate = [videoTrack nominalFrameRate];

CMTime currentTime = [self.playerItem currentTime];
CMTime oneFrame = CMTimeMakeWithSeconds(1.0 / frameRate, currentTime.timescale);
CMTime added = CMTimeAdd(currentTime, oneFrame);

[self.player seekToTime:added toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];

ご協力いただきありがとうございます!

4

2 に答える 2

5

あまり明白ではありませんが (不思議なことに、AVPlayer ではなく AVPlayerItem でのみ使用できるため)、AVPlayerItem が YES を返す場合は、特定のフレーム数だけ前後に移動するようにcanStepForward/canStepBackward呼び出すことができます。stepByCount:(NSInteger)stepCount:

于 2013-10-11T19:37:43.587 に答える
5

あなたの質問への答えは、コードの 2 行目にあり、nominalFrameRate から「公称」を削除します。

あなたのコードは、ビデオのフレーム レートが一定であることを前提としています。これは正しくありません。

ビデオは一定の fps を持つことができますが、そうである必要はありません。たとえば、さまざまな照明条件で携帯電話で映画を撮影すると、フレームの露出時間が変化し、フレーム レートが逆に変化します。

フレーム境界に「スナップ」するには、AVAssetReader を使用して個々のフレームをステップスルーする必要があります。各フレームにはプレゼンテーション タイム スタンプ (「t」) がタグ付けされていますが、位置マーカーを更新していない限り、ステップを実行している場合はそれほど重要ではありません。

于 2011-06-24T22:14:33.323 に答える