web-dev-qa-db-fra.com

Jouer un son court dans iOS

J'imagine que je pourrais utiliser AVAudioPlayer pour jouer un son. Cependant, ce dont j'ai besoin, c'est de jouer un son bref et je n'ai besoin d'aucune boucle ni d'aucun contrôle précis du volume, etc.

Y a-t-il un moyen facile de faire ceci?

58
Besi

Chacune des autres réponses perd de la mémoire (sauf si ARC est activé pour une des réponses) ... curieusement, la réponse marquée à l'origine comme correcte a un appel à retainCount sans raison apparente.

Si vous alloc/init Quelque chose, il doit être publié (sauf si vous utilisez ARC).

Si vous appelez AudioServicesCreateSystemSoundID(), vous devez vous débarrasser du son résultant.

Voir l'exemple Sons de l'interface audio .

Fondamentalement:

@interface MyClass:UI*ViewController // fixed
{
     SystemSoundID mySound;
}
@implementation MyClass
- (void) viewDidLoad {
    [super viewDidLoad];
    AudioServicesCreateSystemSoundID(.... URL ...., &mySound);
}

- (void) playMySoundLikeRightNowReally {
    AudioServicesPlaySystemSound(mySound);
}

- (void) dealloc {
   AudioServicesDisposeSystemSoundID(mySound);
   [super dealloc]; // only in manual retain/release, delete for ARC
}
@end

Pour être complet:
add AudioToolbox.framework
#import <AudioToolbox/AudioToolbox.h>

88
bbum

Pour les clips audio courts (moins de 30 secondes), il y a une bibliothèque SystemSounds qui est vraiment agréable.

Avantages: vous n'avez pas besoin de gérer les paramètres de volume séparément. Le son est joué dans un fil séparé et le chargement et la lecture du clip audio se font très rapidement. En bref, vous traitez ce clip comme un autre son système.

Inconvénients: Vous ne pouvez pas fournir un paramètre de contrôle audio séparé. Cela est lié aux paramètres des sons du système. Vous ne pouvez pas jouer plus de 30 secondes. Vous ne pouvez probablement pas appliquer de filtres sonores pour améliorer les effets audio.

Il y a certes plus d'avantages et d'inconvénients, mais ce sont des exemples auxquels je pourrais penser, et ce, par cœur.

utiliser cette importation: <AudioToolbox/AudioToolbox.h> Ajoutez le cadre AudioToolbox puis appelez la méthode ci-dessous telle que [self playSound], où vous voulez lire le clip.

-(void) playSound {
    NSString *soundPath = [[NSBundle mainBundle] pathForResource:@"changeTrack" ofType:@"aif"];
    SystemSoundID soundID;
    AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath: soundPath], &soundID);
    AudioServicesPlaySystemSound (soundID);
    [soundPath release];
}
43
Himanshu Singh

Swift

Les autres réponses ici utilisent Objective-C, donc je fournis une Swift ici. Swift utilise le comptage de référence automatique (ARC), donc je ne suis pas au courant). tout problème de fuite de mémoire avec cette réponse (comme indiqué dans la réponse acceptée).

Utiliser AudioToolbox

Vous pouvez utiliser le framework AudioToolbox pour jouer des sons courts lorsque vous n'avez pas besoin de beaucoup de contrôle sur la manière dont ils sont lus.

Voici comment vous le configurer:

import UIKit
import AudioToolbox

class PlaySoundViewController: UIViewController {

    var soundURL: NSURL?
    var soundID: SystemSoundID = 0

    @IBAction func playSoundButtonTapped(sender: AnyObject) {

        let filePath = NSBundle.mainBundle().pathForResource("yourAudioFileName", ofType: "mp3")
        soundURL = NSURL(fileURLWithPath: filePath!)
        if let url = soundURL {
            AudioServicesCreateSystemSoundID(url, &soundID)
            AudioServicesPlaySystemSound(soundID)
        }
    }
}

Remarques:

  • Cet exemple est adapté de Comment lire un court clip audio avec AudioToolbox dans Swift .
  • N'oubliez pas d'ajouter yourAudioFileName.mp3 (ou .wav, etc) à votre projet.
  • Se souvenir de import AudioToolbox
  • Cette réponse met le code dans un robinet de bouton IBAction, mais il pourrait tout aussi bien être mis dans une autre fonction, bien sûr.

