14

aに a をcanAddOutput:追加できるかどうかを判断するために使用していますが、時々 NO を返し、ほとんどが YES を返していることがわかりました。NO が返された理由を調べる方法はありますか? または、NO が返される原因となっている状況を解消する方法はありますか? または、ユーザーが断続的な障害を見るのを防ぐためにできることはありますか?AVCaptureMovieFileOutputAVCaptureSessioncanAddOutput:

その他の注意事項: これは、30 回の呼び出しに約 1 回発生します。私のアプリは起動されていないため、1 つのデバイス (7.1.2 を実行している iPhone 5) でのみテストされています。

4

5 に答える 5

15

ここにドキュメントからの引用があります(の議論canAddOutput:

レシーバーの初期化に使用されたアセット以外のアセットのトラックから読み取る出力を追加することはできません。

説明が役立ちます(コードがこのガイドに一致しているかどうかを確認してください。問題がなければ、基本的canAddOuput:に互換性をチェックするため、エラーは発生しません)。

AVCaptureSession DShow
フィルターの接続と同様に、組織のデバイスの入力と出力の間の接続に使用されます。入力と出力が接続できれば、起動後、入力から出力にデータが読み込まれます。いくつかの要点:
a) AVCaptureDevice、機器の定義、両方のカメラ デバイス。
b) AVCaptureInput
c) AVCaptureOutput
入力と出力は 1 対 1 ではありません。たとえば、ビデオを出力しながらビデオ + オーディオを入力します。カメラの切り替え前と切り替え後:

AVCaptureSession * session = <# A capture session #>; 
[session beginConfiguration]; 
[session removeInput: frontFacingCameraDeviceInput]; 
[session addInput: backFacingCameraDeviceInput]; 
[session commitConfiguration];

キャプチャ INPUT の追加:
キャプチャ デバイスをキャプチャ セッションに追加するには、AVCaptureDeviceInput (抽象 AVCaptureInput クラスの具体的なサブクラス) のインスタンスを使用します。キャプチャ デバイス入力は、デバイスのポートを管理します。

NSError * error = nil; 
AVCaptureDeviceInput * input = 
[AVCaptureDeviceInput deviceInputWithDevice: device error: & error]; 
if (input) { 
   // Handle the error appropriately. 
}

出力、出力分類を追加します。

キャプチャ セッションから出力を取得するには、1 つ以上の出力を追加します。出力は、AVCaptureOutput の具体的なサブクラスのインスタンスです。
使用するもの:
AVCaptureMovieFileOutputムービー ファイルに出力する
AVCaptureVideoDataOutputキャプチャされたビデオからフレームを処理する場合
AVCaptureAudioDataOutputキャプチャされたオーディオ データを処理する場合
AVCaptureStillImageOutputメタデータを伴う静止画像をキャプチャする場合 出力をキャプチャに追加しますaddOutput: を使用したセッション。
を使用して、キャプチャ出力が既存のセッションと互換性があるかどうかを確認しcanAddOutput:ます。
セッションの実行中に、必要に応じて出力を追加および削除できます。

AVCaptureSession * captureSession = <# Get a capture session #>; 
AVCaptureMovieFileOutput * movieInput = <# Create and configure a movie output #>; 
if ([captureSession canAddOutput: movieInput]) { 
   [captureSession addOutput: movieInput]; 
} 
else {
   // Handle the failure. 
}

ビデオ ファイルを保存し、ビデオ ファイル出力を追加します

AVCaptureMovieFileOutput オブジェクトを使用して、ムービー データをファイルに保存します。(AVCaptureMovieFileOutput は AVCaptureFileOutput の具体的なサブクラスであり、基本的な動作の多くを定義します。) 録画の最大時間や最大ファイル サイズなど、ムービー ファイル出力のさまざまな側面を構成できます。また、ディスクの空き容量が所定の量より少ない場合は、録画を禁止することもできます。

AVCaptureMovieFileOutput * aMovieFileOutput = [[AVCaptureMovieFileOutput alloc] 
init]; 
CMTime maxDuration = <# Create a CMTime to represent the maximum duration #>; 
aMovieFileOutput.maxRecordedDuration = maxDuration; 
aMovieFileOutput.minFreeDiskSpaceLimit = <# An appropriate minimum given the quality 
of the movie format and the duration #>;

プレビュー ビデオ フレーム データの処理、各フレーム ビュー ファインダー データは、顔検出などの後続の高度な処理に使用できます。
AVCaptureVideoDataOutput オブジェクトは委任を使用してビデオ フレームを販売します。を使用してデリゲートを設定し
setSampleBufferDelegate: queue:ます。
デリゲートに加えて、デリゲート メソッドが呼び出されるシリアル キューを指定します。フレームが適切な順序でデリゲートに配信されるようにするには、シリアル キューを使用する必要があります。
によって返されたキューを渡すべきではありません。dispatch_get_current_queue現在のキューがどのスレッドで実行されているかについて保証がないためです。キューを使用して、ビデオ フレームの配信と処理に与えられる優先度を変更できます。フレームのデータ処理には、サイズ (画像サイズ) と処理時間の制限が必要です。処理時間が長すぎると、基盤となるセンサーがレイアウターとコールバックにデータを送信しません。

