8

繰り返しムービーを表示する小さな UIView があります。ユーザーがボタンをタップすると、別のムービーが読み込まれ、同じ UIView に表示されます。

問題は、最初のムービーの削除と 2 番目のムービーの表示の間に 0.5 秒の「フラッシュ」があることです。これを取り除くものはありますか?

- (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コード、誰かの役に立てば幸いです:)

Apple のリファレンス ドキュメントはここにあります。私はそれらを使用してほとんどの情報を取得しました 。 /doc/uid/TP40010188-CH1-SW3

私が最初にしたことは、PlayerView という名前の次のクラスをプロジェクトに追加することでした (申し訳ありませんが、どこで取得したか思い出せません)。UIView のサブクラスであり、ムービーが表示されるビューです。プロジェクトに追加したら、UI ビルダーを開き、新しいビューを既存の xib に追加し、そのクラスを PlayerView に変更します。これを IBOutlet を使用して接続します。ここでも、これがムービーを表示するビューであることを思い出してください。

PlayerView.h


#import 
#import 
#import 

@interface PlayerView : UIView {
    AVPlayer *player;
}

@property (nonatomic,retain) AVPlayer *player;

@end

PlayerView.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 には、次のものがあります。

DisplayMovies.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 を持つ 2 つのビューを作成することで、問題を解決できました。両方を再生してから、トップ ビューを非表示にして切り替えます。これでフラッシュがなくなり、setHidden を使用する代わりにアルファを 0.0 に設定してトップ ビューを非表示にすることで、2 つのトラック間のトランジションをアニメートすることができました。これが私のコードです:

    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

私はまだこのプロジェクトに戻らなければなりませんが、さらにアドバイスを受けました。できれば 2 週間以内にこのプロジェクトに戻ってくるので、どのソリューションがうまくいったか (指が交差した) をお知らせします。それまでの間、ここに私のオプションがあります:

1. MPMoviePlayerController を使用して、フラッシュなしでムービーを切り替えることはできません。

代わりに、AV Foundation を使用できます。AVPlayer -replaceCurrentItemWithPlayerItem: メソッドは、フラッシュなしで古いプレーヤー アイテムから新しいプレーヤー アイテムにシームレスに移行します。

AV Foundation を使用したプログラミングの詳細については、次の場所にある「AV Foundation プログラミング ガイド」を参照してください。

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

2. すべてのムービーを 1 つの (大きな) ムービーに結合し、MPMediaPlayback の currentPlaybackTime / endPlaybackTime プロパティを使用して、(大きなムービー内で) 目的のムービーを「選択」して再生することができます。この手法を使用する場合は、新しいムービーが開始する時点にキー フレームがあることも確認する必要があります。

3. または、単一の MPMoviePlayerController オブジェクトを作成し、-setContentURL: を使用して新しいムービー URL を設定し、backgroundView プロパティを利用してよりシームレスな移行を行います。backgroundView はビュー プロパティで自動的にサイズ変更されますが、ムービーがプリロードされる前に非表示になります。両方のムービー ビューの後ろに黒いビューを配置し、backgroundView の backgroundColor = black を作成すると、よりシームレスに表示されます。

お役に立てれば。

于 2011-02-09T22:00:47.980 に答える
0

ここで解決策を見つけてください。MPMoviePlayerReadyForDisplayDidChangeNotification をキャッチして [self.movi​​ePlayer play] を使用します。

于 2014-09-25T09:37:27.657 に答える