【问题标题】:PlaySystemSound with mute switch onPlaySystemSound 静音开关打开
【发布时间】:2011-03-04 18:19:54
【问题描述】:

我知道,我必须将AudioSession 设置为“播放”类别,即使在静音开关打开时也允许播放音频。我就是这样做的,但是打开开关时声音仍然会静音。

 UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
 AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,sizeof(sessionCategory), &sessionCategory);

 SystemSoundID soundID;
 NSString *path = [[NSBundle mainBundle] pathForResource:soundString ofType:@"wav"];    

 AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path],&soundID);
 AudioServicesPlaySystemSound (soundID);


编辑:顺便说一句,该应用程序是一个音板。播放声音是应用程序的唯一目的。以下是 Apple Doc 对此的评价:

将此类别用于应用程序 其音频播放是主要的 重要性。您的音频甚至可以播放 屏幕锁定并使用 响铃/静音开关设置为静音。


编辑 2:打开静音开关后,声音甚至无法通过耳机播放。 我知道用户为王。我知道静音开关有它的用途。那不是问题。我试图回答将AudioSession 类别设置为kAudioSessionCategory_MediaPlayback 并没有预期的结果。


编辑 3:按照 Jonathan Watmough 的建议,我设置了 AudioServices kAudioServicesPropertyIsUISound 属性,但仍然没有运气。我错过了什么吗?

// set the session property
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,sizeof(sessionCategory), &sessionCategory);

// creates soundID
SystemSoundID soundID;
NSString *path = [[NSBundle mainBundle] pathForResource:soundString ofType:@"wav"];    
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path],&soundID);

// Jonathan Watmough suggestion
UInt32 flag = 0;
AudioServicesSetProperty(kAudioServicesPropertyIsUISound, sizeof(UInt32), &soundID, sizeof(UInt32), &flag);

AudioServicesPlaySystemSound (soundID);

【问题讨论】:

  • 当用户将手机静音时播放声音似乎是完全恶意的。如果系统级别的东西不这样做,为什么你的应用程序应该这样做。除非你的应用是“核反应堆熔毁警告”,否则我认为没有理由允许你的应用用噪音打断会议、婚礼或葬礼。
  • 来自 Apple Doc:“将此类别用于音频播放至关重要的应用程序。即使屏幕锁定且铃声/静音开关设置为静音,您的音频也会播放。”跨度>
  • 那么对你来说什么是最重要的?我猜在一天结束的时候他们已经打开了你的应用程序,因为我忘记了你的应用程序在没有他们打开它的情况下无法执行操作,但即使他们将手机静音并且没有收到看似想要的行为的噪音,它仍然可以执行。
  • 我会尊重用户的意愿。坐下来考虑一下,当我将电话静音时键盘发出噪音是不正确的行为。
  • 在某些情况下,使用静音开关播放声音确实很好,Sam 的情况似乎就是其中之一。如果用户执行操作的目的是播放声音或音乐,那么无论静音开关是打开还是关闭都似乎完全没问题。这是 iPod 应用程序的行为。

标签: iphone audio audiosession


【解决方案1】:

我正在使用下面的代码来解决我的问题

AudioSessionInitialize(NULL, NULL, NULL, NULL); UInt32   
sessionCategory = kAudioSessionCategory_MediaPlayback;    
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,sizeof(sessionCategory),
&sessionCategory); AudioSessionSetActive(YES);

【讨论】:

    【解决方案2】:

    补充一下 Jonathan Watmough 的回答,确实似乎不可能让 AudioServicesSystemSound 覆盖静音开关。我最终做的是使用 OpenAL 来播放声音,这将在您指定的音频会话类别之后正常播放。以下是我设置音频会话的方法:

    AudioSessionInitialize(NULL, NULL, NULL, NULL);
    UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,sizeof(sessionCategory), &sessionCategory);
    AudioSessionSetActive(YES);
    

    为了播放声音,我使用了Finch,这是一个简单的基于 OpenAL 的 iPhone 音效播放器。

    【讨论】:

    • 感谢您的回答。我做了一个测试,你是对的,使用 Finch 使用 OpenAL 可以让你播放声音,即使使用 kAudioSessionCategory_MediaPlayback 设置了静音(如该常量的文档中所述)。
    【解决方案3】:

    我在文档中找不到明确提到它,但我希望 AudioServicesPlaySystemSound() 会忽略您的音频会话配置。

    如果你想控制会话混合和其他属性,你需要使用 AVAudioPlayer 来代替,例如:

    NSError *err;
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayback error:&err];
    [session setActive:YES error:&err];
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Basso" ofType:@"aiff"];    
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&err];
    [player prepareToPlay];
    [player play];
    

    【讨论】:

    • 我正在播放不应该用 AVAudioPlayer 播放的超短声音。 AudioServicesPlaySystemSound 或 OpenAL 是 2 个适合播放短声音的声音引擎。
    • 好吧,您不能使用 AudioServicesPlaySystemSound,因为“系统”将控制会话混合选项,包括静音。我看不出有什么办法可以规避这一点,尽管有时这样做会很方便。
    【解决方案4】:

    您在某处为 AVAudioSession 调用 setActive:error: 对吗?这是我用来初始化的代码。但我没有使用系统声音,我使用 AVAudioPlayer 播放声音。

    avSession = [AVAudioSession sharedInstance];    // init session, important
    
    // allow other audio to mix, such as iPod
    const UInt32 categoryProp = kAudioSessionCategory_MediaPlayback;
    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(categoryProp), &categoryProp);
    
    UInt32 category = kAudioSessionCategory_MediaPlayback;
    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);
    
    // Allow our audio to mix with any iPod audio that is playing
    AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(setProperty_YES), &setProperty_YES);
    
    [avSession setActive:YES error:nil];
    

    【讨论】:

      【解决方案5】:

      我还没有尝试过,但您可能想更改加载声音的属性:

      kAudioServicesPropertyIsUISound 一个 UInt32 值,其中 1 表示,对于 inSpecifier 参数中传递的系统声音指定的音频文件,系统声音服务器尊重用户在 Sound Effects 首选项中的设置,并在用户关闭音效时静音。 此属性默认设置为 1。 将其设置为 0 以便系统声音在传递给 AudioServicesPlaySystemSound 时始终播放,而不管用户在声音首选项中的设置如何。 适用于 iPhone OS 2.0 及更高版本。 在 AudioServices.h 中声明。

      我希望在完成所有其他操作后,将该属性设置为 0 会告诉系统您的声音是应用程序声音,而不是“UI”声音,因此会静音。

      编辑:看起来它不能用系统声音来完成。如果你通过 OpenAL,你显然可以设置静音按钮来玩。

      我构建了 SysSound 示例,并添加了以下代码来设置标志,就像您在上面所做的那样,它根本不会在静音时播放。

       // Set the sound to always play
          int setTo0 = 0;
          AudioServicesSetProperty( kAudioServicesPropertyIsUISound,0,nil,
                                   4,&setTo0 );

      【讨论】:

      • 以为是这样,但不是 :( 请参阅我原帖中的编辑 3
      • 是的,我就是这么想的。请强调无法使用 SystemSound 完成的答案(建议使用 OpenAL),以便我接受您的答案。非常感谢您的帮助!
      • 此代码错误。您需要传递一个 SystemSoundID 作为第二个和第三个参数。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-21
      • 2012-07-27
      • 1970-01-01
      • 2011-09-14
      • 2017-09-24
      • 2014-11-30
      相关资源
      最近更新 更多