cocos2d: воспроизведение видео на фоне меню - PullRequest
17 голосов
/ 15 декабря 2010

У меня есть CCLayer с меню «Пуск» моего приложения, и я хотел бы, чтобы в фоновом режиме воспроизводился короткий фильм.Мне удалось воспроизвести фильм в glView, но когда он воспроизводится, меню не отображается.Для обработки фильма я создаю экземпляр MPMoviePlayerController, а затем добавляю его представление в glView следующим образом:

[[[CCDirector sharedDirector] openGLView] addSubview:moviePlayer.view];

Я видел, что этот вопрос был очень похож

Как получитьменю при воспроизведении фильма - iphone cocos2d

но я хотел бы знать, есть ли лучшее решение для него, возможно, такое, которое позволит мне по-прежнему использовать объекты каркаса cocos2d (а не мое собственноеПросмотры).

Я пытался отправить фильм moviePlayer.view обратно таким образом

[theView sendSubviewToBack:moviePlayer.view];

, но меню все еще скрыто фильмом ...

(много часов спустя..)

Хорошо, как вы можете прочитать в первом комментарии, я понял, что (возможно) единственный способ - использовать пользовательские представления.Я сделал это, и он запускается в симуляторе, добавляя любые виды в glView после moviePlayer.view.Однако, когда я запускаю его на своем IPod touch с 3.1.3 FW, просмотр фильма всегда на высоте.Поэтому я понял, что MPMoviePlayerController фактически создает свое собственное окно и свое собственное представление.В некоторых публикациях (например, Overlay поверх Streaming MPMoviePlayerController ) предлагается перехватить событие, когда загружается новое окно, и только затем добавлять подпредставления.

это то, что я пытался сделать, но это событие фактически никогда не ловится ни на симуляторе, ни на целевом Ipod.Поэтому я добавил запланированное обновление селектора - (void), которое реализовано следующим образом:

-(void) update{
    NSArray *windows = [[UIApplication sharedApplication] windows];
    if ([windows count] > 1)
    {
    UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"logo.png"]];
    UIView *theView = [[CCDirector sharedDirector] openGLView];
    [logo setCenter:ccp(240,80)];
    [moviePlayer.view addSubview:logo];
        [self unscheduleAllSelectors];
    }
}

, но фильм по-прежнему остается на вершине

, пожалуйста, ребята, любая помощь будет очень признательна!

(несколько дней спустя ...) Я также ждал 2 секунды, пока фильм на самом деле запущен, чтобы добавить мой логотип в качестве подпредставления игрока.Он корректно работает на симуляторе, но на Ipod (3.1.3) получается другой результат.При первом воспроизведении фильма логотип не отображается (фильм сверху).Однако, как только фильм заканчивается, воспроизводится метод воспроизведения, начиная со второго раза, когда логотип отображается с фильмом на заднем плане (если это так).Это имеет какой-то смысл для вас?

Мне действительно нужно понять, как решить эту проблему, это довольно нелепо, мне удалось разработать игру за 2 месяца, а теперь я застрял с 2 неделями в меню «Пуск»:)

В любом случае, если я решил вставить весь код слоя, который я пытаюсь исправить, чтобы вы могли лучше выяснить, в чем проблема (или, по крайней мере, это моя надежда :))

+(id) scene
{
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];

    // 'layer' is an autorelease object.
    StartMenu *layer = [StartMenu node];

    // add layer as a child to scene
    [scene addChild: layer];

    // return the scene
    return scene;
}

