私はビデオを再生するアプリケーションで作業しており、ビデオ内で前後にスクラブすることができます。スクラビングはスムーズに行わなければならないため、ビデオ圧縮プロパティーAVVideoMaxKeyFrameIntervalKey:@1
を使用してビデオをSDAVAssetExportSession
に書き換え、各フレームがキーフレームとなり、スムーズな逆スクラブが可能になります。これは素晴らしい作品で、滑らかな再生を提供します。アプリケーションはさまざまなソースからのビデオを使用し、アンドロイドまたはiOSデバイスに記録され、ウェブからダウンロードしてアプリケーションに追加することもできます。その結果、いくつかはすでにスクラビングに適しています(各フレームキーフレームです)。不必要なビデオ処理を避けるために、ビデオファイルのキーフレーム間隔を検出する方法はありますか?私はAVFoundationの文書の多くを読んできましたが、この情報を入手する明確な方法は見当たりません。これに関する助けをありがとう。AVAssetの現在のキーフレーム間隔を検出する
答えて
AVAssetReaderTrackOutput
をnil outputSettings
で作成して、イメージをデコードせずにファイルをすばやく解析できる場合は、あなたが遭遇するフレームサンプルバッファには、役に立つ情報を持つ辞書を含む添付ファイル配列があり、フレームが他のフレームに依存するかどうか、または他のフレームがそれに依存するかどうかが含まれます。私は前者をキーフレームを示すものとして解釈しますが、それは私にいくつかの低い数値を与えます(1つのファイルに4%のキーフレーム?)。とにかく、コード:
let asset = AVAsset(url: inputUrl)
let reader = try! AVAssetReader(asset: asset)
let videoTrack = asset.tracks(withMediaType: AVMediaTypeVideo)[0]
let trackReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: nil)
reader.add(trackReaderOutput)
reader.startReading()
var numFrames = 0
var keyFrames = 0
while true {
if let sampleBuffer = trackReaderOutput.copyNextSampleBuffer() {
// NB: not every sample buffer corresponds to a frame!
if CMSampleBufferGetNumSamples(sampleBuffer) > 0 {
numFrames += 1
if let attachmentArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, false) as? NSArray {
let attachment = attachmentArray[0] as! NSDictionary
// print("attach on frame \(frame): \(attachment)")
if let depends = attachment[kCMSampleAttachmentKey_DependsOnOthers] as? NSNumber {
if !depends.boolValue {
keyFrames += 1
}
}
}
}
} else {
break
}
}
print("\(keyFrames) on \(numFrames)")
N.B.これは、ローカルファイルアセットでのみ機能します。
p.s.あなたはスクラブや遊びの方法を言っていません。 AVPlayerViewController
とAVPlayer
?
ここでは、同じ回答のObjective Cバージョンです。これを実装して使用すると、すべてのキーフレームが必要なビデオは、このコードから約96%のキーフレームを返しています。なぜ私はそれがより正確であることを望んでいるにもかかわらず、私は決定要因としてその数を使用しています。私はこの決定をするために20分のビデオ全体を読む必要はないので、最初の600フレームまたはビデオの終わり(最初のどちらか早い方)を見ているだけです。
+ (BOOL)videoNeedsProcessingForSlomo:(NSURL*)fileUrl {
BOOL needsProcessing = YES;
AVAsset* anAsset = [AVAsset assetWithURL:fileUrl];
NSError *error;
AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:anAsset error:&error];
if (error) {
DLog(@"Error:%@", error.localizedDescription);
return YES;
}
AVAssetTrack *videoTrack = [[anAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVAssetReaderTrackOutput *trackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:videoTrack outputSettings:nil];
[assetReader addOutput:trackOutput];
[assetReader startReading];
float numFrames = 0;
float keyFrames = 0;
while (numFrames < 600) { // If the video is long - only parse through 20 seconds worth.
CMSampleBufferRef sampleBuffer = [trackOutput copyNextSampleBuffer];
if (sampleBuffer) {
// NB: not every sample buffer corresponds to a frame!
if (CMSampleBufferGetNumSamples(sampleBuffer) > 0) {
numFrames += 1;
NSArray *attachmentArray = ((NSArray*)CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, false));
if (attachmentArray) {
NSDictionary *attachment = attachmentArray[0];
NSNumber *depends = attachment[(__bridge NSNumber*)kCMSampleAttachmentKey_DependsOnOthers];
if (depends) {
if (depends.boolValue) {
keyFrames += 1;
}
}
}
}
}
else {
break;
}
}
needsProcessing = keyFrames/numFrames < 0.95f; // If more than 95% of the frames are keyframes - don't decompress.
return needsProcessing;
}
申し訳ありません - 私はあなたが目的のCを使用していたのか分からなかった、質問はタグ付けされていません –
私のための言語にはあまり関係はありませんでした。あなたのお手伝いをありがとう。私は似たようなものを持っていて、たくさんのドキュメンテーションを通して読んでいましたが、kCMSampleAttachmentKey_DependsOnOthersを使ってこれを判断することができるかどうかは分かりませんでした。 – johnrechd
- 1. キーフレームの間隔を確認していますか?
- 2. 時間間隔で現在の地理位置を送信
- 3. MySQLの現在の間隔はミリ秒で可能ですか?
- 4. 間隔をクリアすると現在動作しません
- 5. RxJSによるイベント間の長い間隔の検出
- 6. divの現在の方向を検出
- 7. Postgres:現在のトランザクションレベルを検出
- 8. Rzsliderを描く角度jsの現在の時間間隔に基づいて?
- 9. 現在実行中のブラウザの現在のWebアプリケーションを検出します。
- 10. 現在の@keyframes%/変更キーフレームの取得/設定
- 11. @とtextarea現在位置の間に出現する
- 12. 間隔検閲データのdinterval()?
- 13. JavaScriptで特定のCSS3キーフレームを検出する
- 14. セグメント間隔検索
- 15. 間隔データフレームからのサブ間隔の検索
- 16. オーバーラップ間隔での基本的な間隔の検索
- 17. ビューメソッド内の現在のURLを検出する方法
- 18. 現在のビューの外にあるタップを検出します
- 19. アンドロイドの現在の充電状態を検出する方法
- 20. 現在のオーディオデバイスのボリュームを検出する方法
- 21. 指示内の現在の状態を検出する方法
- 22. PHPで現在のIISのバージョンを検出するには?
- 23. jQueryで現在のページのメディアタイプを検出する方法
- 24. 現在のページのURLを検出する液体マークアップ?
- 25. 現在のキーボードの言語をPythonで検出する方法
- 26. UIPageViewControllerの現在のページを検出する
- 27. RxJavaより長い時間間隔の期間が現在の放射回数に依存する
- 28. 出力間隔エラー
- 29. 現在のフォアグラウンドアクティビティを検出してリロードする
- 30. 現在の入力言語を検出する
回答ありがとうございます。私は今日これを実装しました(目的はCです)。私はAVPlayerとAVPlayerLayerでカスタムUIViewを使用しています。これはかなり正確で、すべてのキーフレームを使用するようにエンコードしたビデオの約96%のキーフレームを返します。他の圧縮設定の動画の方がずっと少なくなりました。スクラバーは、スクロール速度をスクラブループに変換して一度に1つのフレームにステップするホイール(scrollView)です。 Qへの回答として私の方法を掲載するかもしれません。私はこれのObjective cバージョンも投稿します。 – johnrechd
クール!私はそれを見ることを楽しみにしています。それは欠けている4%について奇妙です。私はその説明が何であるか疑問に思います。 –