在iOS中播放短音

时间:2012-04-26 07:52:37

标签: ios audio

我想我可以使用AVAudioPlayer来播放声音,但是,我需要的是播放一个简短的声音,我不需要任何循环或对音量等进行细粒度控制。

有一种简单的方法吗?

13 个答案:

答案 0 :(得分:88)

其他答案中的每一个都会泄漏内存(除非为一个答案启用ARC)...奇怪的是,最初标记为正确的答案可以调用retainCount没有明显的理由。

如果您alloc/init某事,则需要释放它(除非您使用ARC)。

如果你致电AudioServicesCreateSystemSoundID(),你必须处理产生的声音。

请参阅Audio UI Sounds示例。

基本上:

@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

完整性:
添加AudioToolbox.framework
#import <AudioToolbox/AudioToolbox.h>

答案 1 :(得分:43)

对于短声音片段(少于30秒),有一个非常好的SystemSounds库。

优点: 您无需单独管理卷设置。声音在一个单独的线程中播放,加载和播放音频片段的速度很快。简而言之,您将此剪辑视为另一种系统声音。

缺点:您无法提供单独的音频控制设置。它与系统声音的设置有关。你玩的时间不能超过30秒。您可能无法应用任何声音滤镜来增强音频效果。

肯定有更多的优点和缺点,但这些是我能想到的,我的头脑。

使用此导入:<AudioToolbox/AudioToolbox.h> 添加AudioToolbox框架 然后调用下面的方法,如[self playSound],无论你想在哪里播放剪辑。

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

答案 2 :(得分:23)

夫特

这里的其他答案使用Objective-C,所以我在这里提供Swift版本。 Swift使用自动引用计数(ARC),所以我不知道这个答案有任何内存泄漏问题(正如在接受的答案中所警告的那样)。

使用AudioToolbox

当你不需要太多控制它们的播放时,你可以使用AudioToolbox框架播放短音。

以下是设置方法:

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

注意:

  • 此示例改编自How to play a short sound clip with AudioToolbox in Swift
  • 请务必将yourAudioFileName.mp3(或.wav等)添加到您的项目中。
  • 请记住import AudioToolbox
  • 这个答案将代码放在IBAction按钮中,但当然可以很容易地将其放入另一个功能中。

使用AVAudioPlayer

通过导入AVFoundation框架,您可以使用AVAudioPlayer。它适用于短音频剪辑和长歌。与使用AudioToolbox方法相比,您还可以更好地控制播放。

以下是设置方法:

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

注意:

答案 3 :(得分:17)

最近,我用这段代码播放了很好的短mp3音频: -

在@implementation

下面声明
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

答案 4 :(得分:9)

我使用此代码在iOS上播放简短的aiff-sound

#import <AudioToolbox/AudioServices.h> 

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

希望这有帮助。

答案 5 :(得分:6)

SIMPLE CLEAN SWIFT 3 VERSION

我更喜欢控制我的声音所以我正在使用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()
  }
}

确保声音文件已添加到项目中并导入AVFoundation。

答案 6 :(得分:4)

我的答案是比尔的回答,但我在没有初始化或dealloc的情况下使用它并在播放后释放声音:

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

答案 7 :(得分:2)

这是一种快速清理方法,可以复制并在您的应用中使用:

-(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;
}

然后只使用:

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

如果你要循环,那么你需要把你的AVAudioPlayer *audioPlayer带到你的班级,以便能够停止声音。如果你只是想要一个短暂的声音你就不会这样做。

使用ARC ......我从未对NSError做任何事情,所以如果你喜欢......

,请使用它

答案 8 :(得分:2)

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

答案 9 :(得分:1)

许多答案令人困惑,有些人正在使用AudioToolbox框架,与AVAudioFoundation框架不同......这就是我所做的。在.h文件中,我将此代码放在:

@property (nonatomic, retain) AVAudioPlayer *player;

此代码声明一个名为“播放器”的音频播放器。在.m文件的@implementation声明下,添加@synthesize player。这合成了player属性。

在您想要的任何功能中,通过添加以下代码行将声音绑定到播放器,其中yourSound是声音文件的名称,aif是您的文件扩展名:

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

我知道Apple文档声明要声明字符串和NSURL,但是如果将它组合成一行,那么之后就不必处理它了。此外,由于这是ViewController.m文件中的属性,因此您无需将player对象设置为与声音相关联。

其他答案也包括使用SystemSoundID,但也施加了限制,例如“文件不能超过30秒”,“它必须采用特定格式”,以及作品。有了它,它可以一次播放几个声音(如果你正在开发一个音板),并且更容易创建声音。

要实际播放你的声音,请插入此行(是的,这真的很容易):

[player play]

如果您使用ARC,则无法手动处理播放器,因为系统会为您执行此操作。如果您刚开发并且使用的是最新版本的Xcode,那么您已启用ARC。如果由于某些奇怪的原因,您没有,那么处理player正在使用的资源的代码是:

[player release]

答案 10 :(得分:0)

来自Sound does only work on Device but not in Simulator

Nick创建了一个可用于在iOS和Mac应用中播放声音的库。

请参阅nicklockwood/SoundManager

答案 11 :(得分:0)

请参阅Simple iOS audio playback

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

答案 12 :(得分:-1)

查看systemound播放短音频文件

包括audiotoolbox框架

并创建

systemsoundid对象

NSString *soundPath =  [[NSBundle mainBundle] pathForResource:file ofType:@"aiff"];
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath: soundPath], &soundID);
AudioServicesPlaySystemSound (soundID);