Utiliser AVAudioPlayer

En important le framework AVFoundation, vous pouvez utiliser AVAudioPlayer. Cela fonctionne pour les clips audio courts et les chansons longues. Vous avez également davantage de contrôle sur la lecture qu'avec la méthode AudioToolbox.

Voici comment vous le configurer:

import UIKit
import AVFoundation

class PlaySoundViewController: UIViewController {

    var mySound: AVAudioPlayer?

    // a button that plays a sound
    @IBAction func playSoundButtonTapped(sender: AnyObject) {
        mySound?.play() // ignored if nil
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // initialize the sound
        if let sound = self.setupAudioPlayerWithFile("yourAudioFileName", type: "mp3") {
            self.mySound = sound
        }
    }

    func setupAudioPlayerWithFile(file: NSString, type: NSString) -> AVAudioPlayer? {

        let path = NSBundle.mainBundle().pathForResource(file as String, ofType: type as String)
        let url = NSURL.fileURLWithPath(path!)
        var audioPlayer: AVAudioPlayer?
        do {
            try audioPlayer = AVAudioPlayer(contentsOfURL: url)
        } catch {
            print("Player not available")
        }

        return audioPlayer
    }
}

Remarques:

23
Suragch

Récemment, j'ai utilisé ce code pour lire de courts fichiers audio MP3 qui fonctionnaient bien: -

Déclarez ceci en dessous de la @implémentation

NSString *path;

NSURL *url;

//where you are about to add sound 

path =[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"quotes_%d",soundTags] ofType:@"mp3"];

    url = [NSURL fileURLWithPath:path];
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
    [player setVolume:1.0];
    [player play];

//just add AVFoundation framework
17
Arshad Parwez

J'ai utilisé ce code pour jouer un bref son aiff sur iOS

#import <AudioToolbox/AudioServices.h> 

SystemSoundID completeSound;
NSURL *audioPath = [[NSBundle mainBundle] URLForResource:@"downloadCompleted" withExtension:@"aiff"];
AudioServicesCreateSystemSoundID((CFURLRef)audioPath, &completeSound);
AudioServicesPlaySystemSound (completeSound);

J'espère que cela t'aides.

9
Schulze Thomas

SIMPLE CLEAN Swift 3 VERSION

J'aime mieux contrôler mes sons et j'utilise donc AVFoundation.

import AVFoundation

class TodayViewController: UIViewController {

  var clink: AVAudioPlayer?
  var shatter: AVAudioPlayer?

  override func viewDidLoad() {
    super.viewDidLoad()

    // initialize the sound
    shatter = setupAudioPlayer(withFile: "shatter", type: "wav")
    clink = setupAudioPlayer(withFile: "clink", type: "wav")
  }

  func setupAudioPlayer(withFile file: String, type: String) -> AVAudioPlayer? {
    let path = Bundle.main.path(forResource: file, ofType: type)
    let url = NSURL.fileURL(withPath: path!)
    return try? AVAudioPlayer(contentsOf: url)
  }

  func onClick() {
    clink?.play()
  }
}

Assurez-vous que le fichier son est ajouté à votre projet et que vous importez AVFoundation.

6
Rob Norback

Ma réponse est la réponse de Bill, mais je l'utilise sans init ou dealloc et libère le son après l'avoir joué:

- (void)playSound:(NSURL *)url
    SystemSoundID ssID = 0;
    AudioServicesCreateSystemSoundID((CFURLRef)url, &ssID);
    AudioServicesAddSystemSoundCompletion(ssID, NULL, NULL, (AudioServicesSystemSoundCompletionProc)MyAudioServicesSystemSoundCompletionProc, NULL);
    AudioServicesPlaySystemSound(ssID);
    //AudioServicesDisposeSystemSoundID(ssID);
}

void MyAudioServicesSystemSoundCompletionProc (SystemSoundID  ssID, void *clientData) {
    AudioServicesDisposeSystemSoundID(ssID);
}
4
Conor

Utilisation de Swift 4

import AudioToolbox

func playSoundEasy(note : String) {
    var soundURL: NSURL?
    var soundID: SystemSoundID = 0

    let filePath = Bundle.main.path(forResource: note, ofType: "wav")
    soundURL = NSURL(fileURLWithPath: filePath!)
    if let url = soundURL {
        AudioServicesCreateSystemSoundID(url, &soundID)
        AudioServicesPlaySystemSound(soundID)
    }
}
2
VictorSimplify

