2012年12月30日日曜日

Sample Code - AVLoupe



カメラロール内のビデオを選択すると、再生中の動画上でルーペ(拡大鏡)が使えるようになる。


ポイントは2つのAVPlayerLayerを合成しているところ。
@property AVPlayer *player;
@property AVPlayerLayer *zoomPlayerLayer;
@property AVPlayerLayer *mainPlayerLayer;
mainPlayerLayer は通常の動画再生レイヤーで、zoomPlayerLayerがルーペ内の拡大された動画再生レイヤーになる。どちらも -[AVPlayerLayer playerLayerWithPlayer:] から取得した AVPlayerの動作再生レイヤー。このメソッドを使うと再生中の動画を複数のレイヤーで同時に表示することができる(って今回初めて知った)。この性質を利用して、zoomPlayerLayerに変形とマスクを適用することでループを表現している。

以下はzoomPlayerLayerの生成部分
// Set up the zoom AVPlayerLayer.
self.zoomPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
CGSize zoomSize = CGSizeMake(self.view.layer.bounds.size.width * ZOOM_FACTOR,
 self.view.layer.bounds.size.height * ZOOM_FACTOR);
self.zoomPlayerLayer.frame = CGRectMake((contentLayer.bounds.size.width /2) - (zoomSize.width /2),
(contentLayer.bounds.size.height /2) - (zoomSize.height /2),zoomSize.width,zoomSize.height);

[contentLayer addSublayer:self.zoomPlayerLayer];
[self.loupeView.layer addSublayer:contentLayer];

丸く切り取るマスク
// The content layer has a circular mask applied.
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = contentLayer.bounds;

CGMutablePathRef circlePath = CGPathCreateMutable();
CGPathAddEllipseInRect(circlePath, NULL, CGRectInset(
self.loupeView.layer.bounds, LOUPE_BEZEL_WIDTH , LOUPE_BEZEL_WIDTH));

maskLayer.path = circlePath;
CGPathRelease(circlePath);

動画再生の変形と合成がこんなに簡単にできるとは。これは色々と応用できそう。

0 件のコメント:

コメントを投稿