美文网首页OC开发iOS技术点
iOS播放音乐,音量淡出暂停效果

iOS播放音乐,音量淡出暂停效果

作者: ziooooo | 来源:发表于2016-04-01 09:33 被阅读895次

    在开发过程中,使用到了音频的播放AVAudioPlayer,其中的-(void)pause;暂停播放的方法暂停时过于生硬。于是我试着暂停时使音量逐渐降低,达到淡出的效果。

    音量、逐渐、降低,看这几个词我决定使用一个定时器修改AVAudioPlayer实例的volume属性直到值为0,来实现这个效果。


    首先为AVAudioPlayer创建一个分类

    @interface AVAudioPlayer (Category)
    
    -(void)graduallyPasue;
    
    @end
    

    下面按照之前的想法来简单实现以下音量逐渐降低,在.m文件中

    -(void)graduallyPasue
    {
        //用GCD创建一个计时器
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        //0.1秒执行一次
        dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 0.1 * NSEC_PER_SEC, 0);
        dispatch_source_set_event_handler(_timer, ^{
            //每次音量 -0.1
            self.volume -= 0.1;
            if (self.volume < 0) {//音量小于0时结束定时器
                dispatch_source_cancel(_timer);
            }
        });
        dispatch_source_set_cancel_handler(_timer, ^{
            //结束时,暂停
            [self pause];
        });
        dispatch_resume(_timer);
    }
    

    上面的代码中,如果原来的音量是1.0,那么就需要1s的时间来暂停音乐,暂时先这么写,以后再做优化。

    接下来试一试-(void)graduallyPasue的效果,我的使用场景是暂停一首音乐,继续播放下一首音乐。这时问题出现了:

    • 如果是用的是同一个AVAudioPlayer实例来播放音乐的话,第一首音乐并没有声音淡出的效果,并且第二首音乐声音逐渐变小直到暂停。
    • 如果不是同一个AVAudioPlayer实例来播放音乐的话,第二首音乐会在第一首音乐没有暂停时就开始播放。

    造成这种问题的原因就是播放第二首音乐的代码,在第一首暂停方法未执行完毕的时候就开始执行了。那么我们使用GCD提供的dipatch group来保持队列同步,使计时器结束后再执行后面的代码。

    -(void)graduallyPasue
    {
        dispatch_group_t group = dispatch_group_create();
        dispatch_group_enter(group);
        
        //用GCD创建一个计时器
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        //0.1秒执行一次
        dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 0.1 * NSEC_PER_SEC, 0);
        dispatch_source_set_event_handler(_timer, ^{
            //每次音量 -0.1
            self.volume -= 0.1;
            if (self.volume < 0) {//音量小于0时结束定时器
                dispatch_source_cancel(_timer);
            }
        });
        dispatch_source_set_cancel_handler(_timer, ^{
            //结束时,暂停
            [self pause];
            
            dispatch_group_leave(group);
        });
        dispatch_resume(_timer);
        
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    }
    

    这样用起来就好多了,那么再优化一下,可以控制暂停时淡出的时间。

    -(void)graduallyPasueWithDuration:(NSTimeInterval)duration
    {
        //频率
        static NSTimeInterval frequency = 0.05;
        //定时器执行次数
        __block int overCount = duration / frequency;
        //声音每次降低的偏移量
        float volumeOffset = self.volume / overCount;
        
        dispatch_group_t group = dispatch_group_create();
        dispatch_group_enter(group);
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), frequency * NSEC_PER_SEC, 0);
        dispatch_source_set_event_handler(_timer, ^{
            overCount -= 1;
            self.volume -= volumeOffset;
            if (overCount < 0) {
                dispatch_source_cancel(_timer);
            }
        });
        dispatch_source_set_cancel_handler(_timer, ^{
            [self pause];
            dispatch_group_leave(group);
        });
        dispatch_resume(_timer);
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    }
    

    修改一下.h的方法名,就可以使用了。


    第一次发文章,热爱技术的大家,欢迎交流啊!

    相关文章

      网友评论

        本文标题:iOS播放音乐,音量淡出暂停效果

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