セッション出力は、アプリケーションの実用的な最低解像度に設定する必要があります。
出力を必要以上に高い解像度に設定すると、処理サイクルが無駄になり、電力が不必要に消費されます。フレームに割り当てられた時間内に、captureOutput: didOutputSampleBuffer: fromConnection: の実装がサンプル バッファを処理できることを確認する必要があります。時間がかかりすぎてビデオ フレームを保持している場合、AVFoundation はデリゲートだけでなく、プレビュー レイヤーなどの他の出力へのフレームの配信も停止します。

キャプチャ プロセスを処理します。

AVCaptureStillImageOutput * stillImageOutput = [[AVCaptureStillImageOutput alloc] 
init]; 
NSDictionary * outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, 
AVVideoCodecKey, nil]; 
[StillImageOutput setOutputSettings: outputSettings];

さまざまな形式をサポートできるため、jpg ストリームを直接生成することもできます。JPEG 画像をキャプチャする場合は、通常、独自の圧縮形式を指定しないでください。代わりに、静止画像出力に圧縮を行わせる必要があります。その圧縮はハードウェア アクセラレーションによるものです。画像のデータ表現が必要な場合は、jpegStillImageNSDataRepresentation: を使用して、画像のメタデータを変更しても、データを再圧縮せずに NSData オブジェクトを取得できます。

カメラのプレビュー表示:

AVCaptureVideoPreviewLayer オブジェクトを使用して、記録されている内容のプレビューをユーザーに提供できます。AVCaptureVideoPreviewLayer は CALayer のサブクラスです (Core Animation Programming Guide を参照してください。プレビューを表示するための出力は必要ありません。

AVCaptureSession * captureSession = <# Get a capture session #>; 
CALayer * viewLayer = <# Get a layer from the view in which you want to present the 
The preview #>; 
AVCaptureVideoPreviewLayer * captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer 
alloc] initWithSession: captureSession]; 
[viewLayer addSublayer: captureVideoPreviewLayer];

一般に、プレビュー レイヤーは、Render Tree 内の他の CALayer オブジェクトと同じように動作します (Core Animation Programming Guide を参照)。他のレイヤーと同じように、画像をスケーリングし、変換、回転などを実行できます。1 つの違いは、レイヤーの方向プロパティを設定して、カメラからの画像を回転させる方法を指定する必要がある場合があることです。さらに、iPhone 4 では、プレビュー レイヤーがミラーリングをサポートしています (これは、前面カメラをプレビューするときのデフォルトです)。

于 2014-07-10T11:40:01.757 に答える
2

この回答から参照すると、このデリゲート メソッドがバックグラウンドで実行されている可能性があるため、前のメソッドがAVCaptureSession適切に切断されないことcanAddOutput:NOあります。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection

解決策は、上記のデリゲートで使用することstopRunningです (もちろん、必要なアクションと条件チェックを行った後、以前のセッションを適切に終了する必要がありますよね?)。

それに加えて、あなたがやろうとしていることのコードを提供する方が良いでしょう。

于 2014-07-07T05:53:12.673 に答える
1

この 2 つのケースから 1 つを選択できます
1) セッションは実行中
です 2) 既に出力を追加してい
ます 2 つの出力または 2 つの入力を追加することはできず、2 つの異なるセッションを作成することもできません

于 2014-07-10T16:26:20.927 に答える
0

canAddOutput: セッションに特定の出力を追加できるかどうかを示すブール値を返します。

- (BOOL)canAddOutput:(AVCaptureOutput *)output

パラメータ output セッションに追加する出力。戻り値 セッションに出力を追加できる場合は YES、そうでない場合は NO。

提供状況 OS X v10.7 以降で利用可能。

ここにアップルドキュメントのリンクがあります ここをクリック

于 2014-07-10T11:05:33.440 に答える
0

次の組み合わせの可能性があります。

  • カメラがビジー状態のときにこのメソッドを呼び出します。
  • 以前に接続した を適切に削除していませんAVCaptureSession

canAddOutput:一度だけ追加して(常に になると思いますYES)、必要に応じてセッションを一時停止/再開する必要があります。

// Stop session if possible
if (_captureSession.running && !_captureInProgress)
{
    [_captureSession stopRunning];
    NBULogVerbose(@"Capture session: {\n%@} stopped running", _captureSession);
}

ここで見ることができます。

于 2014-07-07T02:17:16.780 に答える