HLS/Fairplay - Terminated due to signal 9 - Only when running "Mac (designed for iPad)" from xcode

My project is a TV player app for HLS streams with fairplay encryption. It is made on swiftUI for iPhone and iPad, it is in production.

I have enabled the target "Mac (Designed for iPad)" in the project settings, and It is working perfectly on Mac M1 chips when running the app from the Mac AppStore. The Mac version has never been main main focus, but it is nice to have it working so easily.

However when I run the app from Xcode, by selecting "My Mac (Designed for iPad)", everytime AVPlayer wants to start playback I am ejected from the app and the only thing I get from the logcat is: Message from debugger: Terminated due to signal 9 Why? And Why does it work when running the app published on the appstore?

I was able to debug a bit and identify which line of code triggers the issue but I am still stuck:

I am using an AVAssetResourceLoaderDelegate to load the Fairplay Keys instead of the default one (because I need some authentication parameters in the HTTP headers to communicate with the DRM Proxy). So, in the process I am able to request SPC data and CKC (I have verified the data), and then when the loadingRequest.finishLoading() is called.. BOOM the app is terminated and it triggers the log Message from debugger: Terminated due to signal 9.

I am sharing the delegate method from the AVAssetResourceLoaderDelegate where it happens. This has been written a while ago and is running fine on all devices. If you are not used to this delegate, it is used by AVPlayer whenever a new mediaItem is set with the method: AVPlayer.replaceCurrentItem(with: mediaItem)

func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
        guard let dataRequest = loadingRequest.dataRequest else { return false }
        getFairplaycertificate { data, _ in
            // Request Server Playback Context (SPC) data
            guard
                let certificate = data,
                let contentIdData = (loadingRequest.request.url?.host ?? "").data(using: String.Encoding.utf8),
                let spcData = try? loadingRequest.streamingContentKeyRequestData(
                    forApp: certificate,
                    contentIdentifier: contentIdData,
                    options: [AVContentKeyRequestProtocolVersionsKey: [1]]
                ) else {
                loadingRequest.finishLoading(with: NSError(domain: "tvplayer", code: -1, userInfo: nil))
                print("⚠️", #function, "Unable to get SPC data.")
                return false
            }
            
            // Now the CKC can be requested
            let networkId = loadingRequest.request.url?.host ?? ""
            self.requestCKC(spcData: spcData, contentId: networkId) { ckc, error in
                if error == nil && ckc != nil {
                    // The CKC is correctly returned and is sent to AVPlayer. Stream is decrypted
                    dataRequest.respond(with: ckc!)
                    loadingRequest.contentInformationRequest?.contentType = AVStreamingKeyDeliveryContentKeyType
                    loadingRequest.finishLoading()  // <--- THIS LINE IS GUILTY!!!
                } else {
                    print("⚠️", #function, "Unable to get CKC.")
                    loadingRequest.finishLoading(with: error)
                }
            }
            return true
        }
        return true
    }

If I comment loadingRequest.finishLoading() or if I replace it by: loadingRequest.finishLoading(with: error), the app is not terminated but my decryption keys are not loaded. That's the only clue I have so far.

Any help would be appreciated.

  • What should I look for?
  • Is there a way to get a detailed error stacktrace?

Thanks.

Accepted Reply

You can reproduce the same thing by setting AdHoc certificate for the dev build instead of automatic signing. XCode launches the build and it runs well (with Fairplay media playing) but expectedly the debugging is not possible anymore.

  • Thanks, it runs with manual signing with ad hoc provisioning profile and ad hoc certificate for the Debug build! Indeed there is no log. But at least I can try video features and still debug with automatic signing.

Add a Comment

Replies

You can reproduce the same thing by setting AdHoc certificate for the dev build instead of automatic signing. XCode launches the build and it runs well (with Fairplay media playing) but expectedly the debugging is not possible anymore.

  • Thanks, it runs with manual signing with ad hoc provisioning profile and ad hoc certificate for the Debug build! Indeed there is no log. But at least I can try video features and still debug with automatic signing.

Add a Comment