Best ways to play simple sound effect in iOS

前端 未结 5 563
野性不改
野性不改 2020-11-30 01:54

I\'m finding a number of conflicting data about playing sounds in iOS. What is a recommended way to play just a simple \"ping\" sound bite every time the user touches the sc

相关标签:
5条回答
  • 2020-11-30 02:31

    Here's an updated answer for Swift (4):

    import AudioToolbox
    
    func playSound() {
        var soundId: SystemSoundID = 0
        guard let soundPath = Bundle.main.url(forResource: "Success7", withExtension: "wav") else {
            print("Error finding file")
            return
        }
    
        let error = AudioServicesCreateSystemSoundID(soundPath as CFURL, &soundId)
        if error != kAudioServicesNoError {
            print("Error loading sound")
            return
        }
    
        AudioServicesPlaySystemSoundWithCompletion(soundId) {
            AudioServicesDisposeSystemSoundID(soundId)
        }
    }
    

    If you have a sound effect that you want to play multiple times in a view, then you can be a little more smart about loading and disposing of the audio:

    class YourViewController: UIViewController {
        fileprivate lazy var soundId: SystemSoundID? = {
            guard let soundPath = Bundle.main.url(forResource: "Success7", withExtension: "wav") else {
                return nil
            }
    
            var soundId: SystemSoundID = 0
            let error = AudioServicesCreateSystemSoundID(soundPath as CFURL, &soundId)
            if error != kAudioServicesNoError {
                return nil
            }
    
            return soundId
        }()
    
        func playScannedSound() {
            guard let soundId = self.soundId else {
                return
            }
    
            AudioServicesPlaySystemSoundWithCompletion(soundId, nil)
        }
    
        deinit {
            guard let soundId = self.soundId else {
                return
            }
            AudioServicesDisposeSystemSoundID(soundId)
        }
    
    }
    
    0 讨论(0)
  • 2020-11-30 02:35

    This is the best way of playing a simple sound in iOS (no more than 30 seconds):

    //Retrieve audio file
    NSString *path  = [[NSBundle mainBundle] pathForResource:@"soundeffect" ofType:@"m4a"];
    NSURL *pathURL = [NSURL fileURLWithPath : path];
    
    SystemSoundID audioEffect;
    AudioServicesCreateSystemSoundID((__bridge CFURLRef) pathURL, &audioEffect);
    AudioServicesPlaySystemSound(audioEffect);
    
    // call the following function when the sound is no longer used
    // (must be done AFTER the sound is done playing)
    AudioServicesDisposeSystemSoundID(audioEffect);
    
    0 讨论(0)
  • 2020-11-30 02:37

    You can use AVFoundation or AudioToolbox.

    Here're two examples which use the libraries separately.

    • SAMSoundEffect (archived repository)
    • BRYSoundEffectPlayer
    0 讨论(0)
  • 2020-11-30 02:51

    I use this:

    Header file:

    #import <AudioToolbox/AudioServices.h>
    
    @interface SoundEffect : NSObject
    {
        SystemSoundID soundID;
    }
    
    - (id)initWithSoundNamed:(NSString *)filename;
    - (void)play;
    
    @end
    

    Source file:

    #import "SoundEffect.h"
    
    @implementation SoundEffect
    
    - (id)initWithSoundNamed:(NSString *)filename
    {
        if ((self = [super init]))
        {
            NSURL *fileURL = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
            if (fileURL != nil)
            {
                SystemSoundID theSoundID;
                OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)fileURL, &theSoundID);
                if (error == kAudioServicesNoError)
                    soundID = theSoundID;
            }
        }
        return self;
    }
    
    - (void)dealloc
    {
        AudioServicesDisposeSystemSoundID(soundID);
    }
    
    - (void)play
    {
        AudioServicesPlaySystemSound(soundID);
    }
    
    @end
    

    You will need to create an instance of SoundEffect and direct call the method play on it.

    0 讨论(0)
  • 2020-11-30 02:53

    (Small amendment to the correct answer to take care of the disposing of the audio)

    NSString *path  = [[NSBundle mainBundle] pathForResource:@"soundeffect" ofType:@"m4a"];
    NSURL *pathURL = [NSURL fileURLWithPath : path];
    
    SystemSoundID audioEffect;
    AudioServicesCreateSystemSoundID((__bridge CFURLRef) pathURL, &audioEffect);
    AudioServicesPlaySystemSound(audioEffect);
    // Using GCD, we can use a block to dispose of the audio effect without using a NSTimer or something else to figure out when it'll be finished playing.
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        AudioServicesDisposeSystemSoundID(audioEffect);
    });
    
    0 讨论(0)
提交回复
热议问题