在 iOS 中播放短声音

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10329291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:05:12  来源:igfitidea点击:

Play a short sound in iOS

iosaudio

提问by Besi

I guess I could use AVAudioPlayerto play a sound, however, what I need is to just play a short sound and I don't need any loops or fine-grained control over the volume etc.

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

Is there an easy way to do this?

是否有捷径可寻?

回答by bbum

Every single one of the other answers leaks memory (unless ARC is enabled for oneof the answers)... oddly, the answer originally marked as correct has a call to retainCountfor no apparent reason.

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

If you alloc/initsomething, it needs to be released (unless you are using ARC).

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

If you call AudioServicesCreateSystemSoundID()you have to dispose of the resulting sound.

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

See the Audio UI Soundsexample.

请参阅音频 UI 声音示例。

Basically:

基本上:

@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

For completeness:
add AudioToolbox.framework
#import <AudioToolbox/AudioToolbox.h>

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

回答by Himanshu Singh

For short sound clips (less than 30 secs), there's a SystemSounds library which is really nice.

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

Pros: You don't need to manage volume settings separately. The sound is played in a separate thread and loading and playing of audio clip is v fast. In short, you treat this clip as another system sound.

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

Cons: You can't provide a separate audio control setting. It's tied to the settings of the system sounds. You can't play more than 30 seconds. You probably can't apply any sound filters to enhance audio effect.

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

There are certainly more pros and cons, but these are some I could think of, off the top of my head.

当然有更多的优点和缺点,但这些是我能想到的,在我的脑海中。

use this import: <AudioToolbox/AudioToolbox.h>Add the AudioToolbox Framework then call the below method like [self playSound], wherever you want to play the clip.

使用此导入:<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];
}

回答by Suragch

Swift

迅速

The other answers here use Objective-C so I am providing a Swift version here. Swift uses Automatic Reference Counting (ARC), so I am not aware of any memory leak issues with this answer (as warned about in the accepted answer).

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

Using AudioToolbox

使用音频工具箱

You can use the AudioToolboxframework to play short sounds when you do not need much control over how they are played.

AudioToolbox当您不需要太多控制播放方式时,您可以使用该框架播放短声音。

Here is how you would set it up:

以下是您如何设置它:

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

Notes:

笔记:

  • This example is adapted from How to play a short sound clip with AudioToolbox in Swift.
  • Remember to add yourAudioFileName.mp3(or .wav, etc) to your project.
  • Remember to import AudioToolbox
  • This answer puts the code in an IBAction button tap, but it could just as easily be put in another function, of course.
  • 此示例改编自How to play a short sound clip with AudioToolbox in Swift
  • 请记住将yourAudioFileName.mp3(或.wav等)添加到您的项目中。
  • 记得 import AudioToolbox
  • 这个答案将代码放在 IBAction 按钮点击中,但它当然可以很容易地放在另一个函数中。

Using AVAudioPlayer

使用 AVAudioPlayer

By importing the AVFoundationframework, you can use AVAudioPlayer. It works for both short audio clips and long songs. You also have more control over the playback than you did with the AudioToolbox method.

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

Here is how you would set it up:

以下是您如何设置它:

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

Notes:

笔记:

回答by Arshad Parwez

Recently, I used this code to play short mp3 audio which worked fine:-

最近,我使用此代码播放了运行良好的短 mp3 音频:-

Declare this below the @implementation

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

回答by Schulze Thomas

I used this code to play a short aiff-sound on iOS

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

#import <AudioToolbox/AudioServices.h> 

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

Hope this helps.

希望这可以帮助。

回答by Rob Norback

SIMPLE CLEAN SWIFT 3 VERSION

简单清洁 Swift 3 版本

I like more control over my sounds so I'm using AVFoundation.

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

Make sure you sound file is added to your project and you import AVFoundation.

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

回答by Conor

My answer is Bill's answer, but I use it without init or dealloc and release the sound after it's played:

我的答案是 Bill 的答案,但我在没有 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);
}

回答by VictorSimplify

Using Swift 4

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

回答by Andres Canella

Heres a quick clean method you can copy in and use in your app:

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

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

Then to use just:

然后只使用:

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

If you're gonna loop then you need to take your AVAudioPlayer *audioPlayerout into your class to be able to stop the sound.. Which you dont if you just want a short sound.

如果你要循环,那么你需要把你AVAudioPlayer *audioPlayer的课带到课堂上才能停止声音......如果你只是想要一个短促的声音,你就不需要。

Use ARC... and I never did do anything with the NSError, so use it if ya like...

使用 ARC ......我从来没有对 NSError 做过任何事情,所以如果你喜欢就使用它......

回答by DDPWNAGE

A lot of answers are confusing, and some are using the AudioToolboxframework, different from the AVAudioFoundationframework... here's what I did. In the .hfile, I put this code in:

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

@property (nonatomic, retain) AVAudioPlayer *player;

@property (nonatomic, retain) AVAudioPlayer *player;

This code declares an audio player named "player." In the .mfile, under your @implementationdeclaration, add @synthesize player. This synthesizes that playerproperty.

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

In whatever function you want, tie your sound in to the player by adding this line of code, where yourSoundis the name of the sound file, and aifis your file extension:

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

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

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

I know the Apple Documentation says to declare a string and a NSURL, but if you combine it into one line, then you won't have to dispose of it afterwards. Also, since this is a property in your ViewController.mfile, then you won't have to keep setting that playerobject to tie in with your sound.

我知道 Apple 文档说要声明一个字符串和一个 NSURL,但是如果将其合并为一行,则之后就不必处理它了。此外,由于这是您ViewController.m文件中的一个属性,因此您不必继续设置该player对象以配合您的声音。

Other answers also included using a SystemSoundID, but that also imposes restrictions like, "the file can't be over 30 seconds long," "it has to be in a specific format," and the works. With that, it can play several sounds at a time (in case you're developing a soundboard), and it's easier to create the sounds.

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

To actually play your sound, insert this line (and yes, it's really this easy):

要实际播放您的声音,请插入以下行(是的,这真的很简单):

[player play]

[player play]

If you use ARC, you can't manually dispose of the player, as the system will do it for you. If you're new to developing and you're using the latest version of Xcode, then you have ARC enabled. If, for some strange reason, you don't, then the code for disposing of the resources being used by playeris:

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

[player release]

[player release]