iOSで動画ストリーミング。簡単で十分なやり方。
動画ストリーミングを実装する機会があったので、まとめる。
やり方は大きくわけて2つ
- HTTP Live Streaming
- Media Player framework
前者を用いた場合の再生方法は
- AV Foundation framework
- OpenAL framework
などがあります。
やりたいこと
UITableViewCell上でサーバー上にある動画を再生する。
方針
今回の要件を満たすのには、Media Player frameworkで十分なので、これを使う。MPMoviePlayerControllerというクラスを用いる。これはiOS2.0からあるクラスなので、バージョン対応もバッチリ。
Media Player frameworkを使う上での注意点
- Simulator上で動かすことが出来ない場合がある。
- 複数の動画を同時に再生する事はできない。Media Player frameworkで新しい動画を再生し始めると、その直前に再生していた動画のキャッシュは削除される。
- ビデオの長さが10分以上、5分間のデータ量が5MB以上であれば、HTTP Live Streamingを用いる必要がある。
- アプリ側で動画をミュートできない
実装
まず、viewDidLoad
にてMPMoviePlayerController
を初期化する。
@interface JSKMainTableViewController () @property (nonatomic) MPMoviePlayerController *moviePlayer; @end static NSString *const kURLString = @"https://ia802302.us.archive.org/27/items/Pbtestfilemp4videotestmp4/video_test.mp4"; @implementation JSKMainTableViewController - (void)viewDidLoad { [super viewDidLoad]; self.moviePlayer = [[MPMoviePlayerController alloc] init]; // ストリーミングするため self.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming; self.moviePlayer.contentURL = [NSURL URLWithString:kURLString]; // UITableViewCell上に表示するため、動画操作パーツは非表示 [self.moviePlayer setControlStyle:MPMovieControlStyleNone]; // 動画をリピートする self.moviePlayer.repeatMode = MPMovieRepeatModeOne; }
このmoviePlayerを、- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
にてCellに渡す。
CellForRowAtIndexPath
で渡していないのは、Storyboard+Autolayoutを用い、UIViewの上に貼り付けているため、Viewが生成されるのを待つ必要があるため。
- (void)layoutWithUrl:(NSString *)url { // 貼り付ける予定のUIViewのサイズを取得 player.view.frame = _videoSuper.frame; [self.videoSuper addSubview: player.view]; // 再生 [player prepareToPlay]; [player play]; }
以上で再生ができる。
Cellが表示している時のみ動画再生
今回はCellが出現するタイミングで再生を実施したかったので、UITableViewCell内の[player play];
を削除し、UITableViewに以下を実装した。
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if ([cell.class isSubclassOfClass:JSKVideoTableViewCell.class]) { // 動画停止 [self.moviePlayer pause]; } } - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if ([cell.class isSubclassOfClass:JSKVideoTableViewCell.class]) { // 動画の貼り付け [(JSKVideoTableViewCell *)cell layoutWithPlayer:self.moviePlayer]; // 動画再生 [self.moviePlayer play]; } }
これにより、画面上にCellが表示されている時のみ動画が再生される。