Как воспроизвести фильм с URL-адресом с помощью настраиваемого протокола NSURLProtocol?

Как вы знаете, воспроизвести фильм с объектом MPMoviePlayerController, используя

[[MPMoviePlayerController alloc] initWithContentURL: aURL];

Теперь я хочу создать собственный протокол NSURLProtocol, в котором я буду расшифровывать источник фильма, который был зашифрован с помощью AlgorithmDES. Это возможность? спасибо за любые идеи. нужна ваша помощь ~


person ben    schedule 08.12.2010    source источник
comment
Привет, я хочу реализовать ту же функцию, что и вы. У меня есть зашифрованный видеофайл на сервере. и я хочу воспроизвести то же видео с потоковой передачей. Как это возможно? Спасибо   -  person Nishith Shah    schedule 03.09.2013


Ответы (4)


ОБНОВЛЕНИЕ: я говорил об этом с Apple, и в настоящее время невозможно использовать MPMoviePlayerController с подклассом NSURLProtocol!


Привет,

Я не уверен, но это возможно. В настоящее время я работаю над чем-то похожим, но еще не полностью. Я выяснил, что MPMoviePlayerController взаимодействует с моим настраиваемым подклассом NSURLProtocol, НО кажется важным принять во внимание HTTPHeaders NSURLRequest, поскольку они определяют диапазон байтов, который необходим MPMoviePlayerController.

Если вы сбросите их в свой подкласс NSURLProtocol, вы для начала дважды получите что-то вроде этого:

2011-01-16 17:00:47.287 iPhoneApp[1177:5f03] Start loading from request: {
Range = "bytes=0-1";

}

Итак, я УГАДАЮ, что до тех пор, пока вы можете предоставить правильный диапазон и вернуть файл mp4, который может воспроизводиться MPMoviePlayerController, это должно быть возможно!

РЕДАКТИРОВАТЬ: Вот интересная ссылка: Защита ресурсов в приложениях для iPhone и iPad

person Oliver Heyme    schedule 16.01.2011
comment
Я обнаружил, что игроку нужно разобрать URL-адрес сам по себе, это не могло сработать, как если бы я нашел способ игрока, как разобрать URL-адрес, но яблоко не предоставит нам его. - person ben; 20.01.2011
comment
Я не вижу никаких методов в NSURLProtocol, которые содержат эту настраиваемую начальную загрузку с диапазоном. Наверное частный метод. Кто-нибудь знает об этом? - person BadPirate; 01.04.2011
comment
В методе startLoading вашего подкласса NSURLProtocol вызовите NSDictionary* headers = [self.request allHTTPHeaderFields]; if([[headers allKeys] containsObject:@"Range"]) { NSLog(@"Range: %@",[headers objectForKey:@"Range"]); } - person Oliver Heyme; 12.04.2011
comment
Я написал собственный протокол, который реализует запросы диапазона и возвращает идентичные данные и заголовки, но по-прежнему получает ошибку -11850 (сервер не настроен правильно) - любая идея, как AVPlayer / MPMoviePlayer определяет, что сервер настроен с запросами диапазона? - person Robert Diamond; 03.02.2013
comment
Согласно протоколу, вам нужно, чтобы ваш сервер возвращал Accept-Ranges: <type> в качестве заголовка HTTP. Обычно <type> равно bytes. - person Jim Dovey; 14.02.2013
comment
@RobertDiamond Удалось ли вам когда-нибудь заставить работать собственный протокол? - person Andrew Theis; 01.06.2013
comment
@AndrewThe нет, это просто невозможно. Мы перешли на AVAudioPlayer - person Robert Diamond; 12.06.2013
comment
iOS 7, похоже, исправила это, я бы попробовал еще раз :) - person Andrew Theis; 31.07.2013
comment
@AndrewTheis вы можете уточнить свое заявление? Или дайте ссылку на то, что он сейчас работает? - person auibrian; 19.12.2013
comment
@auibrian Ну, теперь он отправляет больше запросов 0-1, но, кажется, прерывается после второго запроса (который является 0-X). Это наводит меня на мысль, что это могло быть исправлено в iOS 7, но получаемый ответ не такой, как ожидалось. - person Andrew Theis; 27.12.2013
comment
@AndrewTheis Я вижу одно и то же: запрос 0-2, затем запрос дополнительных байтов, а затем один и тот же запрос снова и снова. Мои ответы в точности совпадают с тем, что я видел с помощью прокси. У меня есть ощущение, что загрузчик AVFoundation ожидает, что соединение не будет закрыто между запросами, и, к сожалению, NSURLProtocol будет следовать тому же шаблону, что и стандартные NSURLConnections, который должен закрывать соединение между каждым запросом. - person auibrian; 06.01.2014
comment
@auibrian Я отправил в Apple билет DTS, и они ответили, что по-прежнему невозможно использовать NSURLProtocol для обслуживания видеофайлов в iOS 7. Они предложили подать запрос на улучшение функции на радаре. - person Andrew Theis; 07.01.2014
comment
@AndrewTheis Следили ли вы за улучшением функции на радаре? Это похоже на серьезное упущение со стороны Apple. URL-адреса должны быть U универсальными. - person Meda; 26.02.2014
comment
@Meda, да, мы (mophie) представили радар для улучшения функций, а также сообщили об этом напрямую нашим каналам в Apple. Позже я найду номер радара. - person Andrew Theis; 28.02.2014
comment
Пожалуйста, сделайте это, когда у вас будет время, я постараюсь повысить осведомленность, и нет смысла составлять еще один запрос. - person Meda; 28.02.2014
comment
@AndrewTheis Получили ли вы какие-либо обновления о возможности использования NSURLProtocol для обслуживания видеофайлов? - person Ravi; 13.06.2014

