せでぃのブログ

ブログ初心者おいどんのどうでもいい愚痴やどうでもいい愚痴やどうでもいいマメ知識などを披露するチラシの裏です。

LavaFlow2

LavaFlow
この動画再生アプリのデバッグを試みていたが、この度諦めることにした。
だから、今回はダウンロード不要。新規で作ってみる。


たぶん、InterfaceBuilderの根本のWindowとDelegateの作りあたりに原因がありそう。この通り、本当に何をやってもダメだった。であれば、何もxcode2だか3だかといった古い作りを再現するのもバカらしいので、この度はアプリを一から今風に作ってみることにした。
今回は最下の参考サイトさんの作りが非常に参考になった。デバッグからずっとお世話になりまくり(最終的に丸パクリ)、zipも公開されているので動画のみ再生ということであれば、そちらの方が参考になるかも。LavaFlowの作りに一番似てた。


1.動画の準備
再生したいm4v形式の動画を用意しておく
なければgithubにプロジェクトを置いといたので、そこから拾ってくる。
https://github.com/csny/movieplay

2.xcode起動
元のアプリ再現のため、Utility Applicationを選択。
StoryBoardsのチェックを忘れずに入れて、プロジェクト名は適当にLavaFlow-kaiという名前で作成してみた。
f:id:Sediment:20130818234427p:plain
f:id:Sediment:20130818234600p:plain

3.用意した動画ファイルの取り込み
プロジェクトフォルダ内にあるSupporting Filesフォルダで右クリックして、Add Files toを選択。
用意したm4vファイルを選択して、Add。
※元ファイルを削除してみるとエラーになるのでわかるけども、ここではファイルへの参照を作成しているだけなので、アプリとしてフォルダを移動したりサーバ上へアップロードする場合は、必ず、プロジェクトフォルダの中へ実際のファイルを移動しておいてからこの作業を行う必要があるので、注意。
f:id:Sediment:20130726083737p:plain

4.MediaPlayer.frameworkフレームワーク追加
プロジェクトのフォルダでBuild Phasesを選択。
Link Bynary With Libraryを選択して、+ボタンを押す。
MediaPlayer.frameworkを選択してAdd。
f:id:Sediment:20130726082706p:plain
f:id:Sediment:20130726083436p:plain
f:id:Sediment:20130819005419p:plain

5.アプリインフォメーションを軽く設定
StoryBoards.xibを選択し、既に用意されている画面の右側のナビゲーションバーのタイトルにアプリ名を入力して、リターン。
f:id:Sediment:20130818234818p:plain

6.AppDelegateの準備
InterfaceBuilder左側の画面にあるMainViewController側へ、「Object」という名前のオブジェクトをドラッグアンドドロップする。
Objectを選択したまま、右ペインでidentity inspectorを選択。Classの右側のボタンを押し、ドロップダウンリストからAppDelegateを選択する。
※MainViewControllerにあまりいろいろ書きたくないのであれば、ここら辺から別な動画専用ビューコントローラを用意するとかもありかなって。
f:id:Sediment:20130818235222p:plain
f:id:Sediment:20130818235310p:plain

7.IBからAppDelegate.hへの関連付け
Assistant Editorを選択。今回はInterfaceBuilderからAppDelegate.hのコード内へドロップしたいので、右ペインの上部のAutomaticという表示あたりをいじるとAppDelegate.hが選べる。
MainViewControllerをAppDelegate.hの「@property (strong, nonatomic) UIWindow *window;」の行の下へドラッグアンドドロップ
TypeをStrongへ変更し、NameをviewControllerにして、Connect。
f:id:Sediment:20130819015415p:plain
f:id:Sediment:20130818235733p:plain

f:id:Sediment:20130819000124p:plain

8.コードの入力
8.1.AppDelegate.h
@class、@interfaceを下記の通りへ変更
f:id:Sediment:20130819023308p:plain


appDelegate.h

#import <UIKit/UIKit.h>

@class MainViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate> {
    UIWindow *window;
    MainViewController *viewController;
}


@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) IBOutlet MainViewController *viewController;

@end

8.2.AppDelegate.m
import、synthesize、(BOOL)内に下記の通り追記。
これ以外にもずらずらとファイル下部に記載があるが、触らなくていい。
f:id:Sediment:20130819001002p:plain

appDelegate.m

#import "AppDelegate.h"
#import "MainViewController.h"

@implementation AppDelegate

@synthesize window;
@synthesize viewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
    // Override point for customization after application launch.
    return YES;
}
//以下略

8.3.MainViewController.h
import、property部分を下記の通り追記。
f:id:Sediment:20130819024706p:plain

MainViewController.h

#import "FlipsideViewController.h"
#import <MediaPlayer/MediaPlayer.h>

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate>

@property (strong, nonatomic) MPMoviePlayerController *player;

@end

8.4.MainViewController.m-part1
synthesize、(void)viewDidLoad内に画像の赤枠で囲まれた内容を追記。
f:id:Sediment:20130819001616p:plain

