Frage

Ich bin AVAudioPlayer mit Musik in meinem iPhone app zu spielen.

In einer Klasse, die ich geschrieben habe ich ein Array haben, die zufällig ansteigenden Zahlen enthält. (2, 4, 9, 17, 18, 20, ...) Diese Zahlen repräsentieren mal in dem Lied, bei dem ein bestimmtes Ereignis auftreten sollte. Also, wenn Sie die oben genannte Array nehmen, nach 2 Sekunden des Songs spielen, sollen einige Methoden aufgerufen werden. Nach 4 Sekunden sollte eine andere Methode aufgerufen werden. Und so weiter.

Ich habe versucht, eine sich wiederholende NSTimer mit:

NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerTick) userInfo:nil repeats:YES];

Jedes Mal, es feuert, wird geprüft, ob der Wert des Audioplayer und des aktuellen Arrayindex ist die gleiche:

- (void) timerTick {
   if([[myArray objectAtIndex:currentIndex] intValue] == (int)(player.currentTime)) {
   //here the event-method is called
   currentIndex++;
   }
}

Dieser Code tatsächlich funktioniert, aber nur für einige Zeit. aber nach einiger Zeit myTimer und der Timer, der die Musikplayer-Steuerelemente sind nicht synchron. So fehlt es ein Element von arr und eine Endlos-Schleife beginnt. Ich weiß nicht genau, warum sie nicht mehr synchron, aber ich denke, dass es sein könnte, weil der Timer und die Spieler sind nicht exakt zur gleichen Zeit oder vielleicht begonnen, weil die kurze Performance hinkt.

Ich glaube, ich dies auf eine ganz andere Art und Weise zu nähern haben. Ist Schlüssel-Wert-Beobachtung eine Art und Weise, dies zu tun? Ich konnte meine Klasse als Beobachter an den Spieler-Objekt hinzufügen, so dass es, wenn die player.currentTime Wertänderungen informiert wird. Aber das würde eine Menge Benachrichtigungen verursachen senden werden, und ich denke, es wäre für die Leistung wirklich schlecht sein.

Jede Hilfe sehr geschätzt!

War es hilfreich?

Lösung

hier Ok ist meine Lösung: ich einen Open-Source-App gefunden, die fast die gleiche Sache tut mein app tun soll, was mir sehr geholfen. Ich werde mit dem Code-Stick habe ich schon mit ein wenig Änderung sollte es genug für meine Zwecke genau sein. Hier ist sie:

currentIndex = 0;
myTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(timerTick) userInfo:nil repeats:YES];


- (void) timerTick {
 if(timerRunning){


     if([[myArray objectAtIndex:currentIndex] intValue] <= (int)(player.currentTime*100)) { 
         //some event code
         currentIndex++;
     }
 }
}

Die wichtige Änderung ist von == bis <= in der if-Bedingung. Wenn es erhält asynchrone und vermisst ein Element der myArray, wird der Fehler beim nächsten hundertstel Sekunde korrigiert. Das ist gut genug.

Vielen Dank für Ihre Hilfe!

Andere Tipps

Es könnte sein, dass die Timer maßen synchron sind, aber Ihr Code dauert nur zu lange auszuführen (das heißt: länger als 1 Sekunde).

Könnten Sie nicht den Timer des Musikplayer verwenden, und laichen jedes Mal einen Thread ein Ereignis eintreten sollte? Auf diese Weise der Timer bleibt ununterbrochen, und den Thread wird tun, was es tun muss (läßt die schweren Sachen sagen).

Wenn Sie y zwei Timer reall brauchen, denke ich Ihnen ein Hintergrund-Threads erstellen könnte, die diese beiden Timer synchron hält, aber ich denke, Sie Probleme haben zu fragen dort ..

Reale Welt Synchronisation mit Musik ist sehr schwer, weil die Benutzer mis-Synchronisierungen von nur ein Zehntel einer Sekunde oder weniger feststellen können. Sie können feststellen, dass AVAudioPlayer zu einfach ist, für das, was Sie brauchen. Sie könnten die Rate steuern müssen die Musik AudioQueueServices , so dass Sie die Musik auf den Code statt umgekehrt synchronisieren. Man konnte sehen, Zeit Code kommen zu feuern und dann die Methoden starten, bevor die Musik tatsächlich spielt. Done geschickt würde dies die Musik die meiste Zeit synchronisieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top