8

我有一个显示重复电影的小 UIView。当用户点击一个按钮时,另一个电影被加载并显示在同一个 UIView 中。

问题是在第一部电影的移除和第二部电影的显示之间有半秒的“闪光”。有什么可以删除的吗?

- (void) setUpMovie:(NSString*)title {
NSString *url = [[NSBundle mainBundle] pathForResource:title ofType:@"mp4"];

MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:url]];
[[player view] setFrame:self.movieView.bounds];
[self.movieView addSubview:player.view];
if ([title isEqualToString:@"Bo_idle_02"]) {
    [player setRepeatMode:MPMovieRepeatModeOne];
} else {
    [player setRepeatMode:MPMovieRepeatModeNone];
}
[player setControlStyle:MPMovieControlStyleNone];
[player play];
}

- (void) startDanceAnimation { [self setUpMovie:@"Bo_dance_02"]; return; }
4

4 回答 4

4

如前所述,我设法使用 AVFoundation 在没有白色闪光灯的情况下改变我的电影。下面的 sudo 代码,希望对某人有所帮助:)

苹果参考文档可以在这里找到,我用它们来获取我的大部分信息:http: //developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/00_Introduction.html#//apple_ref /doc/uid/TP40010188-CH1-SW3

我做的第一件事是在我的项目中添加以下名为 PlayerView 的类(不记得我在哪里得到它,抱歉)。它是 UIView 的子类,也是电影将在其中显示的视图。将其添加到项目后打开 UI Builder,将新视图添加到现有 xib 并将其类更改为 PlayerView。使用 IBOutlet 连接它。再次记住这是将显示电影的视图。

播放器视图.h


#import 
#import 
#import 

@interface PlayerView : UIView {
    AVPlayer *player;
}

@property (nonatomic,retain) AVPlayer *player;

@end

播放器视图.m


#import "PlayerView.h"


@implementation PlayerView
@synthesize player;

+ (Class)layerClass {
    return [AVPlayerLayer class];
}
- (AVPlayer*)player {
    return [(AVPlayerLayer *)[self layer] player];
}
- (void)setPlayer:(AVPlayer *)player {
    [(AVPlayerLayer *)[self layer] setPlayer:player];
}

- (void) dealloc {
    [super dealloc];
    [player release];
}

@end

在显示电影的 ViewContoller 中,我有以下内容:

显示电影.h


#import 
#import 
@class PlayerView;

@interface DisplayMovies : UIViewController {
IBOutlet AVPlayer *player;
AVPlayerItem *movieOneItem;
AVPlayerItem *movieTwoItem;
}
@property (nonatomic, retain) AVPlayer *player;
@property (retain) AVPlayerItem *movieOneItem;
@property (retain) AVPlayerItem *movieTwoItem;

DisplayMovies.m


@implementation DisplayMovies
@synthesize player, movieOneItem, movieTwoItem;

- (void)viewDidLoad {
// load the two movies
NSURL *movieOneItemURL = [[NSBundle mainBundle] URLForResource:@"movieOne" withExtension:@"mp4"];
    AVURLAsset *movieOneItemAsset = [AVURLAsset URLAssetWithURL:movieOneItemURL options:nil];
    self.movieOneItem = [AVPlayerItem playerItemWithAsset:movieOneItemAsset];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(movieOneItemDidReachEnd:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:self.movieOneItem];

NSURL *movieTwoItemURL = [[NSBundle mainBundle] URLForResource:@"movieTwo" withExtension:@"mp4"];
    AVURLAsset *movieTwoItemAsset = [AVURLAsset URLAssetWithURL:movieTwoItemURL options:nil];
    self.movieTwoItem = [AVPlayerItem playerItemWithAsset:movieTwoItemAsset];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(movieTwoItemDidReachEnd:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:self.movieTwoItem];
    [self.player play];
}


- (void) movieOneItemDidReachEnd:(NSNotification*)notification {
// play movie two once movie one finishes
    [self.player seekToTime:kCMTimeZero];
    [self.player replaceCurrentItemWithPlayerItem:self.movieTwoItem];
    [self.player play];
}

