Подтвердить что ты не робот

Список доступных выходных аудио-целей AVAudioSession

Мне нужно указать аудиовыходы, доступные для приложения iOS. Мой вопрос похож на этот: Как указать доступный маршрут вывода аудио на iOS

Я пробовал этот код:

NSError *setCategoryError = nil;
BOOL success = [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback
                                                      error: &setCategoryError];

NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];

…
NSLog(@"session.currentRoute.outputs count %d", [[[[AVAudioSession sharedInstance] currentRoute] outputs ] count]);
for (AVAudioSessionPortDescription *portDesc in [[[AVAudioSession sharedInstance] currentRoute] outputs ]) {
    NSLog(@"-----");
    NSLog(@"portDesc UID %@", portDesc.UID);
    NSLog(@"portDesc portName %@", portDesc.portName);
    NSLog(@"portDesc portType %@", portDesc.portType);
    NSLog(@"portDesc channels %@", portDesc.channels);
}

Однако я всегда вижу только один выходной порт (число равно 1), также, если у меня есть два (Airplay и встроенный динамик). Если я использую приложение "Музыка", я могу видеть оба порта и переключаться между ними. В моем приложении я вижу только тот, который я выбрал.

Есть что-то еще, что мне нужно сделать?

Спасибо

EDIT:

Я тоже пробовал этот код:

CFDictionaryRef asCFType = nil;
UInt32 dataSize = sizeof(asCFType);
AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &dataSize, &asCFType);
NSDictionary *audioRoutesDesc = (__bridge NSDictionary *)asCFType;
NSLog(@"audioRoutesDesc %@", audioRoutesDesc);

но словарь содержит только один выход. Кроме того, массив входных источников пуст (у меня есть iPhone 4s)

EDIT2:

У меня что-то работает с помощью MPVolumeView. Этот компонент имеет кнопку, позволяющую выбрать выходной аудиомаршрут, например, в приложении "Музыка".

Если вы хотите, вы можете скрыть ползунок (и иметь только кнопку), используя:

self.myMPVolumeView.showsVolumeSlider = NO;
4b9b3361

Ответ 1

Попробуйте что-то вроде этого, его больше, чем вам нужно, но вы можете его обмануть:

    + (NSString *) demonstrateInputSelection
{
    NSError* theError = nil;
    BOOL result = YES;
    NSMutableString *info = [[NSMutableString alloc] init];
    [info appendString: @"     Device Audio Input Hardware\n"];

    NSString *str = nil;
    if( iOSMajorVersion < 7 ){
        str = @"No input device information available";
        NSLog(@"%@",str);
        [info appendFormat:@"%@\n",str];

        return info;
    }

    AVAudioSession* myAudioSession = [AVAudioSession sharedInstance];

    result = [myAudioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&theError];
    if (!result)
    {
        NSLog(@"setCategory failed");
    }

    result = [myAudioSession setActive:YES error:&theError];
    if (!result)
    {
        NSLog(@"setActive failed");
    }

    // Get the set of available inputs. If there are no audio accessories attached, there will be
    // only one available input -- the built in microphone.
    NSArray* inputs = [myAudioSession availableInputs];
    str = [NSString stringWithFormat:@"\n--- Ports available on %@: %d ---", [UIDevice currentDevice].name , [inputs count]];
    NSLog(@"%@",str);
    [info appendFormat:@"%@\n",str];

    // Locate the Port corresponding to the built-in microphone.
    AVAudioSessionPortDescription* builtInMicPort = nil;
    AVAudioSessionDataSourceDescription* frontDataSource = nil;

    for (AVAudioSessionPortDescription* port in inputs)
    {
        // Print out a description of the data sources for the built-in microphone
        str = @"\n**********";
        NSLog(@"%@",str);
        [info appendFormat:@"%@\n",str];
        str = [NSString stringWithFormat:@"Port :\"%@\": UID:%@", port.portName, port.UID ];
        NSLog(@"%@",str);
        [info appendFormat:@"%@\n",str];
        if( [port.dataSources count] ){
            str = [NSString stringWithFormat:@"Port has %d data sources",(unsigned)[port.dataSources count] ];
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];
        }

        str = [NSString stringWithFormat:@">%@", port.dataSources];
        NSLog(@"%@",str);
   //     [info appendFormat:@"%@\n",str];

        if( [port.portType isEqualToString:AVAudioSessionPortLineIn] ){
            str = @"Line Input found";
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];
        }
        else if( [port.portType isEqualToString:AVAudioSessionPortUSBAudio] ){
            str = @"USB Audio found";
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];
        }
        else if ([port.portType isEqualToString:AVAudioSessionPortBuiltInMic]){
            builtInMicPort = port;
            str = @"Built-in Mic found";
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];
        }
        else if ([port.portType isEqualToString:AVAudioSessionPortHeadsetMic]){
            builtInMicPort = port;
            str = @"Headset Mic found";
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];
        }
        else{
            str = @"Other input source found";
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];
        }

        // loop over the built-in mic data sources and attempt to locate the front microphone
        for (AVAudioSessionDataSourceDescription* source in port.dataSources)
        {
            str = [NSString stringWithFormat:@"\nName:%@ (%d) \nPolar:%@ \nType:%@ \nPatterns:%@", source.dataSourceName, [source.dataSourceID intValue], source.selectedPolarPattern, port.portType, source.supportedPolarPatterns];
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];

            //           if ([source.orientation isEqual:AVAudioSessionOrientationFront])
            //           {
            //               frontDataSource = source;
            //               break;
            //           }
        } // end data source iteration

    }

    str = @"\n----  Current Selected Ports ----\n";
    NSLog(@"%@",str);
    [info appendFormat:@"%@",str];

    NSArray *currentInputs = myAudioSession.currentRoute.inputs;
