2012-05-06 3 views
0

Dans mon application, j'ai 52 mp3 et quand je charge mon contrôleur de vue que j'alloc les 52 mp3 ainsi:IOS: AVAudioPlayer

NSString *pathFrase1 = [NSString stringWithFormat:@"%@/%@",[[NSBundle mainBundle] resourcePath],[NSString stringWithFormat:@"a%d_1a.mp3",set]]; 
NSURL *filePath1 = [NSURL fileURLWithPath:pathFrase1 isDirectory:NO]; 
f1 = [[AVAudioPlayer alloc] initWithContentsOfURL:filePath1 error:nil]; 
[f1 prepareToPlay]; 

mais il est très lent quand j'ouvre viewcontroller, puis est-il un moyen allouer mp3 quand je l'utilise? et libérer son AVAudioPlayer ??

Répondre

1

Bien sûr, mais il y aura un délai car le AVAudioPlayer est alloué et prêt à jouer. Pouvez-vous prédire ce qui va jouer et quand? Si oui, peut-être vous pouvez charger quelques secondes avant d'avoir besoin d'un mp3 particulier à jouer.

Une alternative qui ne peut pas fonctionner en fonction de vos besoins de synchronisation, est la suivante:

- (void)prepareAudioPlayer { 
    static int index = -1; 
    index = index + 1; 
    if (index < [[self FileNames] count]) { 
     NSError *err = nil; 
     NSString *audioFilePath = @""; // Figure out how to get each file name here 
     NSURL *audioFileURL = [NSURL fileURLWithPath:audioFilePath]; 
     AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL error:&err]; 
     if (err) { 
      NSLog(@"Audio Player Error: %@", [err description]); 
     } 
     [player prepareToPlay]; 
     // Add this player to the "AudioPlayers" array 
     [[self AudioPlayers] addObject:player]; 
     // Recurse until all players are loaded 
     [self prepareAudioPlayer]; 
    } 
} 

Cette solution nécessite des propriétés de FileNames et AudioPlayers.

Une fois configuré, vous pouvez faire quelque chose comme ce qui suit (probablement viewDidLoad):

// Make the file name array 
[self setFileNames:[NSMutableArray array]]; 
// Initiate the audio player loading 
[self performSelectorInBackground:@selector(prepareAudioPlayer) withObject:nil]; 

Plus tard, quand vous avez besoin de lire un fichier particulier, vous pouvez trouver l'index du nom de fichier dans le tableau FileNames et l'appel play sur le AVAudioPlayer pour cet index dans le tableau AudioPlayers.

Cela ne semble peut-être pas la meilleure façon de faire les choses, mais cela pourrait fonctionner si vous le souhaitez.

0

Voici la méthode utilisée. Si le son est en cours de lecture, le temps actuel correspond au décalage de la position de lecture actuelle, mesurée en secondes à partir du début du son. Si le son n'est pas joué, le temps actuel est le décalage de l'endroit où la lecture commence lors de l'appel de la méthode de lecture, mesurée en secondes à partir du début du son.

En réglant cette propriété, vous pouvez rechercher un point spécifique dans un fichier son ou implémenter des fonctions d'avance rapide et de retour rapide. La valeur de cette propriété augmente de façon monotone pendant la lecture ou la mise en pause d'un lecteur audio.

Si plusieurs lecteurs audio sont connectés au périphérique de sortie audio, l'heure de l'appareil continue d'augmenter tant que l'un des lecteurs est en cours de lecture ou en pause.

Si le périphérique de sortie audio n'a pas de lecteurs audio connectés qui sont soit lecture ou en pause, le temps de l'appareil revient à 0.

Utilisez cette propriété pour indiquer « maintenant » lorsque vous appelez le AtTime de jeu: méthode d'instance. En configurant plusieurs lecteurs audio pour jouer à un décalage spécifié de deviceCurrent Time, vous pouvez effectuer une synchronisation précise - comme décrit dans la discussion pour cette méthode. Pour en savoir plus, visitez .. enter link description here

6

C'est un peu plus compliqué à gérer, mais Au lieu d'utiliser AVAudioPlayer, utilisez AVPlayer. AVPlayer est conçu pour lire AVAssets, qui peut être des fichiers préchargés. Plus précisément, vous voudrez utiliser une sous-classe de AVAsset appelée AVURLAssets, qui peut charger votre URL: Loading AVAsset. Vous pouvez ensuite utiliser AVAsset pour créer un AVPlayerItem. Un AVPlayerItem est un wrapper léger qu'AVPlayer utilise pour suivre l'état de lecture d'un AVAsset. La bonne chose à propos de l'utilisation de AVPlayer est qu'il peut jouer un AVMutableComposition, qui lui-même peut contenir plusieurs AVAssets.AVPlayer peut également lire une file d'attente d'AVAssets et vous fournir des informations sur le moment où il commence à lire un nouvel AVAsset, et lequel. Si vous chargez vos MP3 dans un groupe d'AVURlAssets, vous pouvez les charger et les conserver, en créant AVPlayerItem & AVPlayer uniquement lorsque vous souhaitez lire un (ou plusieurs) des fichiers MP3. AVAudioPlayer est conçu pour lire des fichiers uniques, mais il utilise AVAssets (et probablement AVPlayer) en arrière-plan. C'est sympa pour les situations simples, mais quelque chose de plus complexe et que vous voulez vraiment utiliser AVPlayer.

Je devrais également souligner que AVPlayerItem & AVPlayer sont des objets légers. Ils ne tardent pas à instancier. Il charge l'AVAsset qui prend tout le temps. Vous pouvez donc créer et détruire des objets AVPlayerItem & AVPlayer selon vos besoins. Enfin, AVAsset et AVPlayer comptent parfois sur des blocs pour les notifications. Ainsi, par exemple, vous devrez peut-être utiliser des c-blocks lors du chargement de AVURLAsset pour obtenir une notification sur le moment où un Asset est complètement chargé. Sachez simplement que ces blocs ne sont pas appelés sur le thread principal. Donc, si vous essayez de mettre à jour des éléments de l'interface utilisateur ou de faire des animations à partir de ce bloc, cela ne fonctionnera pas correctement. Pour ce faire, vous devez envoyer un autre bloc au thread principal, par exemple: dispatch_async(dispatch_get_main_queue(),^{....update UI element code....});. Pour plus d'informations sur les blocs d'envoi, consultez les articles Concurrency Programming Guide et Block Programming Guide d'Apple.