11

私は iOS アプリケーション (現時点では特に iPhone を対象としています) を開発しています。このアプリケーションは、iPhone の内蔵マイク (ヘッドフォン/ヘッドセットが接続されている場合でも) からのみオーディオを録音し、ヘッドフォンで再生する必要があります (ヘッドフォンが接続されていると仮定しましょう)。今のところ)。

利用可能な API で現在これが可能かどうか疑問に思っていますか? もしそうなら、どうすればこれを行うことができるのか、誰かに光を当てることができますか?

ありがとう!

4

6 に答える 6

8

この質問に対する答えは「いいえ」だと思います。私は iPhone 4 と iOS 4 の新機能 AVFoundation を使って実験し、AVCaptureDeviceクラスに焦点を当てました。

アプリケーションに次を追加しました。

NSLog(@"%@", [AVCaptureDevice devices]);

そのため、オーディオやビデオのキャプチャに使用できるすべてのデバイスをリストするよう求められます。ヘッドフォンが接続されていない場合、次のようになります。

(
    "Back Camera",
    "Front Camera",
    "iPhone Microphone" 
)

ヘッドフォンを接続すると、次のようになります。

(
    "Back Camera",
    "Front Camera",
    Headphones
)

したがって、iPhone のマイクは、ヘッドフォンが使用可能になるとすぐに、使用可能な AVCaptureDevices のリストから削除されます。これをさらに調査するために、利用可能なオーディオ デバイスの AVCaptureDevice インスタンスを取得し、その一意の ID を出力する簡単なコードを追加しました。「iPhone マイク」として自身を識別するデバイスと「ヘッドフォン」として自身を識別するデバイスの両方について、次のようになりました。

com.apple.avfoundation.avcapturedevice.built-in_audio:0

2 つのデバイスが同じ一意の ID を持つことができないことは明らかであるように思われるため、同じデバイスが状態を変更していることは明らかです。AVCaptureDevices には状態を設定するためのものがたくさんありますが、フォーカス、露出、フラッシュ、ホワイト バランスなどの視覚的なものに限定されます。

于 2011-02-14T17:00:26.840 に答える
3

Apple がオーディオ システムを 7.0 から再び変更したため、更新されたコードをここに投稿します。

