【问题标题】:Play a short sound in iOS在 iOS 中播放短声音
【发布时间】:2012-05-06 22:36:32
【问题描述】:

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

有没有简单的方法可以做到这一点?

【问题讨论】:

  • 你可以播放声音作为这个答案stackoverflow.com/a/18958454/2459296
  • "我想我可以使用 AVAudioPlayer..." 你为什么不呢?为什么没有人?使用 AVAudioPlayer 播放声音要容易得多。

标签: ios audio


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    斯威夫特

    这里的其他答案使用了 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
        }
    }
    

    注意事项:

    【讨论】:

    • AudioServicesPlaySystemSound 的一个问题是,如果用户打开静音按钮,则不会播放声音。这在某些方面是有道理的,但根据您的应用程序,用户可能仍然希望听到声音。
    • 非常适合我需要处理的内容。很好地解释了使用 AudioToolbox 或 AVAudioPlayer 的区别。我在我的情况下选择了 AudioToolbox(能够播放来自音频流媒体服务的音乐,同时在我的应用程序中点击的按钮上播放我自己的音效)
    【解决方案3】:

    最近,我用这段代码播放了简短的 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
    

    【讨论】:

    • @bbum:- 是的,在我的情况下它是启用的。当 ARC 未启用时,“玩家”的保留数必须减少。
    • [player setVolume:1.0]; 应该在创建播放器之后出现。
    • "我想我可以使用 AVAudioPlayer 来播放声音,但是,我需要的只是播放一个简短的声音,我不需要任何循环或对音量等的细粒度控制。 "从问题中阅读了这件事后,我认为这个答案不应该在这里..
    • setVolume:1 不是必需的。 1 是新玩家的默认值
    【解决方案4】:

    简单干净的 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。

    【讨论】:

      【解决方案5】:

      请参考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);
      }
      

      【讨论】:

        【解决方案6】:

        很多答案令人困惑,有些正在使用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 对象以与您的声音相关联。

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

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

        [player play]

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

        [player release]

        【讨论】:

          【解决方案7】:

          对于短的声音剪辑(少于 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];
          }
          

          【讨论】:

          • 该代码泄露了声音并且对retainCount 的调用(以及注释的[soundPath release])表明对内存管理有点误解......
          • @Anshu:我就是这样做的,我已经将我的文件转换为aif 文件,但我在模拟器中听不到任何声音......
          • @Besi 检查声音下的系统偏好设置,并确保选中“播放用户界面音效”复选框
          • 使用 AudioServicesDisposeSystemSoundID(SystemSoundID inSystemSoundID);用于释放内存
          【解决方案8】:

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

          #import <AudioToolbox/AudioServices.h> 
          
          SystemSoundID completeSound;
          NSURL *audioPath = [[NSBundle mainBundle] URLForResource:@"downloadCompleted" withExtension:@"aiff"];
          AudioServicesCreateSystemSoundID((CFURLRef)audioPath, &completeSound);
          AudioServicesPlaySystemSound (completeSound);
          

          希望这会有所帮助。

          【讨论】:

          • 我使用iTunes将我的文件从m4a转换为aif,现在我在模拟器中听不到任何声音,你能告诉我你用什么方法进行转换吗?跨度>
          • 我们需要在头文件中导入什么?
          • 虽然您的 aif 可能会复制到您的资源中,但请确保它也列在 Build Sources > Target 中的 Copy Bundle Resources 中
          【解决方案9】:

          我的答案是比尔的答案,但我使用它没有 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);
          }
          

          【讨论】:

            【解决方案10】:

            其他每一个答案都会泄漏内存(除非为 一个 答案启用了 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 &lt;AudioToolbox/AudioToolbox.h&gt;

            【讨论】:

            • 我正在使用 ARC,但由于其他人可能不会,您的回答似乎是合理的。
            • 酷 -- 好 -- ARC 是正确的方法。 :) 我总是特别注意 ARC 的使用,因为我看到太多人以太多简单的方式搞砸了内存管理。
            • 我就是这样做的,我已将我的文件转换为aif 文件,但我在模拟器中听不到任何声音...
            • 使用ARC时,请务必使用__bridge:AudioServicesCreateSystemSoundID((__bridge CFURLRef)mySoundNSURL, &amp;_mySound);
            • 因为粘连在这里很流行:您的示例在NSObject 的子类上调用[super viewDidLoad]。 ;)
            【解决方案11】:

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

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

            nicklockwood/SoundManager

            【讨论】:

              【解决方案12】:

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

              -(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 做过任何事情,所以如果你喜欢就使用它...

              【讨论】:

                【解决方案13】:

                查看 systemsound 以播放短音频文件

                包含音频工具箱框架

                并创建

                systemsoundid 对象

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多