iOS技术iOS开发系列iOS

iOS流媒体开发之二:滑动手势控制音量、亮度和进度

2016-07-11  本文已影响5202人  张云龙

尊重知识,转发请注明出处:iOS流媒体开发之二:滑动手势控制音量、亮度和进度


概要

看到文章的标题,小伙伴们大概会有两种反应:①这和流媒体技术没关系吧②网上有很多这个功能的实现方案。
1、对于第一种反应,从开发者的角度看这个确实不属于流媒体技术范畴,但是对于用户来讲这个已经是看视频时理所当然应该有的功能,密不可分,鉴于用户就是上帝,所以这个绝对属于流媒体范畴.
2、第二种反应确实是事实,但是能真正完美实现的不多。有6s Plus的小伙伴可以打开爱奇艺或者新浪微博,随便打开一个视频,手势增大音量出现音量无法调节到最大的bug,会剩余4格音量,只能先调节到很小的音量再次增大才可以到最大音量,当然这个是系统在6s上的一个bug,但并非无法解决,即使是爱奇艺和新浪也没有完美实现(您看到此文章的时候有可能已经修复此bug)。还有一点一般的实现方案是添加UIPanGestureRecognizer手势,这个方案如果只是简单的视频播放器或者写一个Demo完全没问题,可是放在一个稍微复杂点的视频播放器会引起很多问题,后面再说,因此我这里提供另一种方案。

新浪微博手势调节音量bug.png

思考

这个功能对于有一些开发经验的人来说并不难,只要勤快点,别遇到点难题没怎么思考就去找第三方库,都可以靠自己弄个八九不离十。我这里想通过这个功能向大家介绍我平时解决一些问题的心路历程,希望能帮到大家的不仅仅是技术本身,还有一种解决问题的能力。对于喜欢“废话少说,直接上代码”的小伙伴,这篇文章可能会让你有些不舒服,因为在我看来代码一文不值,值钱的是我们的思想,别急,咱们慢慢来。

行动

逻辑通了,方案有了,现在开始行动吧,首先你要有个可以播放视频demo,最好是点播视频,可参考上篇博文:iOS流媒体开发之一:总结系统提供的接口,这里不赘述。

.h文件

    #import <UIKit/UIKit.h>

    @protocol ZYLButtonDelegate <NSObject>

    /**
     * 开始触摸
     */
    - (void)touchesBeganWithPoint:(CGPoint)point;

    /**
     * 结束触摸
     */
    - (void)touchesEndWithPoint:(CGPoint)point;

    /**
     * 移动手指
     */
    - (void)touchesMoveWithPoint:(CGPoint)point;

    @end

    @interface ZYLButton : UIButton

    /**
     * 传递点击事件的代理
     */
    @property (weak, nonatomic) id <ZYLButtonDelegate> touchDelegate;

    @end

.m文件
#import "ZYLButton.h"

    @implementation ZYLButton

    //触摸开始
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        [super touchesBegan:touches withEvent:event];
        //获取触摸开始的坐标
        UITouch *touch = [touches anyObject];
        CGPoint currentP = [touch locationInView:self];
        [self.touchDelegate touchesBeganWithPoint:currentP];
    }

    //触摸结束
    - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        [super touchesEnded:touches withEvent:event];
        UITouch *touch = [touches anyObject];
        CGPoint currentP = [touch locationInView:self];
        [self.touchDelegate touchesEndWithPoint:currentP];
    }

    //移动
    - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
        UITouch *touch = [touches anyObject];
        CGPoint currentP = [touch locationInView:self];
        [self.touchDelegate touchesMoveWithPoint:currentP];
    }

    @end

注意:之所以选择UIButton有2点原因: 1、不用手动开启userInteractionEnabled用户交互 2、同时可以很方便的为UIButton添加Target,不需要像UIView那样在再定义一个UITapGestureRecognizer,当然UIButton添加各种状态的背景颜色各背景图也要比UIView方便得多。

在getter方法中初始化:
- (MPVolumeView *)volumeView {
if (_volumeView == nil) {
_volumeView = [[MPVolumeView alloc] init];
[_volumeView sizeToFit];
for (UIView view in [_volumeView subviews]){
if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
self.volumeViewSlider = (UISlider
)view;
break;
}
}
}
return _volumeView;
}

然后在开始触摸的代理里记录
#pragma mark - 开始触摸

    - (void)touchesBeganWithPoint:(CGPoint)point {
        //记录首次触摸坐标
        self.startPoint = point;
        //检测用户是触摸屏幕的左边还是右边,以此判断用户是要调节音量还是亮度,左边是亮度,右边是音量
        if (self.startPoint.x <= self.button.frame.size.width / 2.0) {
            //亮度
            self.startVB = [UIScreen mainScreen].brightness;
        } else {
            //音量
            self.startVB = self.volumeViewSlider.value;
        }
    }
    CMTime ctime = self.avPlayer.currentTime;
    self.startVideoRate = ctime.value / ctime.timescale / self.total;

注意: 1、前面提到一个增大音量的bug,我这里的解决办法是如果检测到用户设置的音量比系统当前的音量大于0.1,表示此时设置的音量已经无效了,然后把音量设置为0.1后再设置为我们设置无效的那个音量就可以了,具体做法参考代码; 2、在修改视频播放进度的时候,最好不在移动的方法中实时修改视频播放进度,一方面会造成卡顿的现象,一方面没有必要这么做,所以这里只是记录了用户想要调整的进度,然后在触摸结束的方法中设置进度; 3、这改变音量会调用系统自己的UI显示音量大小,但是在设置亮度的时候是系统没有提供相应的UI,需要我们自己设置,这个小伙伴们按照项目的需求自行添加一个UI效果就好了。

真机运行效果如图


Demo.png

尾巴

到这里我们就完成了手指滑动视频控制音量、亮度和进度的需求,大家在自己的项目中实际应用时还需要根据项目需要添加适当的UI,处理其他一些逻辑和业务流程。希望大家通过这个小小的示例可以有自己的解决问题的思路和流程,力争将一个即使很简单的功能做到尽量完美。Demo可以在这里下载:示例<small>Demo</small>

上一篇 下一篇

猜你喜欢

热点阅读