-(void) update{
    timer ++;
    if (timer==120){

    UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"stupidLogo.png"]];
    UIView *theView = [[CCDirector sharedDirector] openGLView];
    [logo setCenter:ccp(240,80)];
    //logo.transform = CGAffineTransformMakeRotation(3.14/2);
    [moviePlayer.view addSubview:logo];
        [self unscheduleAllSelectors];
    }
}
-(id) init{
    self = [super init];

    [self schedule: @selector(update)];
    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test_005_conv_06.mp4" ofType:@""]];        
    moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
    // Register to receive a notification when the movie has finished playing.
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(moviePlayBackDidFinish:)
                                                 name:MPMoviePlayerPlaybackDidFinishNotification
                                               object:moviePlayer];

    if ([moviePlayer respondsToSelector:@selector(view)]) {
        if([MPMoviePlayerController instancesRespondToSelector:@selector(view)]){
        // Use the new 3.2 style API
        moviePlayer.controlStyle = MPMovieControlStyleNone;
        moviePlayer.shouldAutoplay = FALSE;
        // This does blows up in cocos2d, so we'll resize manually
        // [moviePlayer setFullscreen:YES animated:YES];
        [moviePlayer.view setTransform:CGAffineTransformMakeRotation((float)M_PI_2)];
        CGSize winSize = [[CCDirector sharedDirector] winSize];

        moviePlayer.view.frame = CGRectMake(0, 0, winSize.height, winSize.width);   // width and height are swapped after rotation
        [[[CCDirector sharedDirector] openGLView] addSubview:moviePlayer.view];
        [moviePlayer play];
        }
    } else {
        // Use the old 2.0 style API
        moviePlayer.movieControlMode = MPMovieControlModeHidden;
        [moviePlayer play];
    }
    return self;
}


- (void)moviePlayBackDidFinish:(NSNotification*)notification {
    MPMoviePlayerController *moviePlayer = [notification object];
    [moviePlayer play];
}

1 Ответ

19 голосов
/ 18 декабря 2010

Потратив некоторое время на это, я нашел ответ. (Я тоже хочу это сделать, но позже, так что я могу начать это прямо сейчас!)

Я использовал код и методы в по этой ссылке от ascorbin, с помощью по этой ссылке . Это не завершено, если вы также не добавите следующую строку в EAGLView:

glView.opaque = NO;

Вид фильма расположен вдоль стороны EAGLView и сдвинут назад, чтобы получить то, что вы ищете. Возможно, вам также придется настроить прозрачность EAGLView, как это упоминается в этом посте. Надеюсь, это поможет.


Вещи, которые мне нужно было изменить, перечислены здесь.

Вам необходимо добавить mediaPlayer.framework яблока в свой проект и включить следующую строку в делегат приложения .h:

#import <MediaPlayer/MediaPlayer.h>

В методе CCDirector setGLDefaultValues установите альфа-значение glClearColor равным 0,0f, а не 1,0f:

//  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

При создании EAGLView в applicationDidFinishLaunching: измените следующие вещи:

Измените pixelFormat со старого значения на следующее:

// kEAGLColorFormatRGB565
kEAGLColorFormatRGBA8

Убедитесь, что EAGLView добавлен как вспомогательное представление (и сделайте его непрозрачным), а не как основное представление:

//  [viewController setView:glView];
    [viewController.view addSubview:glView];
    glView.opaque = NO;

Наконец, перед запуском вашей сцены вы можете добавить свой код для воспроизведения зацикленного фильма. Я добавил метод к делегату приложения для этого. Вы также можете добавить метод, позволяющий остановить воспроизведение фильма, здесь, в приложении-делегате, а также для случаев, когда (если?) Вам нужно удалить фильм.

[self startMovie];

и сам метод:

- (void) startMovie
{
    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"m4v"]];
    moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];

    if ([moviePlayer respondsToSelector:@selector(setFullscreen:animated:)]) {
        // Use the new 3.2 style API
        moviePlayer.controlStyle = MPMovieControlStyleNone;
        moviePlayer.shouldAutoplay = YES;
        moviePlayer.repeatMode = MPMovieRepeatModeOne;
        CGRect win = [[UIScreen mainScreen] bounds];

        moviePlayer.view.frame = CGRectMake(0, 0, win.size.height, win.size.width);
        [viewController.view  addSubview:moviePlayer.view];
        [viewController.view  sendSubviewToBack:moviePlayer.view];
    } 
    else
    {
        // Use the old 2.0 style API
        moviePlayer.movieControlMode = MPMovieControlModeHidden;
        [moviePlayer play];
    }
}

Обратите внимание, что вам не нужно добавлять наблюдателя, как указано в связанном примере, ни функцию повторения фильма, это делается автоматически с опцией 'MPMovieRepeatModeOne'. Если вы не хотите, чтобы фильм повторялся, вы также можете здесь выбрать опцию «MPMovieRepeatModeNone».

Я также должен отметить, что мне не удалось заставить это работать со старым API до 3.2 (поэтому в вашем случае 3.1.3 он не работал), видео не показывалось через EAGLView. Я не уверен, что там происходит, но я не видел конкретных вариантов того, что с этим делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...