Audio über den oberen Lautsprecher (Telefonanruf) wiedergeben

7

Ich versuche, Audio in meiner App zu erhalten, um durch den oberen Lautsprecher auf dem iPhone zu spielen, den Sie während eines Telefonats an Ihr Ohr drücken. Ich weiß, dass es möglich ist, weil ich ein Spiel aus dem App Store gespielt habe ("The Heist" mit "tap tap tap"), das Telefonanrufe simuliert und genau das tut.

Ich habe viel online recherchiert, aber es fällt mir überraschend schwer, jemanden zu finden, der diese Möglichkeit überhaupt diskutiert hat. Die überwiegende Mehrheit der Beiträge scheint über die Freisprecheinrichtung vs Plug-in-Ohrhörer zu sein, (wie dies und dies und Audio Session Category Route Overrides geschaut, aber diese scheinen wieder (korrigiere mich, wenn ich falsch liege) nur mit dem Freisprechlautsprecher an der Unterseite zu tun, nicht mit dem Lautsprecher an der Oberseite des Telefons.

Ich habe EINEN Beitrag gefunden, der darüber zu sein scheint: link Es bietet sogar eine Menge Code, also dachte ich, ich wäre zu Hause frei, aber jetzt kann ich den Code nicht zum Funktionieren bringen. Zur Vereinfachung kopiere ich einfach die DisableSpeakerPhone -Methode (die, wenn ich es richtig verstanden habe, sollte die Audio an den oberen Sprecher umleiten) in mein viewDidLoad , um zu sehen, ob es funktionieren würde, aber die erste "Assert" -Zeile schlägt fehl, und das Audio spielt weiter unten. (Ich habe auch das AudioToolbox Framework importiert, wie im Kommentar vorgeschlagen, so dass das nicht das Problem ist.)

Hier ist der Hauptblock des Codes, mit dem ich arbeite (das habe ich in meine viewDidLoad zum Testen kopiert), obwohl es in dem Artikel, mit dem ich verlinkt bin, noch ein paar Methoden gibt:

%Vor%

Meine Frage ist also: kann mir irgendjemand entweder A) helfen herauszufinden, warum dieser Code nicht funktioniert, oder B) einen besseren Vorschlag dafür geben, einen Knopf zu drücken und die Route zu routen Audio bis zum oberen Lautsprecher?

PS Ich werde immer vertrauter mit iOS-Programmierung, aber dies ist mein erster Ausflug in die Welt der AudioSessions und so, daher werden Details und Codebeispiele sehr geschätzt! Danke für Ihre Hilfe!

UPDATE:

Aus dem Vorschlag von "Er war" (unten) habe ich den oben zitierten Code entfernt und ihn ersetzt durch:

%Vor%

am Anfang von viewDidLoad . Es funktioniert jedoch immer noch nicht (womit ich meine, dass der Ton immer noch aus dem Lautsprecher am unteren Ende des Telefons kommt, anstatt vom Empfänger oben). Anscheinend sollte das Standardverhalten für AVAudioSessionCategoryPlayAndRecord sein, um Audio aus dem Empfänger selbst zu senden, also ist etwas immer noch falsch.

Genauer gesagt, mache ich mit diesem Code Audio über den iPod Music Player (initialisiert direkt nach den AVAudioSession-Zeilen oben in viewDidLoad , für das, was es wert ist):

%Vor%

und die Medien für diesen iPod Music Player werden über MPMediaPickerController :

ausgewählt %Vor%

Das scheint mir ziemlich einfach zu sein, ich habe keine Fehler oder Warnungen, und ich weiß, dass der Media Picker und der Music Player richtig funktionieren, weil die richtigen Songs zu spielen beginnen, es ist nur aus dem falschen Lautsprecher. Könnte es eine "Play Media mit dieser AudioSession" -Methode oder etwas geben? Oder gibt es eine Möglichkeit zu überprüfen, welche Audio-Session-Kategorie gerade aktiv ist, um zu bestätigen, dass nichts sie zurückgestellt haben könnte oder so? Gibt es eine Möglichkeit, den Code mit Nachdruck auf die Verwendung des Empfängers zu setzen, anstatt sich auf den Standardwert zu verlassen? Ich fühle mich, als ob ich auf der Ein-Yard-Linie bin, ich muss nur das letzte Stück durchqueren ...

EDIT: Ich habe gerade an eine Theorie gedacht, bei der es um den iPod Music Player geht, der nicht aus dem Receiver herausspielen will. Meine Argumentation: Es ist möglich, einen Song über die offizielle iPod-App abzuspielen und ihn dann über die App, die ich entwickle, nahtlos anzupassen (Pause, Überspringen usw.). Die kontinuierliche Wiedergabe von einer App zur nächsten hat mich dazu gebracht zu denken, dass der iPod Music Player vielleicht seine eigenen Einstellungen für die Audio-Route hat oder vielleicht hört er nicht auf, die Einstellungen in der neuen App zu überprüfen? Weiß irgendjemand, der weiß, worüber sie sprechen, dass es so etwas sein könnte?

    
Nerrolken 02.08.2013, 21:44
quelle

3 Antworten

4

Sie müssen Ihre Audiositzung zuerst initialisieren.

Verwenden der C-API

%Vor%

In iOS6 können Sie stattdessen AVAudioSession-Methoden verwenden (Sie müssen das AVFoundation-Framework importieren, um AVAudioSession zu verwenden):

Initialisierung mit AVAudioSession

%Vor%

Einstellen der audioSession-Kategorie mit AVAudioSession