#pragma mark Route change listener
// *********************************************************************************************************
// *********** Route change listener ***********************************************************************
// *********************************************************************************************************
-(void)routeChanged:(NSNotification*)notification {

    NSLog(@"]-----------------[ Audio Route Change ]--------------------[");

    AVAudioSession *session = [AVAudioSession sharedInstance];

    //AVAudioSessionRouteDescription* prevRoute = [[notification userInfo] objectForKey:AVAudioSessionRouteChangePreviousRouteKey];

    // Reason
    NSInteger reason = [[[notification userInfo] objectForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
    switch (reason) {
        case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory:
            NSLog(@"] Audio Route: The route changed because no suitable route is now available for the specified category.");
            break;
        case AVAudioSessionRouteChangeReasonWakeFromSleep:
            NSLog(@"] Audio Route: The route changed when the device woke up from sleep.");
            break;
        case AVAudioSessionRouteChangeReasonOverride:
            NSLog(@"] Audio Route: The output route was overridden by the app.");
            break;
        case AVAudioSessionRouteChangeReasonCategoryChange:
            NSLog(@"] Audio Route: The category of the session object changed.");
            break;
        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
            NSLog(@"] Audio Route: The previous audio output path is no longer available.");
            break;
        case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
            NSLog(@"] Audio Route: A preferred new audio output path is now available.");
            break;
        case AVAudioSessionRouteChangeReasonUnknown:
            NSLog(@"] Audio Route: The reason for the change is unknown.");
            break;
        default:
            NSLog(@"] Audio Route: The reason for the change is very unknown.");
            break;
    }

    // Output
    AVAudioSessionPortDescription *output = [[session.currentRoute.outputs count]?session.currentRoute.outputs:nil objectAtIndex:0];
    if ([output.portType isEqualToString:AVAudioSessionPortLineOut]) {
        NSLog(@"] Audio Route: Output Port: LineOut");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortHeadphones]) {
        NSLog(@"] Audio Route: Output Port: Headphones");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortBluetoothA2DP]) {
        NSLog(@"] Audio Route: Output Port: BluetoothA2DP");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortBuiltInReceiver]) {
        NSLog(@"] Audio Route: Output Port: BuiltInReceiver");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortBuiltInSpeaker]) {
        NSLog(@"] Audio Route: Output Port: BuiltInSpeaker");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortHDMI]) {
        NSLog(@"] Audio Route: Output Port: HDMI");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortAirPlay]) {
        NSLog(@"] Audio Route: Output Port: AirPlay");
    }
    else if ([output.portType isEqualToString:AVAudioSessionPortBluetoothLE]) {
        NSLog(@"] Audio Route: Output Port: BluetoothLE");
    }
    else {
        NSLog(@"] Audio Route: Output Port: Unknown: %@",output.portType);
    }

    // Input
    AVAudioSessionPortDescription *input = [[session.currentRoute.inputs count] ? session.currentRoute.inputs:nil objectAtIndex:0];

    if ([input.portType isEqualToString:AVAudioSessionPortLineIn]) {
        NSLog(@"] Audio Route: Input Port: LineIn");
    }
    else if ([input.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {
        NSLog(@"] Audio Route: Input Port: BuiltInMic");
    }
    else if ([input.portType isEqualToString:AVAudioSessionPortHeadsetMic]) {
        NSLog(@"] Audio Route: Input Port: HeadsetMic");
    }
    else if ([input.portType isEqualToString:AVAudioSessionPortBluetoothHFP]) {
        NSLog(@"] Audio Route: Input Port: BluetoothHFP");
    }
    else if ([input.portType isEqualToString:AVAudioSessionPortUSBAudio]) {
        NSLog(@"] Audio Route: Input Port: USBAudio");
    }
    else if ([input.portType isEqualToString:AVAudioSessionPortCarAudio]) {
        NSLog(@"] Audio Route: Input Port: CarAudio");
    }
    else {
        NSLog(@"] Audio Input Port: Unknown: %@",input.portType);
    }

    NSLog(@"]--------------------------[  ]-----------------------------[");

}

オーディオ セッションのデリゲートも非推奨になっているため、必ずオブザーバーを追加してください。

[[NSNotificationCenter defaultCenter] addObserver: self
                                                 selector: @selector(audioInterruption:)
                                                     name: AVAudioSessionInterruptionNotification
                                                   object: nil];

PS: ここでカテゴリをリセットする必要はありません (6.0 の場合と同様)。

于 2014-10-14T14:21:15.107 に答える
2

不可能です。ルートを変更したリスナー(AudioSessionを使用)で把握しようとしています。私の結果は次のとおりです。Apple が提供するカテゴリのため、入力または出力を個別に構成することはできません。*PlayAndRecord を試して、Bluetooth デバイスをペアリングすると、ルートが次のように変更されます。

old route : HeadsetBT
new route : SpeakerAndMicrophone

実際、私のブルートゥースはヘッドセットではなく、ただのスピーカーです...だから私には解決策がありません。

于 2012-08-28T17:36:53.833 に答える
1

これは、アプリケーションのオーディオ セッションを介して可能であると確信しています。

オーディオ セッションは、アプリケーションと iOS の間の仲介者です。各 iPhone アプリケーションには、オーディオ セッションが 1 つだけあります。アプリケーションのオーディオの意図を表現するように構成します。まず、アプリケーションの動作方法に関するいくつかの質問に答えます。

  • 電話などの割り込みにアプリケーションをどのように応答させたいですか?
  • アプリケーションのサウンドを他の実行中のアプリケーションのサウンドとミックスするつもりですか、それとも無音にするつもりですか?
  • たとえば、ユーザーがヘッドセットをプラグインまたはプラグから外した場合、アプリケーションはオーディオ ルートの変更にどのように応答する必要がありますか?

答えを手に入れたら、オーディオ セッション インターフェイス (AudioToolbox/AudioServices.h で宣言されている) を使用して、オーディオ セッションとアプリケーションを構成します。

これらのドキュメントを掘り下げてください:

そして、それがどうなるか教えてください!

于 2011-02-02T06:41:42.840 に答える