Керування аудіовиходами в iOS за допомогою Swift є ключовим аспектом розробки аудіо-орієнтованих додатків. Ця стаття детально розглядає, як програмісти можуть маніпулювати аудіосесіями для досягнення бажаних результатів у відтворенні аудіо через різні аудіовиходи.
AVAudioSession
є центральним компонентом у роботі з аудіо в iOS, що дозволяє додаткам взаємодіяти з аудіосистемою операційної системи. Встановлення правильної категорії аудіосесії є критично важливим для того, щоб аудіо відтворювалось коректно, враховуючи інші аудіопроцеси в системі.
1 2 3 4 5 6 7 |
do { try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default) try AVAudioSession.sharedInstance().setActive(true) print("Audio session category set to playback") } catch { print("Failed to set audio session category: \(error)") } |
Категорія .playback
забезпечує можливість відтворення аудіо, коли додаток не є активним на передньому плані, тобто в фоновому режимі.
Для додатків, що потребують відтворення аудіо через внутрішній динамік телефону, а не через зовнішній гучномовець, Swift надає механізми керування вихідним аудіопотоком.
За замовчуванням, встановлення категорії аудіосесії на .playback
може відтворювати аудіо через зовнішній гучномовець. Щоб відтворення відбувалось через внутрішній динамік, потрібно спеціально не вказувати системі перенаправляти аудіо на гучномовець:
1 2 |
// Активування внутрішнього динаміка за замовчуванням //try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker) |
AVAudioEngine
є потужним інструментом для обробки аудіосигналу в реальному часі. Використовуючи AVAudioEngine
разом з AVAudioPlayerNode
, можна створювати комплексні аудіоаплікації, які потребують відтворення, захоплення або трансформації аудіо.
1 2 3 4 5 6 7 8 9 10 11 12 |
var audioEngine: AVAudioEngine! var audioPlayerNode: AVAudioPlayerNode! audioEngine = AVAudioEngine() audioPlayerNode = AVAudioPlayerNode() audioEngine.attach(audioPlayerNode) audioEngine.connect(audioPlayerNode, to: audioEngine.mainMixerNode, at: nil, format: nil) do { try audioEngine.start() print("Audio engine started") } catch { print("Could not start audio engine: \(error)") } |
Такий підхід дозволяє гнучко інтегрувати аудіопотік з різними частинами аудіосистеми і забезпечує високий рівень контролю над відтворенням.
При роботі з аудіо, отриманим через мережеві сокети, важливо забезпечити правильну обробку та відтворення даних. GCDAsyncUdpSocket
надає асинхронний інтерфейс для роботи з UDP сокетами, що ідеально підходить для передачі аудіоданих в реальному часі.
func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
let audioBuffer = getAudioBuffer(with: data)
audioPlayerNode.scheduleBuffer(audioBuffer, completionHandler: nil)
}
func getAudioBuffer(with data