Несколько экземпляров MPMoviePlayerController - PullRequest
23 голосов
/ 06 декабря 2010

Я пытаюсь поместить два MPMoviePlayerController в UIView, как это

    for (int i = 0; i < 2; i++)
{
    UIView* v = [[UIView alloc] initWithFrame: CGRectMake(0.0f, 300.0f * i, self.view.width, 300.0f)];
    [self.view addSubview: v];

    NSURL* url = [NSURL URLWithString: [urls objectAtIndex: i]];
    MPMoviePlayerController* movieController = [[MPMoviePlayerController alloc] initWithContentURL: url];
    movieController.movieSourceType = MPMovieSourceTypeFile;
    movieController.shouldAutoplay = NO;
    movieController.view.frame = v.bounds;
    [self.view addSubview: movieController.view];
}

Но отображается только один вид за раз. Я знаю, что в документации Apple написано

Примечание. Хотя вы можете создавать несколько объектов MPMoviePlayerController и представлять их представления в своем интерфейсе, только один проигрыватель фильмов одновременно может воспроизводить его.

но не должен ли вид показывать всех двух игроков одновременно? Также только один экземпляр отправляет уведомления MPMoviePlayerLoadStateDidChangeNotification ...

Ответы [ 3 ]

27 голосов
/ 13 июня 2012

Вы можете воспроизводить несколько видео на экране с помощью инфраструктуры AVFoundation: Руководство по программированию AV Foundation

Недостатком является то, что его не так просто использовать, как MPMoviePlayerController, и вы должны создать подкласс UIView, который содержит классы AVFoundation. Таким образом, вы можете создать необходимые элементы управления для него, управлять воспроизведением видео, анимировать вид (например, анимировать переход в полноэкранный режим).

Вот как я это использовал:

// Create an AVURLAsset with an NSURL containing the path to the video
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];

// Create an AVPlayerItem using the asset
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];

// Create the AVPlayer using the playeritem
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];

// Create an AVPlayerLayer using the player
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];

// Add it to your view's sublayers
[self.layer addSublayer:playerLayer];

// You can play/pause using the AVPlayer object
[player play];
[player pause];

// You can seek to a specified time
[player seekToTime:kCMTimeZero];

// It is also useful to use the AVPlayerItem's notifications and Key-Value 
// Observing on the AVPlayer's status and the AVPlayerLayer's readForDisplay property
// (to know when the video is ready to be played, if for example you want to cover the 
// black rectangle with an image until the video is ready to be played)
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(playerItemDidReachEnd:)
                                             name:AVPlayerItemDidPlayToEndTimeNotification 
                                           object:[player currentItem]];

    [player addObserver:self forKeyPath:@"currentItem.status"
                     options:0
                     context:nil];

    [playerLayer addObserver:self forKeyPath:@"readyForDisplay"
                     options:0
                     context:nil];

Вы можете изменять размер AVPlayerLayer по своему усмотрению даже во время воспроизведения видео.

Если вы хотите использовать анимацию при изменении размера или изменении положения AVPlayerLayer, вам нужно изменить анимацию по умолчанию, в противном случае вы увидите, что видео слоя игрока не изменяется в синхронизации с его прямоугольником. (Спасибо @djromero за его ответ относительно анимации AVPlayerLayer )

Вот небольшой пример того, как изменить анимацию по умолчанию. Настройка для этого примера состоит в том, что AVPlayerLayer находится в подклассе UIView, который действует как его контейнер:

// UIView animation to animate the view
[UIView animateWithDuration:0.5 animations:^(){
    // CATransaction to alter the AVPlayerLayer's animation
    [CATransaction begin];
    // Set the CATransaction's duration to the value used for the UIView animation
    [CATransaction setValue:[NSNumber numberWithFloat:0.5] 
                     forKey:kCATransactionAnimationDuration];
    // Set the CATransaction's timing function to linear (which corresponds to the 
    // default animation curve for the UIView: UIViewAnimationCurveLinear)
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction 
                             functionWithName:kCAMediaTimingFunctionLinear]];

        self.frame = CGRectMake(50.0, 50.0, 200.0, 100.0);
        playerLayer.frame = CGRectMake(0.0, 0.0, 200.0, 100.0);

    [CATransaction commit];

}];
1 голос
/ 01 июня 2012

Вы не сможете сделать это.Внутренне MPMoviePlayerController, похоже, использует одно и то же представление для торговли между экземплярами в зависимости от того, какой экземпляр воспроизводится.Единственный вариант - создать свой собственный видеопроигрыватель с использованием AVFoundation, чтобы получить несколько экземпляров, или использовать HTML и UIWebViews.Смотри: http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/00_Introduction.html#//apple_ref/doc/uid/TP40010188

0 голосов
/ 14 января 2012

Вам требуется одновременно воспроизводить оба видео?

Я полагаю, у меня есть два варианта:

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

  2. Создайте один отдельный контроллер представления и добавьте в него свое видео.Теперь добавьте этот viewcontroller.view в ваш основной вид, где вы хотите.

Дайте мне знать, если какой-либо из этих вариантов работает для вас.

...