Может ли AVContentKeySession makeStreamingContentKeyRequestDataForApp безопасно быть принудительно синхронизирован? - PullRequest
4 голосов
/ 29 апреля 2019

У меня есть приложение для потоковой передачи звука, защищенное DRM FairPlay.Изначально он поставлялся с использованием AVAssetResourceLoaderDelegate для доставки ключей FairPlay, но теперь я обновляю его, чтобы использовать AVContentKeySession для iOS 11.2 и более поздних версий .Примечание: если вы пытаетесь это сделать и разочарованы отсутствием документации, пример кода по ссылке «FairPlay Streaming Server SDK (4.2.0)» здесь .

Каждый из моих аудио продуктов разбит на множество треков.Когда я открываю аудиопродукт, я ставлю в очередь более одной дорожки через AVQueuePlayer.Каждый из этих треков генерирует запрос на ключ FairPlay.В случае, когда нет постоянного загруженного ключа, каждый из этих запросов направляется на сервер ключей, загружает ключ, генерирует постоянный ключ и сохраняет его.Каждый трек имеет один и тот же ключ, поэтому все они имеют одинаковые данные постоянного ключа, и каждый перезаписывает последний из них.

Поскольку стоимость моих серверов ключей зависит от количества запросов ключейЯ хотел бы, чтобы только первый запрос действительно попадал на сервер ключей, а последующие запросы используют постоянный ключ.Но метод, используемый для передачи данных SPC на сервер ключей, makeStreamingContentKeyRequestDataForApp, использует асинхронный блок завершения. эквивалентный метод для AVAssetResourceLoadingRequest является синхронным.

Мой вопрос: безопасно ли заставить этот вызов быть синхронным, используя семафор?Например:

-(void)handleOnlineRequest:(AVContentKeyRequest *)req
  NSData *appCert = [self _getAppCertData];
  NSData *assetId = [self _kidFromRequest:req];
  dispatch_semaphore_t sema = dispatch_semaphore_create(0);
  [req makeStreamingContentKeyRequestDataForApp:appCert
                              contentIdentifier:assetId
                                        options:nil
                                        completion:^
    NSData *contentKeyRequestData, NSError *error)
    {
      //request key data and respond to request

      dispatch_semaphore_signal(sema);
    }];
  dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
  dispatch_release(semaphore);

Эффект особенно выражен при загрузке звука, который ранее не передавался.Скорость загрузки аудио с использованием AVAssetDownloadTask составляет очень медленно , поэтому я запускаю сразу несколько, и каждый генерирует запрос ключа.

...