1

I am using Fairplay implementation as per Apple's Fairplay Streaming sample code at https://developer.apple.com/streaming/fps/, although I tried to choose only parts that are related to Online Fairplay Streaming, not the persistence/offline playback. In the below code a video without Fairplay plays/pauses/seeks normally, but when I play a Fairplay protected video, only the video track behaves correctly.

Pausing playback won't stop the audio playback, changing audio track won't stop the previous audio track, so both plays together and perhaps the seek also does not work.

Besides this helper class below, I have AssetLoaderDelegate and AssetPlaybackManager from Apple's client sample code of FairPlay Streaming Server SDK https://developer.apple.com/streaming/fps/ and I have updated the code to handle SPC/CKC for our DRM keys provider.

Did I miss to implement some important part of the code to handle audio for FPS Streaming? Can you please point me into right direction? Many thanks.

class PlayHelper {

    static let shared = PlayHelper()

    fileprivate var playerViewController: PlayerViewController?

    init() {

        AssetPlaybackManager.sharedManager.delegate = self
    }

    // Play video without DRM
    func playVideo(from urlString: String, at context: UIViewController) {

        guard let videoURL = URL(string: urlString) else {
            Log.error("Video URL can't be created from string: \(urlString)")
            return }

        let player = AVPlayer(url: videoURL)

        let playerViewController = PlayerViewController()
        playerViewController.player = player

        context.present(playerViewController, animated: true) {
            playerViewController.player?.play()
        }
    }

    // Play FPS video
    func playFpsVideo(with asset: AVURLAsset, at context: UIViewController) {

        // Cleanup, should be done when playerViewController is actually dismissed
        if self.playerViewController != nil {
            // The view reappeared as a results of dismissing an AVPlayerViewController.
            // Perform cleanup.
            AssetPlaybackManager.sharedManager.setAssetForPlayback(nil)
            self.playerViewController?.player = nil
            self.playerViewController = nil
        }

        let item = AVPlayerItem(asset: asset)

        let player = AVPlayer(playerItem: item)

        // Customize player
        player.appliesMediaSelectionCriteriaAutomatically = true

        let playerViewController = PlayerViewController()
        playerViewController.player = player

        self.playerViewController = playerViewController

        context.present(playerViewController, animated: true) {
            playerViewController.player?.play()
        }
    }

    // Stop video
    func stop() {

        // Cleanup, should be done when playerViewController is dismissed
        if self.playerViewController != nil {

            // Results of dismissing an AVPlayerViewController, perform cleanup
            AssetPlaybackManager.sharedManager.setAssetForPlayback(nil)
            self.playerViewController?.player = nil
            self.playerViewController = nil
        }
    }
}


// MARK: - Extend `PlayHelper` to conform to the `AssetPlaybackDelegate` protocol

extension PlayHelper: AssetPlaybackDelegate {

    func streamPlaybackManager(_ streamPlaybackManager: AssetPlaybackManager, playerReadyToPlay player: AVPlayer) {

        player.play()
    }

    func streamPlaybackManager(_ streamPlaybackManager: AssetPlaybackManager, playerCurrentItemDidChange player: AVPlayer) {

        guard let playerViewController = playerViewController, player.currentItem != nil else { return }

        playerViewController.player = player
    }
}

I can also provide the code in AssetLoaderDelegate and AssetPlaybackManager if needed.

Martin Koles
  • 5,177
  • 8
  • 39
  • 59
  • i am trying to use apple fairplay for protected video content in offiline. The line https://developer.apple.com/streaming/fps/ i need to download the `FairPlay Streaming Server SDK (4.2.0)` to get the sample code from apple ?. If you have any sample code done for it.Please send me.iT would be greatful – david May 18 '19 at 03:59

1 Answers1

1

My bad. I called play() twice in the code above... Grrr.. Once when the presentation of the PlayerViewController finished and second time in the callback from AssetPlaybackDelegate that is triggered by KVO in AssetPlaybackManager. This way the player controls stopped playing the video, but most probably a second (audio) stream was still playing there. I removed the play() in playerReadyToPlay callback and now all the controls in the Player works as expected. I can pause, resume, seek, change audio tracks.

Martin Koles
  • 5,177
  • 8
  • 39
  • 59
  • I want the code to play FairPlay content in iOS app. Could you please help me in resolving the issue? – Saty May 22 '17 at 12:58
  • 1
    There is a good sample code of the client app provided by Apple as part of the Fairplay Streaming Server SDK: https://developer.apple.com/streaming/fps/ That should be your starting point. – Martin Koles May 22 '17 at 13:26
  • @MartinKoles: I am unable to download the sample code from developer.apple.com/streaming/fps, as it is showing forbidden error. We are trying to implement a player which should work across the browsers and it should play the encrypted contents. I would like to know the details like what we need to do when we get 'WebKitNeedKey' event, can we ignore the second WebKitNeedKey event. Could you please provide the sample code if you have? – kadina Feb 13 '18 at 18:15
  • @kadina: The link to sample code still works for me. You may probably need a developer account to download it. The discussion here was about native iOS app, not browsers or web apps. But there are samples for playing Fairplay HLS in Safari browsers as well. – Martin Koles Feb 13 '18 at 21:42
  • @MartinKoles: Thanks for responding. I am using developer account only. But I am unable to download that. – kadina Feb 13 '18 at 22:01