0

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)")
    }
}
  • This might be a starting point for an answer. https://developer.apple.com/documentation/avkit/avroutepickerview – sangony Mar 07 '23 at 01:29
  • I started looking @ Bonjour and I can return a list of service PeerID - now I just need to figure out how to connect to one and play a local mp3 file to it. – Eric Dolecki Mar 07 '23 at 03:15

0 Answers0