【问题标题】:Stop a sound Before PLaying another在播放另一个声音之前停止一个声音
【发布时间】:2012-02-11 21:08:28
【问题描述】:

我知道以前在这里有人问过这个问题,但我不明白回复。我正在制作一个音板,当您单击其中一个按钮播放声音时,我希望已经播放的那个停止。我知道我需要添加AudioServicesDisposeSystemSoundID(soundID);,但是我在哪里添加呢?这是我的代码:

- (IBAction)beyond:(id)sender {
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =  CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"beyond" ,CFSTR ("wav") , NULL);
    UInt32 soundID;
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
   }

- (IBAction)Years:(id)sender {
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =  CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"years" ,CFSTR ("wav") , NULL);
    UInt32 soundID;
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
   }

【问题讨论】:

  • 在不知道用户界面是什么样子的情况下,您的方法名称是难以理解的。为什么你的 IBAction 方法被命名为“beyond”和“Years”?
  • Beyond 和 Years 是播放的声音和按钮的名称。

标签: objective-c ios cocoa-touch


【解决方案1】:

这里的问题是您将 soundID 定义为方法中的局部变量,而不是类中的实例变量。当您使用实例变量时,您可以稍后从类中的任何方法访问它。

【讨论】:

  • 查看 NJones 的答案。这是一个相当基本的面向对象编程概念;我鼓励您查看一些有关面向对象编程的文档。如果你打算用 Objective-C 做很多工作,我个人推荐 Big Nerd Ranch 的 Objective-C 和 iOS 编程书籍。
【解决方案2】:

正如布尼利所说。您需要创建一个实例变量(或 ivar),以便多个方法可以引用同一个变量。正如您已经知道的那样,AudioServicesDisposeSystemSoundID() 会停止当前播放的SystemSoundID。一旦你声明了一个 ivar,你就不需要在每个方法中声明变量。所以合乎逻辑的结论是。

@implementation ViewControllerClassNameHere{
    SystemSoundID soundID;
}
- (IBAction)beyond:(id)sender {
    AudioServicesDisposeSystemSoundID(soundID);
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =  CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"beyond" ,CFSTR ("wav") , NULL);
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
}
- (IBAction)Years:(id)sender {
    AudioServicesDisposeSystemSoundID(soundID);
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =  CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"years" ,CFSTR ("wav") , NULL);
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
}

创建SystemSoundID 后,您可能(肯定会)想要CFRelease() 复制CFURLRefs(这样您就不会泄漏内存)。事实上,您可能会考虑制作您的CFURLRefs ivars,以免不断复制它们。您可能还想在dealloc 中致电AudioServicesDisposeSystemSoundID(soundID);

【讨论】:

    【解决方案3】:

    之前回答过: Stopping sound in Xcode

    但我可以重复我的答案。

    总结一下,停止声音文件的句子是:

    AudioServicesDisposeSystemSoundID (soundFileObject);
    

    解释(重要理解):

    我有一个包含 18 个不同声音文件的表格视图。当用户选择一行时必须发出相应的文件,并且在选择另一行时,它必须停止前一个声音并播放其他。

    所有这些东西都是必需的:

    1) 在“Build Phases”内的“Link Binary With Libraries”内添加到您的项目“AudioToolbox.framework”

    2) 在头文件(在我的项目中它称为“GenericTableView.h”)中添加以下句子:

    #include <AudioToolbox/AudioToolbox.h>
    
    CFURLRef soundFileURLRef;
    SystemSoundID soundFileObject;
    
    @property (readwrite) CFURLRef soundFileURLRef;
    @property (readonly) SystemSoundID soundFileObject;
    

    3) 在实现文件中(在我的项目中它称为“GenericTableView.m”)添加以下语句:

    @synthesize soundFileURLRef;
    @synthesize soundFileObject;
    

    在你的“Action”实现中,或者在我的例子中,在:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    // -----------------------------------------------------------------------
    // -----------------------------------------------------------------------
    // -----------------------------------------------------------------------
    //
    // That is the question: a way to STOP sound file
    //
    // -----------------------------------------------------------------------
    // Very important to STOP the sound file
    AudioServicesDisposeSystemSoundID (soundFileObject);
    
    // -----------------------------------------------------------------------
    // -----------------------------------------------------------------------
    // -----------------------------------------------------------------------
    
    
    // In my project "rowText" is a field that save the name of the 
    // corresponding sound (depending on row selected)
    // It can be a string, @"Alarm Clock Bell" in example
    
    // Create the URL for the source audio file.
    // URLForResource:withExtension: method is new in iOS 4.0.
    NSURL *soundURL = [[NSBundle mainBundle] URLForResource:rowText withExtension:@"caf"];
    
    // Store the URL as a CFURLRef instance
    self.soundFileURLRef = (CFURLRef) [soundURL retain];
    
    // Create a system sound object representing the sound file.
    AudioServicesCreateSystemSoundID (soundFileURLRef,&soundFileObject);
    
    AudioServicesPlaySystemSound (soundFileObject);
    
    [soundURL release];
    }
    

    4) 最后,在同一个实现文件中(在我的项目中它称为“GenericTableView.m”):

    - (void)dealloc {
    [super dealloc];
    
    AudioServicesDisposeSystemSoundID (soundFileObject);
    //CFRelease (soundFileURLRef);
    }
    

    我必须评论“CFRelease (soundFileURLRef)”,因为当用户离开表格视图时,应用程序意外结束。

    所有这些代码均由 Apple 按比例分配。在此链接中,您甚至可以找到直接在 iPhone 模拟器中测试的示例代码。

    https://developer.apple.com/library/ios/samplecode/SysSound/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008018-Intro-DontLinkElementID_2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多