转载

AVPlayerLayer

AVPlayerLayer是一个CALayer的subclass,它是属于另一个framework,AVFoundation framework。它主要用来在iOS中播放视频内容,实际上,例如MPMoviePlayer里面的底层播放实现用的都是它。使用起来很简单,1、创建实例;2、播放操作

我们可以用下面这个简单的例子演示一下这个的用法

- (void)testPlayerLayer {     UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];     containerView.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));     [self.view addSubview:containerView];      // get video url     NSURL *url = [[NSBundle mainBundle] URLForResource:@"Ship" withExtension:@"mp4"];      // Create player and player layer, need <AVFoundation/AVFoundation.h>     AVPlayer *player = [AVPlayer playerWithURL:url];     AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];      // Set player frame and attach to our view     playerLayer.frame = containerView.bounds;     [containerView.layer addSublayer:playerLayer];      [player play]; }

效果就如下图所示

AVPlayerLayer

使用方法就是这样,在这里要说的是,AVPlayerLayer既然是一个CALayer的subclass,那么我们就可以像对待一个普通的CALayer来对待它,使用CALayer的一些方法,比如transform,roundedCorner这些效果都可以加在它上面,还是用例子说话。

- (void)test3DPlayerLayer {     UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];     containerView.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));     [self.view addSubview:containerView];      // get video url     NSURL *url = [[NSBundle mainBundle] URLForResource:@"Ship" withExtension:@"mp4"];      // Create player and player layer, need <AVFoundation/AVFoundation.h>     AVPlayer *player = [AVPlayer playerWithURL:url];     AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];      // Set player frame and attach to our view     playerLayer.frame = containerView.bounds;     [containerView.layer addSublayer:playerLayer];      // Transform layer     CATransform3D transform = CATransform3DIdentity;     transform.m34 = -1.0 / 500.0f;     transform = CATransform3DRotate(transform, M_PI_4, 1, 1, 0);     playerLayer.transform = transform;      // Add rounded corners and border     playerLayer.masksToBounds = YES;     playerLayer.cornerRadius = 20.0f;     playerLayer.borderColor = [UIColor redColor].CGColor;     playerLayer.borderWidth = 5.0f;      [player play]; }

经过3D变换,加圆角,加边框后的效果如下

AVPlayerLayer

代码不难,不过我要解释一下下面这几句关于3D变换的操作

CATransform3D transform = CATransform3DIdentity;     transform.m34 = -1.0 / 500.0f;     transform = CATransform3DRotate(transform, M_PI_4, 1, 1, 0);     playerLayer.transform = transform;

3D变换在iOS中是通过使用矩阵乘法运算来得出最终各个坐标点的,原理是下面的图

AVPlayerLayer

矩阵乘法是怎么运算的就不在这里讲了,网上很容易找到,另外就是在iOS设备上xyz各个轴的定义,以及如何围绕的轴来旋转

AVPlayerLayer

在iOS提供的transform的API中,不需要我们直接来进行矩阵运算,只需要我们指定旋转所需要的参数,其中有角度(单位是弧度),以及是按照哪个轴进行旋转。常用的有下面两个函数

CATransform3D transform = CATransform3DMakeRotation(M_PI_4, 0, 1, 0); transform = CATransform3DRotate(transform, M_PI_4, 1, 1, 0);

第一个函数是从基本面开始,进行的绝对值旋转,4个参数,分别代表了角度,x,y,z,这里是按照y轴旋转了PI/4, PI是180度,也就是相当于旋转了45度,x和z的值为0,也就是不旋转的意思。第二个函数是在第一个transform的基础上继续进行旋转,旋转是既在x轴旋转,也在y轴旋转。

如果大家实验一下,发现其实旋转后的效果怪怪得,

AVPlayerLayer

比如只执行第一个函数的话,可能觉得图片仅仅变窄了(旋转前的原图是个正方形),看不出有旋转的感觉。这是因为没有使用Perspective Projection的原因,Perspective Projection在用户看来,应该是离我们近的,会大一些,离我们远得的看上去会比较小才正确。这个效果是否体现出来,其实是由矩阵中的m34值来决定的

AVPlayerLayer

也就是红圈圈里面的那个,这个值可以设置为 -1/d,d是相当于我们的眼睛与图片的距离,一般来说,对于iOS的应用,我们使用的d值的范围在500~1000之间,值越小,效果越明显,越大,效果越不明显,我们可以看一下m34的设置和使用方法

CATransform3D transform = CATransform3DIdentity; //apply perspective transform.m34 = - 1.0 / 500.0; //rotate by 45 degrees along the Y axis transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0); //apply to layer self.layerView.layer.transform = transform;

AVPlayerLayer

这回效果出来了吧!

CATransform3DIdentity,这个值在矩阵运算中,相当于什么都没干,也就是说,任意一个坐标跟CATransform3DIdentity做乘法运算时,计算后的结果不会变化。

有了这些说明,文章中第一个例子的各条语句在理解上应该都没有问题了。

原文  http://shellcodes.sinaapp.com/articles/540
正文到此结束
Loading...