Question

J'utilise AVAudioPlayer pour lire de la musique dans mon application iPhone.

Dans une classe que j'ai écrite, j'ai un tableau contenant des entiers croissants aléatoires. (2, 4, 9, 17, 18, 20, ...) Ces nombres entiers représentent les moments de la chanson où un certain événement devrait se produire. Donc, si vous prenez le tableau ci-dessus, après 2 secondes de lecture du morceau, une méthode devrait être appelée. Après 4 secondes, une autre méthode devrait être appelée. Et ainsi de suite.

J'ai essayé d'utiliser un NSTimer répété:

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

Chaque fois qu'il se déclenche, il vérifie si les valeurs de Audioplayer et de l'index de tableau actuel sont identiques:

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

Ce code fonctionne réellement, mais seulement pendant un certain temps. Cependant, après un certain temps, myTimer et le minuteur qui contrôle le lecteur de musique ne sont plus synchronisés. Donc, il manque un élément de myArray et une boucle infinie commence. Je ne sais pas exactement pourquoi ils se désynchronisent, mais je pense que cela pourrait être dû au fait que le chronomètre et le lecteur ne démarrent pas exactement au même moment, ou peut-être à cause de la lenteur des performances.

Je pense que je dois aborder la question d'une manière totalement différente. Est-ce que l'observation clé-valeur est un moyen de le faire? Je pourrais ajouter ma classe en tant qu'observateur à l'objet player, afin qu'elle soit avertie lorsque la valeur player.currentTime change. Mais cela entraînerait l'envoi de nombreuses notifications et je pense que ce serait vraiment mauvais pour les performances.

Toute aide très appréciée!

Était-ce utile?

La solution

Ok, voici ma solution: j'ai trouvé une application open source qui fait presque la même chose que mon application devrait faire, ce qui m'a beaucoup aidé. Je vais rester avec le code que j'ai déjà, avec une petite modification, il devrait être assez précis pour mes besoins. La voici:

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++;
     }
 }
}

Le changement important est de == à < = dans la condition if. Quand il devient asynchrone et manque un élément de myArray, l'erreur est corrigée au centième de seconde. C'est assez bon.

Merci pour votre aide!

Autres conseils

Il se peut que les minuteries soient raisonnablement synchronisées, mais que le code soit long à exécuter (c'est-à-dire plus d'une seconde).

Ne pourriez-vous pas simplement utiliser le minuteur du lecteur de musique et créer un fil de discussion chaque fois qu'un événement devrait se produire? De cette façon, la minuterie reste ininterrompue et votre thread fera ce qu’il doit faire (disons le gros matériel).

Si vous avez réellement besoin de deux minuteries, je suppose que vous pouvez créer un fil d’arrière-plan qui garde ces deux minuteurs synchronisés, mais je pense que vous demandez des ennuis ici.

La synchronisation dans le monde réel avec la musique est très difficile, car les utilisateurs peuvent remarquer des erreurs de synchronisation d'un dixième de seconde ou moins. Vous constaterez peut-être qu'AVAudioPlayer est trop simple pour répondre à vos besoins. Vous devrez peut-être contrôler le débit de lecture de la musique à l'aide de AudioQueueServices afin que vous puissiez synchroniser la musique avec le code plutôt que l'inverse. Vous pouvez voir le temps de déclencher votre code, puis de lancer les méthodes avant que la musique ne soit réellement lue. Fait habilement, cela synchroniserait la musique la plupart du temps.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top