Voici une méthode de nettoyage rapide que vous pouvez copier et utiliser dans votre application:

-(BOOL) playSoundFXnamed: (NSString*) vSFXName Loop: (BOOL) vLoop
{
    NSError *error;

    NSBundle* bundle = [NSBundle mainBundle];

    NSString* bundleDirectory = (NSString*)[bundle bundlePath];

    NSURL *url = [NSURL fileURLWithPath:[bundleDirectory stringByAppendingPathComponent:vSFXName]];

    AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];

    if(vLoop)
        audioPlayer.numberOfLoops = -1;
    else
        audioPlayer.numberOfLoops = 0;

    BOOL success = YES;

    if (audioPlayer == nil)
    {
        success = NO;
    }
    else
    {
        success = [audioPlayer play];
    }
    return success;
}

Ensuite, pour utiliser simplement:

[self playSoundFXnamed:@"someAudio.mp3" Loop: NO];

Si vous voulez faire une boucle, vous devez prendre votre AVAudioPlayer *audioPlayer dans votre classe pour pouvoir arrêter le son .. Ce que vous n’aimez pas si vous voulez juste un son bref.

Utilisez ARC ... et je n'ai jamais rien fait avec NSError, alors utilisez-le si vous le souhaitez ...

2
Andres Canella

Beaucoup de réponses prêtent à confusion, et certaines utilisent le framework AudioToolbox, différent du framework AVAudioFoundation ... voici ce que j'ai fait. Dans le fichier .h, J'ai mis ce code dans:

@property (nonatomic, retain) AVAudioPlayer *player;

Ce code déclare un lecteur audio nommé "lecteur". Dans le fichier .m, Sous votre déclaration @implementation, Ajoutez @synthesize player. Ceci synthétise cette propriété player.

Dans la fonction de votre choix, associez votre son au lecteur en ajoutant cette ligne de code, où yourSound est le nom du fichier audio et aif, votre extension de fichier:

player = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"yourSound" withExtension:@"aif"] error:nil]

Je connais le Apple La documentation dit de déclarer une chaîne et un NSURL, mais si vous le combinez en une seule ligne, vous ne serez pas obligé de le supprimer par la suite. En outre, puisqu'il s'agit d'un bien dans votre fichier ViewController.m, vous n’aurez plus à choisir cet objet player pour vous connecter à votre son.

D'autres réponses incluent également l'utilisation de SystemSoundID, mais cela impose également des restrictions telles que "le fichier ne peut pas durer plus de 30 secondes", "il doit être dans un format spécifique" et les travaux. Avec cela, il peut jouer plusieurs sons à la fois (si vous développez une table d'harmonie), et il est plus facile de créer les sons.

Pour jouer votre son, insérez cette ligne (et oui, c’est aussi simple que cela):

[player play]

Si vous utilisez ARC, vous ne pouvez pas vous débarrasser manuellement du lecteur, car le système le fera pour vous. Si vous débutez dans le développement et que vous utilisez la dernière version de Xcode, ARC est activé. Si, pour une raison étrange, vous ne le faites pas, le code de destruction des ressources utilisées par player est le suivant:

[player release]

1
DDPWNAGE

De le son ne fonctionne que sur l'appareil mais pas dans le simulateur

Nick a créé une bibliothèque qui peut être utilisée pour jouer des sons dans iOS et Mac Apps.

Voir nicklockwood/SoundManager

0
Besi

Veuillez vous référer à Lecture audio iOS simple

- (void)playSound
{
    SystemSoundID soundId;

//    NSURL *soundURL = [[NSBundle mainBundle] URLForResource:@"sample"
//                                              withExtension:@"caf"];
//    AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &soundId);

    NSString *path = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"mp3"];
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &soundId);
    AudioServicesAddSystemSoundCompletion(soundId,
                                      NULL,
                                      NULL,
                                      systemAudioCallback,
                                      NULL);
    AudioServicesPlaySystemSound(soundId);
    //AudioServicesPlayAlertSound(soundId);
}

- (void) systemAudioCallback(SystemSoundID soundId, void *clientData)
{
    AudioServicesRemoveSystemSoundCompletion(soundId);
    AudioServicesDisposeSystemSoundID(soundId);
}
0
lmnbeyond