애플 TV 앱에 페어플레이 보호 기능 추가하기

이 항목에서는 tvOS용 브라이트코브 네이티브 SDK를 사용하는 Apple TV 앱에 FairPlay 콘텐츠 보호를 추가하는 방법에 대해 알아봅니다.

개요

tvOS용 네이티브 SDK는 FairPlay 스트리밍과 함께 HLS를 사용하여 디지털 저작권 관리 (DRM) 보호를 지원합니다. 계정이 DRM이 활성화되고 Dynamic Delivery에 대해 구성되어 있으면 비디오를 수집 할 때 자동으로 DRM 용으로 패키징됩니다.

FairPlay로 보호되는 비디오에 대한 지원이 Brightcove Native SDK의 핵심 프레임 워크에 통합되어 있으므로 응용 프로그램 인증서를로드 할 필요가 없습니다. 자세한 내용은 네이티브 플레이어 SDK를 사용한콘텐츠 보안 (DRM)문서를 참조하십시오.

코드 샘플

Apple TV 앱에 FairPlay 콘텐츠 보호를 추가하려면 다음 단계를 따르십시오.

  1. 기본 Apple TV샘플 앱으로 시작하세요.
  2. 앱에 FairPlay 라이선스 코드를 추가합니다. 이는기본 FairPlay샘플에서 확인할 수 있습니다.

ViewController.swift파일의 코드는 다음과 비슷해야 합니다.

//
//  ViewController.swift
//  Fairplay-Video-Playback
//
//  Copyright © 2019 Brightcove. All rights reserved.
//

import UIKit
import BrightcovePlayerSDK

// This example is for content using Dynamic Delivery. Because of this, you do NOT need to specify your FairPlay Application ID or the FairPlay Publisher ID.
fileprivate struct playbackConfig {
    static let policyKey = "your policy key"
    static let accountID = "your account ID"
    static let videoID = "your video ID"
}

class ViewController: UIViewController {
    @IBOutlet weak var videoContainerView: UIView!

    var playbackController: BCOVPlaybackController = BCOVPlayerSDKManager.shared().createPlaybackController()
    var fairPlayAuthProxy: BCOVFPSBrightcoveAuthProxy?

    lazy var playerView: BCOVTVPlayerView? = {
        // Set ourself as the presenting view controller
        // so that tab bar panels can present other view controllers
        let options = BCOVTVPlayerViewOptions()
        options.presentingViewController = self

        // Create and add to the video container view
        guard let _playerView = BCOVTVPlayerView(options: options) else {
            return nil
        }

        // Link the playback controller to the Player View
        _playerView.playbackController = playbackController

        videoContainerView.addSubview(_playerView)

        _playerView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            _playerView.topAnchor.constraint(equalTo: videoContainerView.topAnchor),
            _playerView.rightAnchor.constraint(equalTo: videoContainerView.rightAnchor),
            _playerView.leftAnchor.constraint(equalTo: videoContainerView.leftAnchor),
            _playerView.bottomAnchor.constraint(equalTo: videoContainerView.bottomAnchor)
            ])

        return _playerView
    }()

    lazy var playbackService: BCOVPlaybackService = {
        return BCOVPlaybackService(accountId: playbackConfig.accountID, policyKey: playbackConfig.policyKey)
    }()

    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // With Dynamic Delivery, you don't need to load
        // an application certificate. The FairPlay session will load an
        // application certificate for you if needed.
        // You can just load and play your FairPlay videos.

        // With Dynamic Delivery, you can pass nil for the publisherId and applicationId
        self.fairPlayAuthProxy = BCOVFPSBrightcoveAuthProxy(publisherId: nil,
                                                            applicationId: nil)

        let sdkManager = BCOVPlayerSDKManager.sharedManager()

        // Create chain of session providers
        let psp = sdkManager?.createBasicSessionProvider(with:nil)
        let fps = sdkManager?.createFairPlaySessionProvider(withApplicationCertificate:nil,
                                                            authorizationProxy:self.fairPlayAuthProxy!,
                                                            upstreamSessionProvider:psp)

        createSampleTabBarItemView()

        // Create the playback controller
        playbackController = (sdkManager?.createPlaybackController(with:fps, viewStrategy:nil))!
        // Configure the playback controller
        playbackController.isAutoAdvance = false
        playbackController.isAutoPlay = true
        playbackController.delegate = self

        // Link the playback controller to the Player View
        playerView?.playbackController = playbackController

        requestContentFromPlaybackService()
    }

    private func createSampleTabBarItemView() {

        guard let playerView = playerView, var topTabBarItemViews = playerView.settingsView.topTabBarItemViews else {
            return
        }

        let sampleTabBarItemView = SampleTabBarItemView(size: CGSize.init(width: 620, height: 200), playerView: playerView)

        // Insert our new tab bar item view at the end of the top tab bar
        topTabBarItemViews.append(sampleTabBarItemView)
        playerView.settingsView.topTabBarItemViews = topTabBarItemViews
    }

    private func requestContentFromPlaybackService() {
        playbackService.findVideo(withVideoID: playbackConfig.videoID, parameters: nil) { [weak self] (video: BCOVVideo?, jsonResponse: [AnyHashable: Any]?, error: Error?) -> Void in

            if let _video = video {
                //  since "isAutoPlay" is true, setVideos will begin playing the content
                self?.playbackController.setVideos([_video] as NSArray)
            } else {
                print("ViewController Debug - Error retrieving video: \(error?.localizedDescription ?? "unknown error")")
            }

        }
    }
}

// MARK: - UIFocusEnvironment overrides
extension ViewController {

    // Focus Environment override for tvOS 9
    override var preferredFocusedView: UIView? {
        return playerView
    }

    // Focus Environment override for tvOS 10+
    override var preferredFocusEnvironments: [UIFocusEnvironment] {
        return (playerView != nil ? [ playerView! ] : [])
    }

}

// MARK: - BCOVPlaybackControllerDelegate
extension ViewController: BCOVPlaybackControllerDelegate {

    func playbackController(_ controller: BCOVPlaybackController!, didAdvanceTo session: BCOVPlaybackSession!) {
        NSLog("ViewController Debug - Advanced to new session.")
    }

    func playbackController(_ controller: BCOVPlaybackController!, playbackSession session: BCOVPlaybackSession!, didReceive lifecycleEvent: BCOVPlaybackSessionLifecycleEvent!) {
        NSLog("Event: %@", lifecycleEvent.eventType)
    }

}