MainViewController.m-part1

#import "MainViewController.h"

@interface MainViewController ()

@end

@implementation MainViewController

@synthesize player;

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self playMoive];
    NSLog(@"viewDid");
	// Do any additional setup after loading the view, typically from a nib.
}

8.5.MainViewController.m-part2
それ以外の下記メソッドを追記。part2は追加部分だけ抜き出してるので、part2丸ごとコピペで大丈夫。

MainViewController.m-part2

// 動画の再生処理
- (void)playMoive
{
    // 再生する動画を指定
    NSString *path;
    path = [[NSBundle mainBundle] pathForResource:@"lavaFlow" ofType:@"m4v"];
    NSURL *url;
    url = [NSURL fileURLWithPath:path];
    // ネット上にある動画を再生する場合はURLで指定
    // url = [NSURL URLWithString:@"http://..."];
	
    player = [[MPMoviePlayerController alloc] initWithContentURL:url];
    
	player.controlStyle = MPMovieControlStyleNone;
	
	// ムービープレイヤーのスケールモードを設定
	player.scalingMode = MPMovieScalingModeAspectFill;
	
	CGRect movieSize = CGRectMake(0, 100, 320, 240);
	//[player.view setFrame:[self.view bounds]];  // frame must match parent view
    [player.view setFrame:movieSize];
    player.backgroundView.backgroundColor = [UIColor clearColor];
    
	[self.view addSubview:player.view];
	
	
	// Register to receive a notification that the movie is now in memory and ready to play
	[[NSNotificationCenter defaultCenter]
	 addObserver:self
	 selector:@selector(moviePlayerLoadStateDidChangeNotification:)
	 name:MPMoviePlayerLoadStateDidChangeNotification
	 object:player];
	
    // 再生終了のNotificationを設定
    [[NSNotificationCenter defaultCenter]
	 addObserver:self
	 selector:@selector(finishPlayback:)
	 name:MPMoviePlayerPlaybackDidFinishNotification
	 object:player];
	
	[player play];
    NSLog(@"playing");
}


//  Notification called when the movie finished preloading.
- (void) moviePlayerLoadStateDidChangeNotification:(NSNotification*)notification
{
	NSLog(@"preloaded");
}

// 動画の再生終了
- (void) finishPlayback:(NSNotification *) aNotification
{
	[player play];
    NSLog(@"finished");
}

8.6.MainViewController.m-part3
MainViewController.mの全体像は次のようになっているか確認。

MainViewController.m

#import "MainViewController.h"

@interface MainViewController ()

@end

@implementation MainViewController

@synthesize player;

// 動画の再生処理
- (void)playMoive
{
    // 再生する動画を指定
    NSString *path;
    path = [[NSBundle mainBundle] pathForResource:@"lavaFlow" ofType:@"m4v"];
    NSURL *url;
    url = [NSURL fileURLWithPath:path];
    // ネット上にある動画を再生する場合はURLで指定
    // url = [NSURL URLWithString:@"http://..."];
	
    player = [[MPMoviePlayerController alloc] initWithContentURL:url];
    
	player.controlStyle = MPMovieControlStyleNone;
	
	// ムービープレイヤーのスケールモードを設定
	player.scalingMode = MPMovieScalingModeAspectFill;
	
	CGRect movieSize = CGRectMake(0, 100, 320, 240);
	//[player.view setFrame:[self.view bounds]];  // frame must match parent view
    [player.view setFrame:movieSize];
    player.backgroundView.backgroundColor = [UIColor clearColor];
    
	[self.view addSubview:player.view];
	
	
	// Register to receive a notification that the movie is now in memory and ready to play
	[[NSNotificationCenter defaultCenter]
	 addObserver:self
	 selector:@selector(moviePlayerLoadStateDidChangeNotification:)
	 name:MPMoviePlayerLoadStateDidChangeNotification
	 object:player];
	
    // 再生終了のNotificationを設定
    [[NSNotificationCenter defaultCenter]
	 addObserver:self
	 selector:@selector(finishPlayback:)
	 name:MPMoviePlayerPlaybackDidFinishNotification
	 object:player];
	
	[player play];
    NSLog(@"playing");
}


//  Notification called when the movie finished preloading.
- (void) moviePlayerLoadStateDidChangeNotification:(NSNotification*)notification
{
	NSLog(@"preloaded");
}

// 動画の再生終了
- (void) finishPlayback:(NSNotification *) aNotification
{
	[player play];
    NSLog(@"finished");
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self playMoive];
    NSLog(@"viewDid");
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Flipside View

- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showAlternate"]) {
        [[segue destinationViewController] setDelegate:self];
    }
}

@end

9.Run
動画が繰り返し再生されるようになるはず。
LavaFlowの本物だと横向きで起動してたり、アイコンや起動時の画像があったり等の違いはあるのですが、取り敢えず同じフレームワークで再生というところで、手抜きしてますw
f:id:Sediment:20130819002255p:plain


参考)
【iPhone】iOSでのMPMoviePlayerControllerの扱い