%Vor%

Für weitere Forschung, wenn Sie bessere Suchbegriffe wollen, hier sind die vollständigen Namen der Konstanten für die Sprecher:

%Vor%

Siehe die Apple-Dokumente hier

Aber das wahre Geheimnis ist, warum Sie Schwierigkeiten haben, zum Empfänger zu routen. Dies ist das Standardverhalten für die Kategorie playAndRecord. Apples Dokumentation von kAudioSessionOverrideAudioRoute_None :

"Gibt für die Kategorie kAudioSessionCategory_PlayAndRecord an, dass das ausgegebene Audio an den Empfänger gesendet werden soll. Dies ist die Standard-Audioausgabe für diese Kategorie. "

update

In Ihrer aktualisierten Frage geben Sie an, dass Sie die Klasse MPMusicPlayerController verwenden. Diese Klasse ruft den globalen Musikplayer auf (derselbe Player, der in der Musik-App verwendet wird). Dieser Musikplayer ist von Ihrer App getrennt und teilt nicht die gleiche Audiositzung wie die audioSession Ihrer App. Alle Eigenschaften, die Sie für die audioSession Ihrer App festlegen, werden von MPMusicPlayerController ignoriert.

Wenn Sie das Audioverhalten Ihrer App steuern möchten, müssen Sie ein internes Audio-Framework für Ihre App verwenden. Dies wäre AVAudioRecorder / AVAudioPlayer oder Core Audio (Audio Queues, Audio Units oder OpenAL). Unabhängig davon, welche Methode Sie verwenden, kann die Audiositzung entweder über AVAudioSession properties oder über die Core Audio API gesteuert werden. Core Audio gibt Ihnen eine feinere Kontrolle, aber mit jeder neuen Version von iOS wird mehr davon auf AVFoundation portiert, also fangen Sie damit an.

Denken Sie auch daran, dass die Audiositzung Ihnen eine Möglichkeit bietet, das beabsichtigte Verhalten des Audiomaterials Ihrer App in Bezug auf die gesamte iOS-Umgebung zu beschreiben, aber Ihnen nicht die totale Kontrolle überreichen wird. Apple stellt sicher, dass die Erwartungen des Benutzers an das Audioverhalten des Geräts zwischen den Apps übereinstimmen und wenn eine App den Audiostream eines anderen Geräts unterbrechen muss.

update 2

In Ihrer Bearbeitung weisen Sie darauf hin, dass Audio-Sessions die Audio-Session-Einstellungen anderer Apps überprüfen können. Das passiert nicht 1 . Die Idee ist, dass jede App ihre eigenen Einstellungen für das eigene Audioverhalten vornimmt, indem sie ihre eigenständige Audiositzung verwendet. Das Betriebssystem entscheidet zwischen konkurrierenden Audioanforderungen, wenn mehr als eine App um eine nicht gemeinsam nutzbare Ressource wie das interne Mikrofon oder einen der Sprecher konkurriert, und entscheidet sich in der Regel für das wahrscheinlichste Verhalten um die Erwartungen des Benutzers an das Gerät als Ganzes zu erfüllen.

Die MPMusicPlayerController-Klasse ist insofern etwas ungewöhnlich, als sie es einer App ermöglicht, eine gewisse Kontrolle über eine andere zu haben. In diesem Fall spielt Ihre App das Audio nicht ab. Es wird eine Anfrage an den Musik-Player gesendet, um Audio in Ihrem Namen abzuspielen. Ihre Kontrolle ist durch den Umfang der MPMusicPlayerController API begrenzt. Für mehr Kontrolle muss Ihre App eine eigene Implementierung der Audiowiedergabe bereitstellen.

In Ihrem Kommentar fragen Sie sich:

  

Könnte es eine Möglichkeit geben, ein MPMediaItem aus dem MPMusicPlayerController zu ziehen und sie dann durch die App-spezifische Audio-Session oder etwas ähnliches zu spielen?

Das ist ein (großes) Thema für eine neue Frage. Hier ist ein guter Anfang lesen (von Chris Adamson Blog) - es ist die Fortsetzung von Von iPhone Medienbibliothek zu PCM Proben in Dutzenden von verwirrenden und potenziell verlustreichen Schritten - das sollte Ihnen einen Sinn für die Komplexität geben, der Sie gegenüberstehen. Dieses mag ist seit iOS6 einfacher geworden, aber ich wäre mir nicht so sicher!

1 Es gibt eine otherAudioPlaying schreibgeschützte BOOL-Eigenschaft in ios6, aber darum geht es

    
foundry 02.08.2013, 23:54
quelle
24

Kämpfte auch eine Weile damit. Vielleicht würde das später jemandem helfen. Sie können auch die neueren Methoden zum Überschreiben von Ports verwenden. Viele der Methoden in Ihrem Beispielcode sind tatsächlich veraltet.

Wenn Sie also Ihre AudioSession sharedInstance haben, erhalten Sie

%Vor%

Die Sitzungskategorie muss AVAudioSessionCategoryPlayAndRecord lauten Sie können die aktuelle Ausgabe erhalten, indem Sie diesen Wert überprüfen.

%Vor%

Und jetzt, abhängig von dem Port, an den Sie es senden möchten, schalten Sie einfach die Ausgabe mit

um %Vor%

Dies sollte ein schneller Weg sein, um die Ausgänge zum Lautsprecher und Empfänger umzuschalten.

    
DrJid 25.06.2014 20:45
quelle
1

Swift 3.0-Code

%Vor%     
krish 19.04.2017 10:22
quelle