Решение - прокси-запросы через локальный HTTP-сервер. Я сделал это с помощью CocoaHTTPServer.

Посмотрите на пример HTTPAsyncFileResponse.

person vaughan    schedule 14.01.2014
comment
Я собираюсь реализовать локальный сервер для потоковой передачи видео. Но я не знаю, с чего начать :(. Не могли бы вы рассказать мне, как его создать. Большое спасибо - person sahara108; 08.12.2014
comment
Я попробовал подход AVAssetResourceLoader и не могу заставить его работать. Кажется, слишком много работы для чего-то простого (мне просто нужен собственный заголовок в URL-запросе AVPlayer). Можете ли вы дать рекомендации, как реализовать это с помощью CocoaHTTPServer? - person mixtly87; 04.05.2015

В iOS 7 есть еще одно решение. Вы можете использовать AVAssetResourceLoaderDelegate для AVAssetResourceLoader. Но тогда это будет работать только с AVPlayer.

Существует демонстрационный проект от Apple под названием AVARLDelegateDemo, посмотрите на него, и вы найдете то, что вам нужно. (Я думаю, что ссылка на него - не очень хорошая идея, поэтому просто найдите ее в библиотеке разработчика на сайте developer.apple.com). Затем используйте любую настраиваемую схему URL-адресов (без объявления NSURLProtocol) и обработайте эту схему URL-адресов в AVAssetResourceLoaderDelegate.

Если есть большой интерес, я могу предоставить подтверждение сути концепции.

person Soph    schedule 12.06.2014
comment
Объедините это с iOS8 AVPlayerViewController, и это лучшее решение, которое я нашел. Молодцы, что нашли это. - person Paul de Lange; 01.12.2014

@property AVPlayerViewController *avPlayerVC;
@property NSData *yourDataSource

// initialise avPlayerVC
    NSURL *dummyURL     = [NSURL URLWithString:@"foobar://dummy.mov"];// a non-reachable URL will force the use of the resourceLoader
    AVURLAsset *asset   = [AVURLAsset assetWithURL:dummyURL];
    [asset.resourceLoader setDelegate:self queue:dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)];

    AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];

    self.avPlayerVC.player = [AVPlayer playerWithPlayerItem:item];
    self.avPlayerVC.player.actionAtItemEnd  = AVPlayerActionAtItemEndNone;



// implement AVAssetResourceLoaderDelegate

- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {

    loadingRequest.contentInformationRequest.contentType    = (__bridge NSString *)kUTTypeQuickTimeMovie;
    loadingRequest.contentInformationRequest.contentLength  = self.yourDataSource.length;
    loadingRequest.contentInformationRequest.byteRangeAccessSupported   = YES;

    NSRange range = NSMakeRange((NSUInteger)loadingRequest.dataRequest.requestedOffset, loadingRequest.dataRequest.requestedLength);
    [loadingRequest.dataRequest respondWithData:[self.yourDataSource subdataWithRange:range]];

    [loadingRequest finishLoading];
    return YES;
}

Обратите внимание на использование фиктивного URL-адреса, чтобы заставить AVPlayer использовать методы AVAssetResourceLoaderDelegate вместо прямого доступа к URL-адресу.

person Mojo66    schedule 29.11.2016