I want to play a local mp3 file to a known Airplay-capable speaker in my house. I can bring up the AVRoutePickerView programmatically - but I am more interested in somehow getting a list of known Airplay speakers, loop through looking for my speaker by name, and somehow programmatically selecting it to play my file. Again, this is just for a proof of concept - nothing I would release in the real-world. What is the best way to do this? I looked for ways to hack into the picker to get the list of device and perform a touchUpInside on that device's button, but I have found nothing.
Update Tue Mar 7, 2023.
I am trying to use discovery of AirPlay devices and knowing the MCPeerID want to connect to that. I do not know how yet. When I implement the following class, I get a list of NetService names. Knowing which one I want to connect to and play a local MP3 currently eludes me however.
let apd = AirPlaySpeakerDiscovery()
apd.start()
This produces a console log of service names. Perfect. Now how to play a local mp3 file but route to one of the services? Say "Kitchen HomePod"?
import Foundation
import Network
class AirPlaySpeakerDiscovery: NSObject
{
private var browser: NetServiceBrowser?
private var airplayServices = [NetService]()
override init() {
super.init()
self.browser = NetServiceBrowser()
self.browser?.delegate = self
}
func start() {
self.browser?.searchForServices(ofType: "_airplay._tcp.", inDomain: "local.")
}
func stop() {
self.browser?.stop()
}
func printAirPlayServices() {
for service in self.airplayServices {
print("Service Name: \(service.name)")
// How to connect to one of them now?
if (service.name == "Kitchen HomePod") {
// Play local mp3 file on it?
}
}
}
}
extension AirPlaySpeakerDiscovery: NetServiceBrowserDelegate {
func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) {
self.airplayServices.append(service)
if !moreComing {
self.printAirPlayServices()
}
}
func netServiceBrowser(_ browser: NetServiceBrowser, didRemove service: NetService, moreComing: Bool) {
if let index = self.airplayServices.firstIndex(of: service) {
self.airplayServices.remove(at: index)
}
if !moreComing {
self.printAirPlayServices()
}
}
func netServiceBrowser(_ browser: NetServiceBrowser, didNotSearch errorDict: [String : NSNumber]) {
print("Error searching for AirPlay services: \(errorDict)")
}
}