上一篇:iOS使用AVPlayer自定义音频播放器
iOS内部提供的有三种
视频播放的方式,且都能播放本地、远程
的音频、视频
文件。
- AVPlayer,基于Layer显示,具有高度的
灵活性
,可根据需要自定义UI,实现起来相对麻烦
。 - MPMoviePlayerController,自带播放控制面板,
可控性低
。 - MPMoviePlayerViewController,
高度封装
,播放界面默认就是全屏的,如果播放功能比较简单
,建议用这个。
这篇文章,我们主要讲一下第一种播放方式<AVPlayer>
,毕竟后两种方式的可控性太低了,根本满足不了我们蛋疼的项目经理
的要求。
蛋疼的项目经理
让我们模仿优酷、模仿爱奇艺
,可怜我们做的只是一款社交聊天软件
,呜呼哀哉~
我写了一个简单的demo,页面相当精简,但是该实现的功能都实现了,左边调节亮度
、右边调节声音
等等也都实现了,有兴趣的童鞋可以下载看一下。
延伸知识
我们的项目是这种要求,只有在播放视频的页面才支持横屏
,其他页面都是竖屏
,因此,需要做以下处理,首先:
然后,
重点中的重点
,在AppDelegate中实现如下方法:屏幕快照 2017-04-15 下午7.30.11.png
//只支持竖屏
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskPortrait;
}
之后在需要横屏的试图控制器中,监听当前手机的横竖屏状态,使用代码强制旋转屏幕
:
- (void)viewDidLoad {
[super viewDidLoad];
//监听横竖屏切换
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
//横竖屏切换
- (void)orientationChanged:(NSNotification *)notification {
UIDeviceOrientation currentOrientation = [UIDevice currentDevice].orientation;
if (currentOrientation == UIDeviceOrientationFaceUp) return;
static CGFloat rotation;
if (currentOrientation == UIDeviceOrientationLandscapeLeft) {
rotation = 0.5;
}
else if (currentOrientation == UIDeviceOrientationLandscapeRight) {
rotation = -0.5;
}
else {
rotation = 0;
}
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.25 animations:^{
self.view.transform = CGAffineTransformMakeRotation(M_PI*(rotation));
self.view.frame = SCREEN_BOUNDS;
}];
});
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
播放过程中的具体细节处理,demo里面注释的很详细,不懂的地方欢迎留言。
网友评论
CGFloat rate = self.startVideoRate + (panPoint.x * 180 / (self.bounds.size.width * self.dur));
具体就是这个比例是怎么计算滑动的进度的
这个就容易看懂了吧,初始进度+屏幕滑动的比例。但是这样就有很大的弊端,因为"+"后面的值的取值范围是0-1,那么问题就来了,假如视频时长为200分钟,屏幕宽400(只是假如),那么平均滑动2个像素,视频就会快进1分钟,比例系数太大而导致难以准确定位。
所以现在换一种写法:CGFloat rate = self.startVideoRate+(panPoint.x/self.bounds.size.width)*(180/self.dur);在屏幕滑动比例的基础上,乘以(180秒所占视频总长度的比例),这样做的结果是,保证滑动一次屏幕,视频最多快进3分钟,已达到可以准确定位的目的。
其实这样写还有点bug,没有考虑视频长度小于3分钟的情况,加个判断,应该是下面这种:
CGFloat scale = (self.dur > 180 ? 180/self.dur : 1.0);
CGFloat rate = self.startVideoRate+(panPoint.x/self.bounds.size.width)*scale;
当时我的崩溃消息是'-[AVPlayerItem setObserver:]: unrecognized selector sent to instance 0x13e68c1d0'