iOS使用AVPlayer自定义视频播放器

作者: 九剑仙 | 来源:发表于2017-04-15 19:41 被阅读1981次

    上一篇:iOS使用AVPlayer自定义音频播放器
    iOS内部提供的有三种视频播放的方式,且都能播放本地、远程音频、视频文件。

    1. AVPlayer,基于Layer显示,具有高度的灵活性,可根据需要自定义UI,实现起来相对麻烦
    2. MPMoviePlayerController,自带播放控制面板,可控性低
    3. MPMoviePlayerViewController,高度封装,播放界面默认就是全屏的,如果播放功能比较简单,建议用这个。

    这篇文章,我们主要讲一下第一种播放方式<AVPlayer>,毕竟后两种方式的可控性太低了,根本满足不了我们蛋疼的项目经理的要求。

    LLVideoPlayer-横屏.png LLVideoPlayer-竖屏.png
    蛋疼的项目经理让我们模仿优酷、模仿爱奇艺,可怜我们做的只是一款社交聊天软件,呜呼哀哉~

    我写了一个简单的demo,页面相当精简,但是该实现的功能都实现了,左边调节亮度、右边调节声音等等也都实现了,有兴趣的童鞋可以下载看一下。

    github地址:https://github.com/wangzhaomeng/LLVideoPlayer

    延伸知识

    我们的项目是这种要求,只有在播放视频的页面才支持横屏其他页面都是竖屏,因此,需要做以下处理,首先:

    屏幕快照 2017-04-15 下午7.27.37.png
    然后,重点中的重点,在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里面注释的很详细,不懂的地方欢迎留言。

    觉得好,请给个star,谢谢!

    相关文章

      网友评论

      • 街角仰望:你好 请问_progressSlider滑块推动到最后视频会倒退一点继续播放是什么原因导致的?
      • CoderXLL:有没有考虑到边下边播,以及实时监控网速等功能
        CoderXLL:@九剑仙 嗯嗯,没事的。去年有段时间了解下边下边播,做完之后有瑕疵,所以想一起探讨下
        九剑仙:好久没看过代码了。。
      • 一月与二十四:大佬 我一直没看懂这段代码 能否帮忙解释一下。
        CGFloat rate = self.startVideoRate + (panPoint.x * 180 / (self.bounds.size.width * self.dur));
        具体就是这个比例是怎么计算滑动的进度的
        九剑仙:@Lee_iOS 谢谢:pray:
        Lee_iOS:@九剑仙 特地登录来给你点赞
        九剑仙:那我先换一种写法:CGFloat rate = self.startVideoRate+(panPoint.x/self.bounds.size.width);
        这个就容易看懂了吧,初始进度+屏幕滑动的比例。但是这样就有很大的弊端,因为"+"后面的值的取值范围是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;
      • 法克君:请问,为什么我在真机上跑的时候会在LLAVPlayerView.m中的item.observer = self;这里崩溃啊
        法克君:@九剑仙 谢谢,改过以后就没问题了。但是可以解释下为什么换一种创建方式就没事了么?
        当时我的崩溃消息是'-[AVPlayerItem setObserver:]: unrecognized selector sent to instance 0x13e68c1d0'
        九剑仙:已经改好,把item的创建方式换成这样:LLAVPlayerItem *item = [[LLAVPlayerItem alloc] initWithAsset:asset];
        九剑仙:@法克君 有崩溃日志吗,我试了几个手机都没事
      • 不余先生:支持一下!
      • 不余先生:大神,我算是挖坟了,能不能把demo放到百度网盘上,git上老是下载中途断掉!
        不余先生:@九剑仙 谢谢!我已经下载了,慢慢看你的demo学习!
        九剑仙:@a1203302261 下了吗。。。最近有点忙,没时间更新简书了
      • 秋雨无痕:呵呵,我也写过一个,因为支持的格式太少,完成VLCkit UI部分不用改
      • 九剑仙:如有雷同,纯属巧合!

      本文标题:iOS使用AVPlayer自定义视频播放器

      本文链接:https://www.haomeiwen.com/subject/ifcoattx.html