视频播放横竖屏切换

之前很长一段时间都在做视频相关的项目,其中一个最基础最重要的功能就是播放时的横竖屏切换,于是乎研究对比了下市场上主要视频类APP的横竖屏切换方式。发现共分为两种,一种以优酷视频和土豆视频为代表,当横放手机时整个界面都旋转;另一种以腾讯视频,搜狐视频为代表,当横放手机时只是播放的小视图旋转,其余内容不变。实现方法分别如下。

切换方式1(同优酷视频)

controller支持横竖屏切换

控制整个controller的view支持横竖屏切换的几个方法

1
2
3
4
5
6
7
8
9
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}

监测屏幕方向变化

添加监测屏幕方向变化的通知

1
2
3
4
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationHasChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
}

屏幕方向变化时的处理

通知的回调方法中如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
- (void)orientationHasChange:(NSNotification *)notification {
UIDevice *device = (UIDevice *)notification.object;
if(device.orientation == UIInterfaceOrientationLandscapeLeft){
[self rotateToLandscapeLeft];
}
else if(device.orientation == UIInterfaceOrientationLandscapeRight){
[self rotateToLandscapeRight];
}
else if(device.orientation == UIInterfaceOrientationPortrait){
[self rotateToPortrait];
}
}
- (void)rotateToFullScreen {
if(SCREEN_WIDTH>SCREEN_HEIGHT){
_videoPlayManageView.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
}
else{
_videoPlayManageView.frame = CGRectMake(0, 0, SCREEN_HEIGHT, SCREEN_WIDTH);
}
[_videoPlayManageView enterInFullScreen];
}
- (void)rotateToLandscapeLeft {
if(_lastOrientationValue==UIInterfaceOrientationLandscapeLeft){
return;
}
[self rotateToFullScreen];
_lastOrientationValue = UIInterfaceOrientationLandscapeLeft;
}
- (void)rotateToLandscapeRight {
if(_lastOrientationValue==UIInterfaceOrientationLandscapeRight){
return;
}
[self rotateToFullScreen];
_lastOrientationValue = UIInterfaceOrientationLandscapeRight;
}
- (void)rotateToPortrait {
if(_lastOrientationValue==UIInterfaceOrientationPortrait){
return;
}
_videoPlayManageView.frame = _normalScreenFrame;
[_videoPlayManageView exitFromFullScreen];
_lastOrientationValue = UIInterfaceOrientationPortrait;
}

强制切换

如果想强制播放器横屏或者竖屏播放,可以这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- (void)videoPlayManageViewExitFullScreenButtonTapped {
if([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]){
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = UIInterfaceOrientationPortrait;
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
[UIViewController attemptRotationToDeviceOrientation];
}
- (void)videoPlayManageViewEnterFullScreenButtonTapped {
if([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]){
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = UIInterfaceOrientationLandscapeRight;
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
[UIViewController attemptRotationToDeviceOrientation];
[self rotateToLandscapeRight];
}

切换方式2(同腾讯视频)

controller仅支持竖屏

此时控制整个controller的view仅支持默认的竖屏即可

1
2
3
- (BOOL)shouldAutorotate {
return NO;
}

监测屏幕方向变化

仍然添加监测屏幕方向变化的通知

1
2
3
4
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationHasChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
}

屏幕方向变化时的处理

通知的回调方法中如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
- (void)orientationHasChange:(NSNotification *)notification {
UIDevice *device = (UIDevice *)notification.object;
if(device.orientation == UIInterfaceOrientationLandscapeLeft){
[self rotateToLandscapeLeft];
}
else if(device.orientation == UIInterfaceOrientationLandscapeRight){
[self rotateToLandscapeRight];
}
else if(device.orientation == UIInterfaceOrientationPortrait){
[self rotateToPortrait];
}
}
- (void)rotateToFullScreen {
if(SCREEN_WIDTH>SCREEN_HEIGHT){
_videoPlayManageView.frame = CGRectMake(0, 0, SCREEN_HEIGHT, SCREEN_WIDTH);
}
else{
_videoPlayManageView.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
}
[_videoPlayManageView enterInFullScreen];
}
- (void)rotateToLandscapeLeft {
if(_lastOrientationValue==UIInterfaceOrientationLandscapeLeft){
return;
}
[UIView animateWithDuration:0.3 animations:^{
_videoPlayManageView.transform = CGAffineTransformMakeRotation(-M_PI/2);
[self rotateToFullScreen];
} completion:^(BOOL finished) {
}];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:NO];
_lastOrientationValue = UIInterfaceOrientationLandscapeLeft;
}
- (void)rotateToLandscapeRight {
if(_lastOrientationValue==UIInterfaceOrientationLandscapeRight){
return;
}
[UIView animateWithDuration:0.3 animations:^{
_videoPlayManageView.transform = CGAffineTransformMakeRotation(M_PI/2);
[self rotateToFullScreen];
} completion:^(BOOL finished) {
}];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
_lastOrientationValue = UIInterfaceOrientationLandscapeRight;
}
- (void)rotateToPortrait {
if(_lastOrientationValue==UIInterfaceOrientationPortrait){
return;
}
[[UIApplication sharedApplication] setStatusBarHidden:NO];
[UIView animateWithDuration:0.3 animations:^{
_videoPlayManageView.transform = CGAffineTransformIdentity;
_videoPlayManageView.frame = _normalScreenFrame;
[_videoPlayManageView exitFromFullScreen];
} completion:^(BOOL finished) {
}];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
_lastOrientationValue = UIInterfaceOrientationPortrait;
}

强制切换

如果想强制播放器横屏或者竖屏播放,可以这样

1
2
3
4
5
6
- (void)videoPlayManageViewExitFullScreenButtonTapped {
[self rotateToPortrait];
}
- (void)videoPlayManageViewEnterFullScreenButtonTapped {
[self rotateToLandscapeRight];
}

完整版Demo请猛戳这里