La lecture de l'audio par le biais de haut (appel téléphonique) haut-parleur
Je suis en train d'essayer d'obtenir l'audio dans mon appli pour jouer par la partie supérieure du haut-parleur de l'iPhone, celui que vous appuyez sur à votre oreille pendant un appel téléphonique. Je sais que c'est possible, parce que j'ai joué à un jeu sur l'App Store (Le"hold-up" par "tap tap tap") qui simule les appels téléphoniques et ne fait que cela.
J'ai fait beaucoup de recherches en ligne, mais je vais avoir une surprise du mal à trouver quelqu'un qui a même discuté de la possibilité. L'écrasante majorité des postes semblent être sur le haut-parleur mains libres vs branché des écouteurs, (comme cette et cette et cette), plutôt que par le haut "appel téléphonique" haut-parleur vs le haut-parleur mains libres. (Une partie de ce problème pourrait être de ne pas avoir un bon nom pour elle: "haut-parleur de téléphone", on entend souvent le haut-parleur mains libres au bas de l'appareil, etc, il est donc difficile de faire un vraiment bien ciblés de recherche). J'ai regardé dans Apple Audio Session Category Route Overrides
, mais ces nouveau semble (corrigez-moi si je me trompe) ne traitent qu'avec le haut-parleur mains libres sur le fond, pas le haut-parleur en haut du téléphone.
Je l'ai trouvé UN post qui semble être à ce sujet: lien. Il fournit même un tas de code, donc je pensais que j'étais à la maison gratuitement, mais maintenant je n'arrive pas à obtenir le code du travail. Pour des raisons de simplicité j'ai juste copié le DisableSpeakerPhone
méthode (qui, si je comprends bien, devrait être le seul à le re-routage audio pour le haut-parleur) dans mon viewDidLoad
pour voir si ça marcherait, mais la première "assert" ligne échoue, et la musique continue de jouer la bas. (J'ai aussi importé le AudioToolbox Cadre, comme le suggère le commentaire, si ce n'est pas le problème).
Ici est le principal bloc de code, je travaille avec (c'est ce que j'ai copié dans mon viewDidLoad
pour tester), mais il ya un peu plus de méthodes dans l'article que j'ai lié à:
void DisableSpeakerPhone () {
UInt32 dataSize = sizeof(CFStringRef);
CFStringRef currentRoute = NULL;
OSStatus result = noErr;
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &dataSize, ¤tRoute);
//Set the category to use the speakers and microphone.
UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
result = AudioSessionSetProperty (
kAudioSessionProperty_AudioCategory,
sizeof (sessionCategory),
&sessionCategory
);
assert(result == kAudioSessionNoError);
Float64 sampleRate = 44100.0;
dataSize = sizeof(sampleRate);
result = AudioSessionSetProperty (
kAudioSessionProperty_PreferredHardwareSampleRate,
dataSize,
&sampleRate
);
assert(result == kAudioSessionNoError);
//Default to speakerphone if a headset isn't plugged in.
//Overriding the output audio route
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;
dataSize = sizeof(audioRouteOverride);
AudioSessionSetProperty(
kAudioSessionProperty_OverrideAudioRoute,
dataSize,
&audioRouteOverride);
assert(result == kAudioSessionNoError);
AudioSessionSetActive(YES);
}
Donc ma question est: est-ce quelqu'Un) m'aider à comprendre pourquoi ce code ne fonctionne pas, ou B) d'offrir une meilleure suggestion pour être en mesure d'appuyer sur un bouton et acheminer l'audio jusqu'à la partie supérieure du haut-parleur?
PS je suis de plus en plus familiers avec iOS programmation, mais c'est ma première incursion dans le monde de la AudioSessions et tels, de sorte que les détails et les exemples de code sont très appréciés! Merci pour votre aide!
Mise à JOUR:
De la suggestion de "Il Était" (ci-dessous) j'ai enlevé le code cité ci-dessus et l'a remplacé par:
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord error:nil];
[[AVAudioSession sharedInstance] setActive: YES error:nil];
au début de viewDidLoad
. Il ne fonctionne toujours pas, bien que, je veux dire l'audio est toujours de sortir de l'enceinte du bas du téléphone à la place du récepteur vers le haut). Apparemment, le comportement par défaut devrait être pour AVAudioSessionCategoryPlayAndRecord
pour envoyer la sortie audio du récepteur sur son propre, donc quelque chose est toujours mal.
Plus précisément ce que je fais avec ce code est en cours de lecture audio par le biais de l'iPod Lecteur de Musique (initialisé à droite après le AVAudioSession lignes ci-dessus dans viewDidLoad
, pour ce que ça vaut):
_musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
et les médias pour iPod, Lecteur de Musique est choisie par un MPMediaPickerController
:
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection {
if (mediaItemCollection) {
[_musicPlayer setQueueWithItemCollection: mediaItemCollection];
[_musicPlayer play];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Tout cela semble assez simple pour moi, j'ai pas d'erreurs ou d'avertissements, et je sais que le Sélecteur de support et Lecteur de Musique fonctionne correctement parce que la bonne chansons de commencer à jouer, c'est juste de la mauvaise haut-parleur. Pourrait-il y avoir un "jeu de médias à l'aide de cette AudioSession" méthode ou quelque chose? Ou est-il un moyen de vérifier ce que l'audio de la session de la catégorie active, afin de confirmer que rien n'aurait pu basculer en arrière ou quelque chose? Est-il un moyen de dire catégoriquement le code pour UTILISER le récepteur, plutôt que de compter sur le défaut de le faire? Je sens que je suis sur la ligne d'une verge, j'ai juste besoin de traverser cette finale peu...
EDIT: je viens de penser à une théorie, selon laquelle il est quelque chose au sujet de l'iPod Lecteur de Musique qui ne veulent pas jouer hors du récepteur. Mon raisonnement: il est possible de définir une chanson pour démarrer la lecture à travers les officiels application iPod et puis de façon ajuster (pause, sauter, etc) par le biais de l'application que je suis en développement. La lecture en continu à partir d'une application à l'autre m'a fait penser que peut-être la Musique de l'iPod Player dispose de son propre audio paramètres de l'itinéraire, ou peut-être qu'il ne s'arrête pas à vérifier les paramètres dans la nouvelle application? Quelqu'un qui sait de quoi ils parlent pense que cela pourrait-il être quelque chose comme ça?
Commentaire-les tous, et c'est comme il n'y a pas de code il y a tout: de l'audio passe par le haut-parleur au bas. J'imagine que c'est parce que le même problème à l'origine de la affirme à l'échec, je suis juste pas assez d'expérience pour savoir ce que cela pourrait être.
Je ne suis pas non plus... Bonne chance!
stackoverflow.com/questions/39159695/...
OriginalL'auteur Nerrolken | 2013-08-02
Vous devez vous connecter pour publier un commentaire.
Vous devez initialiser votre session audio en premier.
À l'aide de l'API C
Dans iOS6, vous pouvez utiliser AVAudioSession méthodes à la place (vous devez importer le AVFoundation cadre de l'utilisation
AVAudioSession
):D'initialisation à l'aide de AVAudioSession
Réglage de la audioSession catégorie à l'aide de AVAudioSession
Pour d'autres recherches, si vous voulez mieux les termes de recherche, voici les noms des constantes pour les haut-parleurs:
voir apple docs ici
Mais le vrai mystère est pourquoi vous rencontrez des problèmes de routage pour le récepteur. C'est le comportement par défaut pour la playAndRecord catégorie. La documentation d'Apple de
kAudioSessionOverrideAudioRoute_None
:", Précise, pour la kAudioSessionCategory_PlayAndRecord catégorie, que de l'audio de sortie devrait aller pour le récepteur. C'est la valeur par défaut de sortie audio de l'itinéraire pour cette catégorie."
mise à jour
Dans la mise à jour de votre question vous révéler que vous êtes à l'aide de la
MPMusicPlayerController
classe. Cette classe appelle le global lecteur de musique (le même joueur dans la Musique app). Ce lecteur de musique est séparé de votre application, et ainsi ne partage pas le même audio de la session de votre application audioSession. Toutes les propriétés que vous définissez sur votre application audioSession sera ignoré par le MPMusicPlayerController.Si vous souhaitez garder le contrôle sur votre application audio de comportement, vous devez utiliser une trame sonore à l'intérieur de votre application. Ce serait
AVAudioRecorder
/AVAudioPlayer
ou Core Audio (Audio Files d'attente, Audio units ou OpenAL). Quelle que soit la méthode que vous utilisez, la session audio peut être contrôlé soit par l'intermédiaire deAVAudioSession
propriétés ou via le Core Audio API. Core Audio vous donne un contrôle plus fin, mais avec chaque nouvelle version d'iOS, plus de il est porté sur AVFoundation, afin de commencer avec ça.Rappelez-vous aussi que la session audio fournit un moyen pour vous de décrire les objectifs de comportement de votre application audio par rapport au total de l'environnement iOS, mais il ne sera pas la main que vous avez le contrôle total. Apple prend soin de s'assurer que les attentes de l'utilisateur de leur audio de l'appareil comportement rester cohérent entre les applications, et lorsqu'une application a besoin d'interrompre un autre flux audio.
mise à jour 2
Dans votre montage, vous faites allusion à la possibilité de sessions audio vérifier d'autres app audio les paramètres de la session. Cela ne se produit pas1. L'idée est que chaque application définit les préférences de son propre comportement audio à l'aide, c'est l'auto-contenus audio de la session. Le système d'exploitation joue le rôle d'arbitre entre des exigences relatives à l'audio lorsque plus d'une application en concurrence pour un unshareable de ressources, tels que le microphone interne ou de l'un des haut-parleurs, et sera généralement décider en faveur de ce comportement qui est le plus susceptible de répondre aux attentes de l'utilisateur de l'appareil dans son ensemble.
La MPMusicPlayerController classe est un peu inhabituel en ce qu'il vous donne la possibilité pour une application à avoir un certain degré de contrôle sur l'autre. Dans ce cas, votre application n'est pas la lecture des fichiers audio, il est l'envoi d'une demande au Lecteur de Musique pour lire des fichiers audio sur votre nom. Votre contrôle est limitée par l'étendue de la MPMusicPlayerController API. Pour plus de contrôle, votre application devra fournir sa propre implémentation de la lecture audio.
Dans votre commentaire, vous vous demandez:
C'est un (grand) sujet pour une nouvelle question. Ici, c'est un bon début lire (à partir de Chris Adamson blog) À partir de l'iPod de la Bibliothèque d'Échantillons PCM en bien Moins d'Étapes Que ne l'Étaient Auparavant Nécessaires - c'est la suite de À partir de l'iphone médias de la bibliothèque d'échantillons pcm dans des dizaines de confusion et potentiellement avec perte étapes - qui devrait vous donner une idée de la complexité qui vous feront face. Cette peut ont obtenu plus facile depuis iOS6, mais je ne serais pas si sûr!
1 il y a une
otherAudioPlaying
en lecture seule BOOL propriété dans ios6, mais c'est sur ilAVAudioSessionCategoryPlayAndRecord
et il pourrait être exactement ce que je cherche. Cependant, j'ai ajouté les lignes[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; [[AVAudioSession sharedInstance] setActive:YES error:nil];
à la place du code que j'ai posté àviewDidLoad
, et je ne reçois pas toutes les erreurs, mais il joue encore à travers le haut-parleur. Toute idée de ce que je fais mal? Si ces lignes ne doivent pas aller dansviewDidLoad
, ou dois-je besoin de faire quelque chose avec mon[self.musicPlayer play];
lignes ou quoi que ce soit?oui, ils doivent aller dans viewDidLoad. Vous devez initialiser la audioSession avant de définir toutes les propriétés.
[AVAudioSession sharedInstance]
réalise que. En ce qui concerne[self.musicPlayer play]
vous ne publiez pas ce code dans votre question initiale. Peut-être que vous devriez mettre à jour la question avec plus de code contexte, que le code que vous avez déjà posté devrait fonctionner.Mis à jour. Ne rien là-dedans, regarde comme il pourrait être le problème? Et merci encore pour votre aide si loin!
voir mon jour de réponse. Si vous voulez creuser plus profondément dans Core Audio, je recommande fortement l'Apprentissage "Core Audio" livre de Chris Adamson et Kevin Avila.
En réponse à la première question: oui, c'est correct.
OriginalL'auteur foundry
A été aux prises avec ce pour un temps trop. Peut-être que cela aiderait quelqu'un plus tard.Vous pouvez également utiliser des méthodes plus récentes, de l'annulation de ports. De nombreuses méthodes dans votre exemple de code sont en fait obsolète.
Donc si vous avez votre AudioSession sharedInstance par arriver,
La session de catégorie a à AVAudioSessionCategoryPlayAndRecord
Vous pouvez obtenir la sortie courant par la vérification de cette valeur.
Et maintenant en fonction du port que vous souhaitez envoyer, il suffit de basculer la sortie à l'aide de
Cela devrait être un moyen rapide pour basculer les sorties du haut-parleur du téléphone et d'un récepteur.
Essayé cette solution d'iOS 8. Les travaux de cette. Juste [session overrideOutputAudioPort:AVAudioSessionPortOverrideNone erreur:nil]; si vous ne voulez pas qu'il bascule et juste jouer le son dans l'écouteur.
pouvez vous s'il vous plaît jetez un oeil à ce. stackoverflow.com/questions/45424446/...
OriginalL'auteur DrJid
Swift 3.0 Code
OriginalL'auteur krish