Как разрешить фоновой музыке продолжать играть, пока мое приложение все еще воспроизводит звуки при использовании Swift
Я создал приложение, и я пытаюсь разрешить пользователю продолжать слушать их музыку во время игры, но всякий раз, когда они нажимают "играть", и появляются звуки игры, это останавливает фоновую музыку. Я разрабатываю iOS с помощью Swift. Вот фрагмент кода, который инициирует игровые звуки.
func playSpawnedDot() {
var alertSound: NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("spawnDot", ofType: "mp3")!)!
var error:NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error)
audioPlayer.prepareToPlay()
if volumeBool {
audioPlayer.play()
}
}
Ответы
Ответ 1
Вам нужно установить категорию AVAudioSession
с одним из следующих значений: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/index.html (ссылка на класс AVAudioSession).
Значение по умолчанию равно AVAudioSessionCategorySoloAmbient
. Как вы можете прочитать:
[...], используя эту категорию, подразумевает, что звук ваших приложений не микшируется - активация сеанса прерывает любые другие сеансы аудио, которые также не смешиваются. Чтобы разрешить микширование, используйте категорию AVAudioSessionCategoryAmbient
.
Вы должны изменить категорию перед воспроизведением звука. Для этого:
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
Вам не нужно вызывать эту строку каждый раз, когда вы воспроизводите звук. Возможно, вы захотите сделать это только один раз.
Ответ 2
Вот что я использую для Swift 2.0:
let sess = AVAudioSession.sharedInstance()
if sess.otherAudioPlaying {
_ = try? sess.setCategory(AVAudioSessionCategoryAmbient, withOptions: .DuckOthers)
_ = try? sess.setActive(true, withOptions: [])
}
Обратите внимание, что вы можете заменить .DuckOthers
на []
, если вы не хотите опускать фоновую музыку и вместо этого играть сверху.
Ответ 3
Вот как я это делаю в Swift 3.0
var songPlayer : AVAudioPlayer?
func SetUpSound() {
if let path = Bundle.main.path(forResource: "TestSound", ofType: "wav") {
let filePath = NSURL(fileURLWithPath:path)
songPlayer = try! AVAudioPlayer.init(contentsOf: filePath as URL)
songPlayer?.numberOfLoops = -1 //logic for infinite loop
songPlayer?.prepareToPlay()
songPlayer?.play()
}
let audioSession = AVAudioSession.sharedInstance()
try!audioSession.setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.duckOthers) //Causes audio from other sessions to be ducked (reduced in volume) while audio from this session plays
}
Здесь вы можете увидеть больше AVAudioSessionCategoryOptions: https://developer.apple.com/reference/avfoundation/avaudiosessioncategoryoptions
Ответ 4
версия Swift 4:
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try? AVAudioSession.sharedInstance().setActive(true)
Ответ 5
**
Обновлен для Swift 3.0
**
Название звука, в котором я играю, - shatter.wav
func shatterSound() {
if let soundURL = Bundle.main.url(forResource: "shatter", withExtension: "wav") {
var mySound: SystemSoundID = 0
AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound)
AudioServicesPlaySystemSound(mySound);
}
}
Затем, когда вы хотите воспроизвести звуковой вызов
shatterSound()
Ответ 6
lchamp решение отлично работает для меня, адаптировано для Objective-C:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
Ответ 7
Если вы хотите воспроизвести звуковой сигнал:
public func playSound(withFileName fileName: String) {
if let soundUrl = Bundle.main.url(forResource: fileName, withExtension: "wav") {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, with:[.duckOthers])
try AVAudioSession.sharedInstance().setActive(true)
var soundId: SystemSoundID = 0
AudioServicesCreateSystemSoundID(soundUrl as CFURL, &soundId)
AudioServicesAddSystemSoundCompletion(soundId, nil, nil, { (soundId, clientData) -> Void in
AudioServicesDisposeSystemSoundID(soundId)
do {
// This is to unduck others, make other playing sounds go back up in volume
try AVAudioSession.sharedInstance().setActive(false)
} catch {
DDLogWarn("Failed to set AVAudioSession to inactive. error=\(error)")
}
}, nil)
AudioServicesPlaySystemSound(soundId)
} catch {
DDLogWarn("Failed to create audio player. soundUrl=\(soundUrl) error=\(error)")
}
} else {
DDLogWarn("Sound file not found in app bundle. fileName=\(fileName)")
}
}
И если вы хотите играть музыку:
импортировать AVFoundation
var audioPlayer:AVAudioPlayer?
public func playSound(withFileName fileName: String) {
if let soundUrl = Bundle.main.url(forResource: fileName, withExtension: "wav") {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, with:[.duckOthers])
try AVAudioSession.sharedInstance().setActive(true)
let player = try AVAudioPlayer(contentsOf: soundUrl)
player.delegate = self
player.prepareToPlay()
DDLogInfo("Playing sound. soundUrl=\(soundUrl)")
player.play()
// ensure the player does not get deleted while playing the sound
self.audioPlayer = player
} catch {
DDLogWarn("Failed to create audio player. soundUrl=\(soundUrl) error=\(error)")
}
} else {
DDLogWarn("Sound file not found in app bundle. fileName=\(fileName)")
}
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
self.audioPlayer?.stop()
do {
// This is to unduck others, make other playing sounds go back up in volume
try AVAudioSession.sharedInstance().setActive(false)
} catch {
DDLogWarn("Failed to set AVAudioSession inactive. error=\(error)")
}
}
Ответ 8
Для Swift (Objective-C как это тоже)
вы можете использовать эту ссылку для получения наилучшего ответа, и если у вас нет времени для просмотра 10 минут, лучшим действием является то, что вы просто copy
ниже кода в AppDelegate
в didFinishLaunchingWithOptions
, а затем выберите project target
, затем перейдите к Capabilities
и, наконец, в Background modes
установите флажок Audio, AirPlay and Picture in Picture
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(AVAudioSessionCategoryPlayback)
}
catch {
}
}