Je développe une application iOS (ciblée spécifiquement pour iPhone, pour le moment), qui nécessite l'application sur enregistrement audio uniquement du microphone interne iPhone forte> (même lorsque le casque / casque est branché), et La lecture au casque (supposé le casque est branchée pour l'instant). P>
Je me demande si cela est actuellement possible avec les API disponibles? Si tel est le cas, quelqu'un peut-il perdre une lumière sur la façon dont je vais faire cela? P>
merci! p>
6 Réponses :
Je suis plutôt confiant que cela est possible via la session audio de votre application: p>
une session audio
forte> est un intermédiaire entre votre application et iOS. Chaque L'application iPhone a exactement un Session audio. Vous le configurez à Exprimez votre audio de votre application intentions. Pour commencer, vous répondez à certains questions sur la façon dont vous voulez votre Application à se comporter: P>
- Comment voulez-vous que votre application soit répondre aux interruptions, telles qu'un appel téléphonique? LI>
- Avez-vous l'intention de mélanger votre les sons de l'application avec ceux de d'autres applications en cours d'exécution, ou vous l'intention de les taire? Li>
Comment devrait Votre application répondit à un audio changement de route, par exemple, lorsqu'un utilisateur branche ou débranche un casque? strong> li> ul> avec Réponses à la main, vous utilisez l'audio Interface de session (déclarée dans Audiooolbox / audioservices.h) à Configurez votre session audio et votre Application. P> blockQuote>
creuser sur ces documents: p>
- Aperçu audio de base - Sessions audio: Coopérateur avec Core Audio Li>
- Programmation de session audio li>
- Programmation audio de la session - Manipulation des modifications de l'itinéraire audio LI> ul>
et laissez-moi savoir comment ça se passe! p>
Au point de réponse. Je vais creuser profondément dans des points ci-dessus et vous laisser les gars savoir ce qui me travaille. Merci @defbyte
Je crois que la réponse à cette question est «non». J'ai utilisé un iPhone 4 et l'avexte neuf à iOS 4 pour expérimenter, concentrez-vous sur le avCapturevice classe.
J'ai ajouté ce qui suit à une application: p>
com.apple.avfoundation.avcapturedevice.built-in_audio:0
Ce n'est pas possible, j'essaie de comprendre avec la route changée auditeur (avec audiosession). Mon résultat est le suivant: vous ne pouvez pas configurer séparément d'entrée ou de sortie à cause de catégories fournies par Apple. J'essaye * Playandrecord, quand je jumite un périphérique Bluetooth, itinéraire change comme ceci: en fait, mon Bluetooth
même problème. Mon haut-parleur BT et mon casque BT montrent les deux HFP Bluetooth au lieu de Bluetooth A2DP pour le haut-parleur
On dirait que ce n'est vraiment pas possible.
Mon objectif est d'envoyer de la sortie aux casques Bluetooth et de l'enregistrement de l'enregistrement de celui-ci. Aussi loin que je puisse voir, mes meilleures options sont les suivantes: "Playandrecord + allowbluetootootoothinput" (iPhone 4, casque Nokia BH-214) P>
La chose importante est que, selon la documentation Apple, vous devez toujours reprogrammer votre catégorie audio lorsque l'itinéraire audio change! P>
Ceci Est ma méthode d'écoute de mon itinéraire, qui imprime: RobtechangerAsonsons, OptionsRoute, Audiorout EM>: P> void RouteChangeListener(void *inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void *inData) {
if (inID == kAudioSessionProperty_AudioRouteChange) {
NSLog(@"]-----------------[ Audio Route Change ]--------------------[");
// ************************************************************************************************
// Check route change reason **********************************************************************
// ************************************************************************************************
CFDictionaryRef routeDict = (CFDictionaryRef)inData;
NSNumber* reasonValue = (NSNumber*)CFDictionaryGetValue(routeDict, CFSTR(kAudioSession_AudioRouteChangeKey_Reason));
int reason = [reasonValue intValue];
if (reason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {
NSLog(@"] Logic: audio route change reason: OldDeviceUnavailable");
}else if (reason == kAudioSessionRouteChangeReason_NewDeviceAvailable ) {
NSLog(@"] Logic: audio route change reason: NewDeviceAvailable");
}else if (reason == kAudioSessionRouteChangeReason_Unknown ) {
NSLog(@"] Logic: audio route change reason: Unknown");
}else if (reason == kAudioSessionRouteChangeReason_CategoryChange ) {
NSLog(@"] Logic: audio route change reason: CategoryChange");
}else if (reason == kAudioSessionRouteChangeReason_Override ) {
NSLog(@"] Logic: audio route change reason: Override");
}else if (reason == kAudioSessionRouteChangeReason_WakeFromSleep ) {
NSLog(@"] Logic: audio route change reason: WakeFromSleep");
}else if (reason == kAudioSessionRouteChangeReason_NoSuitableRouteForCategory ) {
NSLog(@"] Logic: audio route chang reasone: NoSuitableRouteForCategory");
}
// ************************************************************************************************
// Check output type ******************************************************************************
// ************************************************************************************************
CFDictionaryRef currentRouteDescriptionDictionary = nil;
UInt32 dataSize = sizeof(currentRouteDescriptionDictionary);
AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &dataSize, ¤tRouteDescriptionDictionary);
if (currentRouteDescriptionDictionary) {
CFArrayRef outputs = CFDictionaryGetValue(currentRouteDescriptionDictionary, kAudioSession_AudioRouteKey_Outputs);
if(CFArrayGetCount(outputs) > 0) {
CFDictionaryRef currentOutput = CFArrayGetValueAtIndex(outputs, 0);
CFStringRef outputType = CFDictionaryGetValue(currentOutput, kAudioSession_AudioRouteKey_Type);
if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_AirPlay, 0) == kCFCompareEqualTo) ) { // if Airplay
NSLog(@"] Logic: output changed to Airplay");
}
else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_BluetoothA2DP, 0) == kCFCompareEqualTo) ) { // if Bluetooth A2DP
NSLog(@"] Logic: output changed to A2DP");
// Mix with others category
UInt32 doSetProperty = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof(doSetProperty),&doSetProperty);
// Bluetooth support enable
UInt32 allowBluetoothInput = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,sizeof (allowBluetoothInput),&allowBluetoothInput);
}
else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_BluetoothHFP, 0) == kCFCompareEqualTo) ) { // if Bluetooth HFP
NSLog(@"] Logic: output changed to HFP");
// Mix with others category
UInt32 doSetProperty = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof(doSetProperty),&doSetProperty);
// Bluetooth support enable
UInt32 allowBluetoothInput = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,sizeof (allowBluetoothInput),&allowBluetoothInput);
}
else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_LineOut, 0) == kCFCompareEqualTo) ) { // if Line Out
NSLog(@"] Logic: output changed to Line Out");
}
else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_Headphones, 0) == kCFCompareEqualTo) ) { // if Headphones
NSLog(@"] Logic: output changed to Headphone");
// Mix with others category
UInt32 doSetProperty = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof(doSetProperty),&doSetProperty);
// Bluetooth support disable
UInt32 allowBluetoothInput = 0;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,sizeof (allowBluetoothInput),&allowBluetoothInput);
}
else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_BuiltInSpeaker, 0) == kCFCompareEqualTo) ) { // if Built In Speaker
NSLog(@"] Logic: output changed to Built In Speaker");
// Mix with others category
UInt32 doSetProperty = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof(doSetProperty),&doSetProperty);
}
else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_USBAudio, 0) == kCFCompareEqualTo) ) { // if USB audio
NSLog(@"] Logic: output changed to USB Audio");
}
else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_HDMI, 0) == kCFCompareEqualTo) ) { // if HDMI
NSLog(@"] Logic: output changed to HDMI");
}
else if ( (CFStringCompare(outputType, kAudioSessionOutputRoute_BuiltInReceiver, 0) == kCFCompareEqualTo) ) { // if Built in Reciever
NSLog(@"] Logic: output changed to Built in Reciever");
// Mix with others category
UInt32 doSetProperty = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,sizeof(doSetProperty),&doSetProperty);
}
else { // Unknown audio type
NSLog(@"] Logic: WARNING: Unknown audio type: %@",(NSString*)outputType);
}
}
}
// ************************************************************************************************
// Check audio route ******************************************************************************
// ************************************************************************************************
UInt32 routeSize = sizeof(CFStringRef);
CFStringRef route;
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &routeSize, &route);
NSLog(@"] Logic: the audio route is: %@",(NSString*)route);
// ************************************************************************************************
NSLog(@"]--------------------------[ ]-----------------------------[");
}
Dans les simulateurs iOS 8, vous devez changer: si (CFarraygetCount (sorties)> 0) à: Si (sorties && cfarraygetCount (sorties)> 0)
Étant donné que Apple a changé le système audio à partir de 7.0, je vais publier ici le code mis à jour ici:
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(audioInterruption:) name: AVAudioSessionInterruptionNotification object: nil];
J'ai trouvé que lorsque vous utilisez des écouteurs AirPod Pro et essayez d'enregistrer une boîte vocale de voeux que le téléphone utilisé le micro intégré, même si le casque était complètement connecté et utilisé. P>
Les questions les plus intéressantes et les plus innovantes iront naturellement sans réponse. Vous aurez beaucoup de travail à faire seuls.
L'enregistrement via un micro interne et une lecture simultanée via les écouteurs de casque (et le micro du casque n'est pas inutilisé) était impossible dans iOS6. Dans l'IOS7, cela est possible grâce aux extensions de l'API présentes dans la classe Avaudiosandession.
@Daniel S. Comment nous pouvons enregistrer du micro interne et de la lecture via des écouteurs de casque?