//    str = [NSString stringWithFormat:@"\n%d current input ports", [currentInputs count]];
//    NSLog(@"%@",str);
//    [info appendFormat:@"%@\n",str];
    for( AVAudioSessionPortDescription *port in currentInputs ){
        str = [NSString stringWithFormat:@"\nInput Port :\"%@\":", port.portName ];
        NSLog(@"%@",str);
        [info appendFormat:@"%@\n",str];
        if( [port.dataSources count] ){
            str = [NSString stringWithFormat:@"Port has %d data sources",(unsigned)[port.dataSources count] ];
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];

            str = [NSString stringWithFormat:@"Selected data source:%@",  port.selectedDataSource.dataSourceName];
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];

            if( [port.selectedDataSource.supportedPolarPatterns count] > 0 ){
                str = [NSString stringWithFormat:@"Selected polar pattern:%@", port.selectedDataSource.selectedPolarPattern];
                NSLog(@"%@",str);
                [info appendFormat:@"%@\n",str];
            }
        }
    }

    NSArray *currentOutputs = myAudioSession.currentRoute.outputs;
//    str = [NSString stringWithFormat:@"\n%d current output ports", [currentOutputs count]];
//    NSLog(@"%@",str);
//    [info appendFormat:@"%@\n",str];
    for( AVAudioSessionPortDescription *port in currentOutputs ){
        str = [NSString stringWithFormat:@"\nOutput Port :\"%@\":", port.portName ];
        NSLog(@"%@",str);
        [info appendFormat:@"%@\n",str];
        if( [port.dataSources count] ){
            str = [NSString stringWithFormat:@"Port has %d data sources",(unsigned)[port.dataSources count] ];
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];

            str = [NSString stringWithFormat:@"Selected data source:%@",  port.selectedDataSource.dataSourceName];
            NSLog(@"%@",str);
            [info appendFormat:@"%@\n",str];
        }

    }

//    str = [NSString stringWithFormat:@"\Current Route: %@ Source:%@\n", myAudioSession.currentRoute.portName, myAudioSession.preferredInput.selectedDataSource.dataSourceName];
//    NSLog(@"%@",str);
//    [info appendFormat:@"%@\n",str];


    if( myAudioSession.preferredInput.portName ){
        str = [NSString stringWithFormat:@"\nPreferred Port: %@ Source:%@\n", myAudioSession.preferredInput.portName, myAudioSession.preferredInput.selectedDataSource.dataSourceName];
    } else {
        str = @"\nNo Preferred Port set";
    }
    NSLog(@"%@",str);
    [info appendFormat:@"%@\n",str];

    return info;

    if (frontDataSource)
    {
        NSLog(@"Currently selected source is \"%@\" for port \"%@\"", builtInMicPort.selectedDataSource.dataSourceName, builtInMicPort.portName);
        NSLog(@"Attempting to select source \"%@\" on port \"%@\"", frontDataSource, builtInMicPort.portName);

        // Set a preference for the front data source.
        theError = nil;
        result = [builtInMicPort setPreferredDataSource:frontDataSource error:&theError];
        if (!result)
        {
            // an error occurred. Handle it!
            NSLog(@"setPreferredDataSource failed");
        }
    }

    // Make sure the built-in mic is selected for input. This will be a no-op if the built-in mic is
    // already the current input Port.
    theError = nil;
    result = [myAudioSession setPreferredInput:builtInMicPort error:&theError];
    if (!result)
    {
        // an error occurred. Handle it!
        NSLog(@"setPreferredInput failed");
    }

    return info;
}

Ответ 2

AVAudioSessionRouteDescription *currentRoute = [[AVAudioSession sharedInstance] currentRoute];
    for (AVAudioSessionPortDescription *output in currentRoute.outputs) {

    }

Ответ 3

Это будет зависеть от вашей категории AVAudioSession.

Вы можете спокойно предположить на iPhone, что у вас есть как минимум микрофон в качестве входного сигнала, а динамик - как выход. Если вы пытаетесь получить список выходов Bluetooth/AirPlay, сначала вам нужно убедиться, что ваша категория сеансов сообщает о них вам:

do 
{
    try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: .AllowBluetooth)
    try audioSession.setActive(true)
} 
catch let e
{
    debugPrint("failed to initialize audio session: \(e)")
}

Тогда неинтуитивный способ получения выходных данных - это проверить AVAudioSession.availableInputs, как правило, у устройства Bluetooth HFP будет тоже микрофон. Возможно, я сейчас очень много думаю, но это единственный способ последовательно получить ваши доступные вызовы.

Лучше всего использовать категорию MultipleRoute, которая даст вам больше свободы при доступе к AVAudioSessionPort