iPhone - starten mehrere Instanzen von AVAudioPlayer gleichzeitig
-
18-09-2019 - |
Frage
ich mehrere Instanzen von AVAudioPlayer bin mit gleichzeitig mehrere Audio-Dateien zu spielen. Ich betreiben eine Schleife zu starten, um die Audio-Dateien wiedergegeben werden (prepareToPlay aufgerufen vorher und die Schleife macht nur einen Aufruf an die Play-Methode)
Aber immer, einer der Spieler in sync nicht spielen. Wie kann ich sicherstellen, dass alle vier Spieler gleichzeitig spielen Audio starten?
Danke.
Lösung
Leider kann man nicht. AVAudioPlayer bietet keinen Mechanismus für eine feinkörnige Steuerung der Startzeit. Die currentTime
Eigenschaft legt den Punkt in der Datei aus zu lesen, ist es nicht garantiert, wenn die AVAudioPlayer Instanz startet in Systemzeit zu spielen, das ist, was Sie mehrere Audio-Streams synchronisieren müssen.
Wenn ich dieses Verhalten benötigen, verwende ich die RemoteIO Audio Unit + den 3D-Mixer Audio Unit + ExtAudioFile.
EDIT
Beachten Sie, dass ab iOS 4 können Sie mehrere AVAudioPlayer
Instanzen mit playAtTime:
Andere Tipps
Die Apple-docs darüber sprechen, wie man „gleichzeitig mehrere Töne spielen, ein Ton pro Audio-Player, mit präzise Synchronisation“ kann. Vielleicht brauchen Sie playAtTime:
zum Beispiel nennen [myAudioPlayer playAtTime: myAudioPlayer.deviceCurrentTime + playbackDelay];
In der Tat, die Apple-Dokumentation für playAtTime: den folgenden Code-Schnipsel enthalten:
NSTimeInterval shortStartDelay = 0.01; // seconds
NSTimeInterval now = player.deviceCurrentTime;
[player playAtTime: now + shortStartDelay];
[secondPlayer playAtTime: now + shortStartDelay];
Sie sollten gleichzeitig spielen (vorausgesetzt, Sie einen ausreichend großen Wert für shortStartDelay
wählen - nicht so schnell, dass es vor diesem Thread geschieht zurückkehrt oder was auch immer).
Mit diesem Code-Segment von mir können Sie dies so lange tun, wie Sie es sofort nicht tun müssen. Sie können in der targetTime als Zeitstempel übergeben, wenn Sie die Klänge hören wollen. Der Trick ist die Verwendung von Zeitstempeln und die Verzögerung Funktionalität von NSObject zu machen. Außerdem nutzt es die Tatsache, dass es viel weniger Zeit in Anspruch nimmt die Lautstärke des Players zu ändern, als es die aktuelle Zeit zu ändern. Sollte fast perfekt präzise arbeiten.
- (void) moveTrackPlayerTo:(double) timeInSong atTime:(double) targetTime {
[trackPlayer play];
trackPlayer.volume = 0;
double timeOrig = CFAbsoluteTimeGetCurrent();
double delay = targetTime - CFAbsoluteTimeGetCurrent();
[self performSelector:@selector(volumeTo:)
withObject:[NSNumber numberWithFloat:single.GLTrackVolume]
afterDelay:delay];
trackPlayer.currentTime = timeInSong - delay - (CFAbsoluteTimeGetCurrent() - timeOrig);
}
- (void) volumeTo:(NSNumber *) volNumb {
trackPlayer.volume = [volNumb floatValue];
}
Versuchen gleichen current Eigenschaftswert für jedes Objekt AVAudioPlayer.