Je travaille sur une application iOS qui doit jouer certains sons à l'aide du cadre AVFoundation
. La structure de l'espace de travail dans Xcode 4 contient deux projets:
Après la construction de la bibliothèque d’utilitaires, il en résulte une bibliothèque statique qui est utilisée dans l’application principale en tant que cadre.
Ainsi, lorsque vous essayez de jouer un son dans l'application principale à l'aide du code ci-dessous, cela fonctionne comme prévu.
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *path = [NSString stringWithFormat:@"%@/sound.mp3", resourcePath];
NSURL *url = [NSURL fileURLWithPath:path];
NSError *error = nil;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url
error:&error];
[audioPlayer play];
En revanche, lorsque vous essayez de reproduire exactement le même son (ou tout autre) à l'intérieur de la bibliothèque d'utilitaires en utilisant le même code que ci-dessus, aucun son n'est joué, même si error est nil et le audioPlayer les valeurs de propriété sont les bonnes (nombre de canaux, durée).
Je me suis assuré que le cadre AVFoundation
est dans les deux projets.
De plus, ma classe utilise le protocole AVAudioPlayerDelegate
et implémente ces deux méthodes:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error;
Aucune de ces méthodes n'est appelée après une tentative de lecture du son.
Si j'utilise plutôt le framework AudioToolbox
, il lit le son. Mais je voudrais utiliser AVFoundation
pour plusieurs raisons.
Une idée de ce qui se passe? Est-ce que je manque quelque chose à propos de AVFoundation
? Cela pourrait-il être lié à l'utilisation de AVAudioPlayer
depuis une bibliothèque statique?
Merci d'avance.
J'ai trouvé la solution et cela est lié à quelque chose que je n'ai pas mentionné et auquel je n'ai pas pensé: je compile avec Automatic Reference Counting (ARC).
ARC insère un appel de libération sur le lecteur audio. Il est donc désalloué juste après avoir quitté la méthode où il est créé. Cela n'a rien à voir avec AVAudioPlayer
mais avec ARC.
Afin de résoudre ce problème, je viens de créer un attribut AVAudioPlayer
pour la classe qui traite les sons afin qu’ils ne soient plus publiés par ARC. Eh bien, au moins, il n'est pas publié avant que l'instance de cette classe ne soit publiée.
Pour plus d'informations sur ARC, voir Comptage automatique de références: Remise à zéro des références faibles avec des explications sur la raison de ce problème.
Oui absolument; ARC était aussi la raison de mon code.
J'ai introduit une propriété:
@property (strong, nonatomic) AVAudioPlayer *audioPlayer;
et cela a bien fonctionné.
utilisez ceci cela fonctionnera définitivement ....
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
NSURL *url = [NSURL fileURLWithPath:@"path of the sound file :)"];
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[_player setDelegate:self];
[_player prepareToPlay];
[_player play];
Avez-vous configuré AVAudioSession?
J'ai eu un problème similaire et l'ai corrigé en utilisant quelque chose comme ceci:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:NULL];
ou
[audioSession setCategory:AVAudioSessionCategoryPlayback error:NULL];
J'espère que ça aide.
Même si audioPlayer est déclaré dans l'étendue de la classe, il ne jouera pas ... au moins sur le périphérique physique iOS 10 iPhone 5c.
play()
result est true
donc aucune erreur ne semble se produire.
J'ai dû ajouter ceci ( Swift 3, 4 ) et maintenant le son est lu correctement.
let session = AVAudioSession.sharedInstance()
try! session.setCategory(AVAudioSessionCategoryPlayback)
J'ai eu le même problème. Je l'avais résolu en ajoutant la ligne ci-dessous dans le fichier .h:
@property (strong, nonatomic) AVAudioPlayer *audioPlayer;
Et dans le fichier .m:
NSError *error;
NSString *soundFilePath = [NSString stringWithFormat:@"%@/dancepechance.mp3",
[[NSBundle mainBundle] resourcePath]];
NSURL *url = [NSURL fileURLWithPath:soundFilePath];
self.audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
NSLog(@"Error %@",error);
[self.audioPlayer prepareToPlay];
[self.audioPlayer play];
J'ai créé un projet open source pour un lecteur audio simple. Jetez-y un coup d'œil si vous rencontrez des problèmes de lecture audio dans iOS (en arrière-plan aussi): https://github.com/wzbozon/DKAudioPlayer
Vous pouvez utiliser AVPlayerViewController à partir de AVKit à la place pour l'audio et la vidéo. Le code est disponible pour Swift et Objective C ici .
Veuillez rester sur la page pendant un certain temps, je faisais face au même problème. et utilisez le sommeil pour le résoudre.
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:@"sounds-1027-are-you-kidding"
ofType:@"mp3"]];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:nil];
[audioPlayer play];
sleep(2);