Лучший способ воспроизвести простой звуковой эффект в iOS - PullRequest
20 голосов
/ 20 марта 2012

Я нахожу ряд противоречивых данных о воспроизведении звуков в iOS.Мне было интересно, может ли кто-нибудь указать мне лучший способ играть простой звук пинга каждый раз, когда пользователь касается экрана.

Спасибо!

Ответы [ 5 ]

29 голосов
/ 21 марта 2012

Я использую это:

Заголовочный файл:

#import <AudioToolbox/AudioServices.h>

@interface SoundEffect : NSObject
{
    SystemSoundID soundID;
}

- (id)initWithSoundNamed:(NSString *)filename;
- (void)play;

@end

Исходный файл:

#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

Вам потребуется создать экземпляр SoundEffect и напрямую вызвать метод play на нем.

25 голосов
/ 20 марта 2012

Это лучший способ воспроизведения простого звука в iOS (не более 30 секунд):

//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);
10 голосов
/ 20 апреля 2014

(Небольшая поправка к правильному ответу, чтобы позаботиться об утилизации аудио)

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);
});
2 голосов
/ 16 сентября 2014

Вы можете использовать AVFoundation или AudioToolbox

Вот два примера использования библиотек отдельно.

0 голосов
/ 01 марта 2019

Вот обновленный ответ для 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)
    }
}

Если у вас есть звуковой эффект, который вы хотите воспроизвести несколько раз в виде, тогда вы можете быть немного более умным в отношении загрузки иудаление аудио:

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)
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...