61

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

是否有捷径可寻?

4

13 回答 13

88

其他每一个答案都会泄漏内存(除非为其中一个答案启用了 ARC)......奇怪的是,最初标记为正确的答案retainCount无缘无故地被调用。

如果你有alloc/init什么东西,它需要被释放(除非你使用 ARC)。

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

请参阅音频 UI 声音示例。

基本上:

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

于 2012-04-26T15:53:38.377 回答
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];
}
于 2012-04-26T08:09:11.960 回答
24

迅速

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

使用音频工具箱

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

笔记:

于 2015-10-01T04:24:14.703 回答
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
于 2012-04-26T12:19:19.367 回答
9

我用这段代码在 iOS 上播放了一个简短的 aiff-sound

#import <AudioToolbox/AudioServices.h> 

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

希望这可以帮助。

于 2012-04-26T08:06:45.300 回答
8

简单干净的 Swift 3 版本

我喜欢更多地控制我的声音,所以我使用了 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。

于 2017-05-09T08:58:04.073 回答
5

我的回答是比尔的回答,但我在没有 init 或 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);
}
于 2014-02-28T16:16:45.640 回答
4

使用斯威夫特 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)
    }
}
于 2018-01-09T16:25:10.197 回答
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 做过任何事情,所以如果你喜欢就使用它……

于 2013-01-17T00:16:52.273 回答
1

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

@property (nonatomic, retain) AVAudioPlayer *player;

此代码声明了一个名为“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对象以与您的声音相关联。

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

要真正播放您的声音,请插入这一行(是的,这真的很简单):

[player play]

如果您使用 ARC,则无法手动处理播放器,因为系统会为您处理。如果您是开发新手并且使用的是最新版本的 Xcode,那么您启用了 ARC。如果由于某种奇怪的原因您不这样做,那么用于处理所使用资源的代码player是:

[player release]

于 2015-01-11T01:35:48.387 回答
0

From Sound 仅适用于设备,但不适用于模拟器

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

nicklockwood/SoundManager

于 2013-09-09T12:29:32.407 回答
0

请参考简单的iOS音频播放

- (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);
}
于 2015-07-14T06:35:03.760 回答
-1

查看 systemsound 以播放短音频文件

包括音频工具箱框架

并创建

systemsoundid 对象

NSString *soundPath =  [[NSBundle mainBundle] pathForResource:file ofType:@"aiff"];
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath: soundPath], &soundID);
AudioServicesPlaySystemSound (soundID);
于 2012-04-26T08:11:18.137 回答