- (void) movieTwoItemDidReachEnd:(NSNotification*)notification {
// play movie one once movie two finishes
    [self.player seekToTime:kCMTimeZero];
    [self.player replaceCurrentItemWithPlayerItem:self.movieOneItem];
    [self.player play];
}

于 2011-02-24T00:51:46.897 回答
2

上面发布的解决方案对我不起作用。我仍然在曲目之间短暂闪烁。我能够通过创建两个视图来解决这个问题,每个视图都有自己的 AVPlayer。我将它们都设置为播放,然后通过隐藏顶视图在它们之间切换。这摆脱了闪光灯,我能够通过将其 alpha 设置为 0.0 而不是使用 setHidden 来隐藏顶视图,从而为两个轨道之间的过渡设置动画。这是我的代码:

    AVPlayerItem *theAsset = [self generatePlaylistAssetWithVideoOne];  //In my app this returns an AVPlayer Item

    layerView1 = [[VideoLayerView alloc] initWithFrame:CGRectMake(-50, 0, 580, 320)];  //VideoLayerView is a subclass of UIView with the video layer stuff added in.

    [layerView1 setPlayer:thePlayer];

    [thePlayer play];

    [self.view addSubview:layerView1];



    AVPlayerItem *theAsset2 = [self generatePlaylistAssetWithVideoTwo];

    [thePlayer2 setActionAtItemEnd:AVPlayerActionAtItemEndNone];

    layerView2 = [[VideoLayerView alloc] initWithFrame:CGRectMake(-50, 0, 580, 320)];

    [layerView2 setPlayer:thePlayer2];

    [thePlayer2 play];

    [self.view addSubview:layerView2];

然后在我使用的视频之间制作动画:

    if (water)  //Water is a BOOL set up earlier in the file
{



    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];

    ///DO STUFF
    [layerView2 setAlpha:0];


    [UIView commitAnimations];


    water = NO;
}
else
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];

    ///DO STUFF
    [layerView2 setAlpha:1.0];

    [UIView commitAnimations];

    water = YES;
}

要更改视频,您只需将隐藏视图设置为开始播放您想要的内容,然后在闪烁后进行切换。

于 2011-05-03T03:53:35.777 回答
1

我仍然必须回到这个项目,但我收到了更多建议。希望两周后我会回到这个项目上工作,所以我会让你知道哪个解决方案对我有用(手指交叉)。与此同时,这是我的选择:

1. 没有闪光灯,你将无法使用 MPMoviePlayerController 切换电影。

作为替代方案,您可以使用 AV Foundation。AVPlayer -replaceCurrentItemWithPlayerItem: 方法将从旧的播放器项目无缝过渡到新的播放器项目,而不会闪烁。

有关使用 AV Foundation 进行编程的更多信息,请参阅“AV Foundation 编程指南”,您可以在此处找到:

http://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/

2. 您可以将所有电影合并为单个(大)电影,然后使用 MPMediaPlayback currentPlaybackTime / endPlaybackTime 属性“选择”并播放所需的电影(在大电影内)。如果您使用此技术,您还需要确保在新电影开始的时间点有一个关键帧。

3. 或者,创建单个 MPMoviePlayerController 对象,使用 -setContentURL: 设置新电影 URL,并利用 backgroundView 属性进行更无缝的过渡。backgroundView 使用 view 属性自动调整大小,但在预加载电影之前它将被隐藏。您可以在两个电影视图后面放置一个黑色视图,然后使 backgroundView 的 backgroundColor = black,这应该使它看起来更加无缝。

希望这可以帮助。

于 2011-02-09T22:00:47.980 回答
0

在这里找到解决方案http://joris.kluivers.nl/blog/2010/01/04/mpmovieplayercontroller-handle-with-care/从 iOS 6 你需要使用 [self.movi​​ePlayer prepareToPlay]; 并捕获 MPMoviePlayerReadyForDisplayDidChangeNotification 以使用 [self.movi​​ePlayer play];

于 2014-09-25T09:37:27.657 回答