How to play movies on UIView?


MOVなどの動画ファイルをiPhone上で再生させたいと思うときに、MPMoviePlayerControllerなどを使わずに自分で好きなように再生させたい時がある。
そういった時にAVFoundationのAVPlayerが役にたつ。このライブラリは動画の再生などを肩代わりしてくれるが、UI周りのすべてを自分で作る必要がある。画面とかに埋め込み動画みたいなものを作りたい人にはおすすめ。

必要なFramework

  • AVFoundation.framework
  • CoreMedia.framework

PlayerView

UIViewに少し付け加えないと動かないので、そのWrapperを作る。

AVPlayerView.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface AVPlayerView : UIView

@end
AVPlayerView.m
#import "AVPlayerView.h"

@implementation AVPlayerView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

// AVPlayerLayerが使えますよと教えてあげる
// これなしで、普通のUIViewにくっつけても動かないので大事
+ (Class)layerClass
{
    return [AVPlayerLayer class];
}

@end

ViewController

ViewControllerに必要な処理。

ViewController.h
#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>
#import <CoreMedia/CoreMedia.h>
#import <AVFoundation/AVFoundation.h>

#import "AVPlayerView.h"

@interface MoviesViewController : UIViewController{
    // あとでくっつける先となるUIViewの継承クラス
    // 上で作ったやつ
    IBOutlet AVPlayerView *playerView;
}

@end
ViewController.m
#import "MoviesViewController.h"

@interface MoviesViewController () {
    AVPlayer     *videoPlayer;
    NSString *moviePath;
}

@end

@implementation MoviesViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 今回はすでにDocuments以下に置いてある動画を再生する
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *directory = [paths objectAtIndex:0];
    moviePath = [directory stringByAppendingPathComponent:@"/movie.mov"];


    NSURL *movieURL = [NSURL fileURLWithPath:moviePath];

    videoPlayer = [[AVPlayer alloc] initWithURL:movieURL];

    AVPlayerLayer* layer = ( AVPlayerLayer* )playerView.layer;
    layer.videoGravity = AVLayerVideoGravityResizeAspect;
    layer.player       = videoPlayer;
    [videoPlayer1 play];
}


@end

ここまででコード部分は完了。あとはStoryboardを使ってAVPlayerViewをattacheしていく。

screen_shot

自分で適当にはっつけたUIViewにさっきのAVPlayerViewをattacheすればいい。ただしこの時気をつけることは、このViewはUIViewのままになっているので以下のように、AVPlayerViewのインスタンスにしてあげないと、attacheの候補に現れてくれないので注意。

screen_shot