LoginSignup
23
25

More than 5 years have passed since last update.

[Objective-C] AVPlayerを使って動画を再生する

Posted at

AVFoundationを使います。

セットアップ

AVPlayerが動画を再生するコンポーネントとなります。
これを適切にセットアップし、ビューに乗せてやります。

AVPlayerViewの実装

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

@interface AVPlayerView : UIView

@end
AVPlayerView.m
@implementation AVPlayerView

+ (Class)layerClass
{
    return AVPlayerLayer.class;
}

@end

まずはAVPlayerViewを定義して、そのlayerAVPlayerLayerになるよう実装します。

ViewControllerの実装

次に、上記ビューを利用するViewControllerを実装します。

properties
@interface ViewController ()

@property (nonatomic, strong) AVPlayerView *playerView;
@property (nonatomic, strong) AVPlayer     *player;

@end
- (void)viewDidLoad {
    [super viewDidLoad];

    // 動画のURLを生成
    NSString *urlString = @"https://example.com/hoge.mp4";
    NSURL *url = [NSURL URLWithString:urlString];

    // URLを元に`AVPlayer`を生成
    self.player = [[AVPlayer alloc] initWithURL:url];

    // viewのlayerに`AVPlayer`のインスタンスをセット
    self.playerView = [[AVPlayerView alloc] initWithFrame:self.view.frame];
    [(AVPlayerLayer*)self.playerView.layer setPlayer:self.player];

    // 該当のビューを表示
    [self.view addSubview:self.playerView];

    // `status`の変化を監視
    [self.player addObserver:self
                  forKeyPath:@"status"
                     options:NSKeyValueObservingOptionNew
                     context:nil];
}

// `status`の値を監視して、再生可能になったら再生
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if (self.player.status == AVPlayerItemStatusReadyToPlay) {
        [self.player removeObserver:self forKeyPath:@"status"];
        [self.player play];
        return;
    }

    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}

動画再生中に一定時間おきに経過時間を取得する

addPeriodicTimeObserverForInterval:queue:usingBlock:を使いintervalをCMTimeで指定することで、その時間間隔でblocksの中身が呼ばれるようになります。

ちなみにCMTimeについてはこちらを参考にしました。

CMTime time = CMTimeMake(200, 600);
[self.player addPeriodicTimeObserverForInterval:time queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
    NSLog(@"Time: %f", CMTimeGetSeconds(time));
}];

動画の再生が終わったことを検知する

NSNotificationCenterを利用して以下のようにします。

detect-end
// 検知するためには`AVPlayerItem`クラスを使う必要があります。
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:url];

self.player = [[AVPlayer alloc] initWithPlayerItem:playerItem];

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

ちなみに、AVPlayerinitWithURLで生成した場合はこの通知が行われないので注意が必要です。
終わりを検知したい場合はAVPlayerItemクラスを使って動画の再生を行います。


参考記事

23
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
25