iOS开发中音频工具类的封装以及音乐播放器的细节控制

一、控制器间数据传递

两个控制器之间数据的传递
第一种方法:

代码如下:

self.parentViewController.music=self.music[indexPath.row];

不能满足
第二种做法:把整个数组传递给它
第三种做法:设置一个数据源,设置播放控制器的数据源是这个控制器。self.parentViewController.dataSource=self;好处:没有耦合性,任何实现了协议的可以作为数据源。
第四种做法:把整个项目会使用到的音频资源交给一个工具类去管理,这样就不用传递过去了。直接向工具类索要资源就可以。
 
二、封装一个音频工具类
新建一个音频工具类,用来管理音乐数据(音乐模型)

工具类中的代码设计如下:

代码如下:

YYMusicTool.h文件
//
//  YYMusicTool.h
//

#import <Foundation/Foundation.h>
@class YYMusicModel;
@interface YYMusicTool : NSObject
/**
 *  返回所有的歌曲
 */
+ (NSArray *)musics;

/**
 *  返回正在播放的歌曲
 */
+ (YYMusicModel *)playingMusic;
+ (void)setPlayingMusic:(YYMusicModel *)playingMusic;

/**
 *  下一首歌曲
 */
+ (YYMusicModel *)nextMusic;

/**
 *  上一首歌曲
 */
+ (YYMusicModel *)previousMusic;
@end

YYMusicTool.m文件

代码如下:

//
//  YYMusicTool.m
//

#import "YYMusicTool.h"
#import "YYMusicModel.h"
#import "MJExtension.h"

@implementation YYMusicTool

static NSArray *_musics;
static  YYMusicModel *_playingMusic;

/**
 *  @return 返回所有的歌曲
 */
+(NSArray *)musics
{
    if (_musics==nil) {
        _musics=[YYMusicModel objectArrayWithFilename:@"Musics.plist"];
    }
    return _musics;
}

+(void)setPlayingMusic:(YYMusicModel *)playingMusic
{
    /*
     *如果没有传入需要播放的歌曲,或者是传入的歌曲名不在音乐库中,那么就直接返回
      如果需要播放的歌曲就是当前正在播放的歌曲,那么直接返回
     */
    if (!playingMusic || ![[self musics]containsObject:playingMusic]) return;
    if (_playingMusic == playingMusic) return;
    _playingMusic=playingMusic;
}
/**
 *  返回正在播放的歌曲
 */
+(YYMusicModel *)playingMusic
{
    return _playingMusic;
}

/**
 *  下一首歌曲
 */
+(YYMusicModel *)nextMusic
{
    //设定一个初值
    int nextIndex = 0;
    if (_playingMusic) {
        //获取当前播放音乐的索引
        int playingIndex = [[self musics] indexOfObject:_playingMusic];
        //设置下一首音乐的索引
        nextIndex = playingIndex+1;
        //检查数组越界,如果下一首音乐是最后一首,那么重置为0
        if (nextIndex>=[self musics].count) {
            nextIndex=0;
        }
    }
    return [self musics][nextIndex];
}

/**
 *  上一首歌曲
 */
+(YYMusicModel *)previousMusic
{
    //设定一个初值
    int previousIndex = 0;
    if (_playingMusic) {
        //获取当前播放音乐的索引
        int playingIndex = [[self musics] indexOfObject:_playingMusic];
        //设置下一首音乐的索引
        previousIndex = playingIndex-1;
        //检查数组越界,如果下一首音乐是最后一首,那么重置为0
        if (previousIndex<0) {
            previousIndex=[self musics].count-1;
        }
    }
    return [self musics][previousIndex];
}
@end

三、封装一个音乐播放工具类

该工具类中的代码设计如下:

YYAudioTool.h文件

代码如下:

//
//  YYAudioTool.h
//

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface YYAudioTool : NSObject
/**
 *播放音乐文件
 */
+(BOOL)playMusic:(NSString *)filename;
/**
 *暂停播放
 */
+(void)pauseMusic:(NSString *)filename;
/**
 *播放音乐文件
 */
+(void)stopMusic:(NSString *)filename;

/**
 *播放音效文件
 */
+(void)playSound:(NSString *)filename;
/**
 *销毁音效
 */
+(void)disposeSound:(NSString *)filename;
@end

YYAudioTool.m文件

代码如下:

//
//  YYAudioTool.m
//

#import "YYAudioTool.h"

@implementation YYAudioTool
/**
 *存放所有的音乐播放器
 */
static NSMutableDictionary *_musicPlayers;
+(NSMutableDictionary *)musicPlayers
{
    if (_musicPlayers==nil) {
        _musicPlayers=[NSMutableDictionary dictionary];
    }
    return _musicPlayers;
}

/**
 *存放所有的音效ID
 */
static NSMutableDictionary *_soundIDs;
+(NSMutableDictionary *)soundIDs
{
    if (_soundIDs==nil) {
        _soundIDs=[NSMutableDictionary dictionary];
    }
    return _soundIDs;
}

/**
 *播放音乐
 */
+(BOOL)playMusic:(NSString *)filename
{
    if (!filename) return NO;//如果没有传入文件名,那么直接返回
    //1.取出对应的播放器
    AVAudioPlayer *player=[self musicPlayers][filename];
   
    //2.如果播放器没有创建,那么就进行初始化
    if (!player) {
        //2.1音频文件的URL
        NSURL *url=[[NSBundle mainBundle]URLForResource:filename withExtension:nil];
        if (!url) return NO;//如果url为空,那么直接返回
       
        //2.2创建播放器
        player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
       
        //2.3缓冲
        if (![player prepareToPlay]) return NO;//如果缓冲失败,那么就直接返回
       
        //2.4存入字典
        [self musicPlayers][filename]=player;
    }
   
    //3.播放
    if (![player isPlaying]) {
        //如果当前没处于播放状态,那么就播放
        return [player play];
    }

return YES;//正在播放,那么就返回YES
}

+(void)pauseMusic:(NSString *)filename
{
    if (!filename) return;//如果没有传入文件名,那么就直接返回
   
    //1.取出对应的播放器
    AVAudioPlayer *player=[self musicPlayers][filename];
   
    //2.暂停
    [player pause];//如果palyer为空,那相当于[nil pause],因此这里可以不用做处理

}

+(void)stopMusic:(NSString *)filename
{
    if (!filename) return;//如果没有传入文件名,那么就直接返回
   
    //1.取出对应的播放器
    AVAudioPlayer *player=[self musicPlayers][filename];
   
    //2.停止
    [player stop];
   
    //3.将播放器从字典中移除
    [[self musicPlayers] removeObjectForKey:filename];
}

//播放音效
+(void)playSound:(NSString *)filename
{
    if (!filename) return;
    //1.取出对应的音效
    SystemSoundID soundID=[[self soundIDs][filename] unsignedIntegerValue];
   
    //2.播放音效
    //2.1如果音效ID不存在,那么就创建
    if (!soundID) {
       
        //音效文件的URL
        NSURL *url=[[NSBundle mainBundle]URLForResource:filename withExtension:nil];
        if (!url) return;//如果URL不存在,那么就直接返回
       
        OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
        NSLog(@"%ld",status);
        //存入到字典中
        [self soundIDs][filename]=@(soundID);
    }
   
    //2.2有音效ID后,播放音效
    AudioServicesPlaySystemSound(soundID);
}

//销毁音效
+(void)disposeSound:(NSString *)filename
{
    //如果传入的文件名为空,那么就直接返回
    if (!filename) return;
   
    //1.取出对应的音效
    SystemSoundID soundID=[[self soundIDs][filename] unsignedIntegerValue];
   
    //2.销毁
    if (soundID) {
        AudioServicesDisposeSystemSoundID(soundID);
       
        //2.1销毁后,从字典中移除
        [[self soundIDs]removeObjectForKey:filename];
    }
}
@end

四、在音乐播放控制器中的代码处理

YYPlayingViewController.m文件

代码如下:

//
//  YYPlayingViewController.m
//

#import "YYPlayingViewController.h"
#import "YYMusicTool.h"
#import "YYMusicModel.h"
#import "YYAudioTool.h"

@interface YYPlayingViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *songLabel;
@property (weak, nonatomic) IBOutlet UILabel *singerLabel;
@property (weak, nonatomic) IBOutlet UILabel *durationLabel;
@property(nonatomic,strong)YYMusicModel *playingMusic;
- (IBAction)exit;

@end

代码如下:

@implementation YYPlayingViewController
#pragma mark-公共方法
-(void)show
{
    //1.禁用整个app的点击事件
    UIWindow *window=[UIApplication sharedApplication].keyWindow;
    window.userInteractionEnabled=NO;
   
    //2.添加播放界面
    //设置View的大小为覆盖整个窗口
    self.view.frame=window.bounds;
    //设置view显示
    self.view.hidden=NO;
    //把View添加到窗口上
    [window addSubview:self.view];
   
    //3.检测是否换了歌曲
    if (self.playingMusic!=[YYMusicTool playingMusic]) {
        [self RresetPlayingMusic];
    }
   
    //4.使用动画让View显示
    self.view.y=self.view.height;
    [UIView animateWithDuration:0.25 animations:^{
        self.view.y=0;
    } completion:^(BOOL finished) {
       
        //设置音乐数据
        [self starPlayingMusic];
        window.userInteractionEnabled=YES;
    }];
}
#pragma mark-私有方法
//重置正在播放的音乐
-(void)RresetPlayingMusic
{
    //1.重置界面数据
    self.iconView.image=[UIImage imageNamed:@"play_cover_pic_bg"];
    self.songLabel.text=nil;
    self.singerLabel.text=nil;
   
    //2.停止播放
    [YYAudioTool stopMusic:self.playingMusic.filename];
}
//开始播放音乐数据
-(void)starPlayingMusic
{
    //1.设置界面数据
   
    //取出当前正在播放的音乐
//    YYMusicModel *playingMusic=[YYMusicTool playingMusic];
   
    //如果当前播放的音乐就是传入的音乐,那么就直接返回
    if (self.playingMusic==[YYMusicTool playingMusic]) return;
    //存取音乐
    self.playingMusic=[YYMusicTool playingMusic];
    self.iconView.image=[UIImage imageNamed:self.playingMusic.icon];
    self.songLabel.text=self.playingMusic.name;
    self.singerLabel.text=self.playingMusic.singer;
   
    //2.开始播放
    [YYAudioTool playMusic:self.playingMusic.filename];
   
}

#pragma mark-内部的按钮监听方法
//返回按钮
- (IBAction)exit {
    //1.禁用整个app的点击事件
    UIWindow *window=[UIApplication sharedApplication].keyWindow;
    window.userInteractionEnabled=NO;
   
    //2.动画隐藏View
    [UIView animateWithDuration:0.25 animations:^{
        self.view.y=window.height;
    } completion:^(BOOL finished) {
        window.userInteractionEnabled=YES;
        //设置view隐藏能够节省一些性能
        self.view.hidden=YES;
    }];
}
@end

注意:先让用户看到界面上的所有东西后,再开始播放歌曲。

提示:一般的播放器需要做一个重置的操作。
  当从一首歌切换到另外一首时,应该先把上一首的信息删除,因此在show动画显示之前,应该检测是否换了歌曲,如果换了歌曲,则应该做一次重置操作。
 实现效果(能够顺利的切换和播放歌曲,下面是界面显示):

五、补充代码

YYMusicsViewController.m文件

代码如下:

//
//  YYMusicsViewController.m
//

#import "YYMusicsViewController.h"
#import "YYMusicModel.h"
#import "MJExtension.h"
#import "YYMusicCell.h"
#import "YYPlayingViewController.h"
#import "YYMusicTool.h"

@interface YYMusicsViewController ()

@property(nonatomic,strong)YYPlayingViewController *playingViewController;
@end

代码如下:

@implementation YYMusicsViewController
#pragma mark-懒加载

-(YYPlayingViewController *)playingViewController
{
    if (_playingViewController==nil) {
        _playingViewController=[[YYPlayingViewController alloc]init];
    }
    return _playingViewController;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

#pragma mark - Table view data source
/**
 *一共多少组
 */
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}
/**
 *每组多少行
 */
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [YYMusicTool musics].count;
}
/**
 *每组每行的cell
 */
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    YYMusicCell *cell=[YYMusicCell cellWithTableView:tableView];
    cell.music=[YYMusicTool musics][indexPath.row];
    return cell;
}
/**
 *  设置每个cell的高度
 */
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 70;
}

/**
 *  cell的点击事件
 */
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //1.取消选中被点击的这行
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
   
    //2.设置正在播放的歌曲
    [YYMusicTool setPlayingMusic:[YYMusicTool musics][indexPath.row]];

//调用公共方法
    [self.playingViewController show];
   
//    //执行segue跳转
//    [self performSegueWithIdentifier:@"music2playing" sender:nil];
}
@end

六、一些细节控制
再来看一个实现的效果:

完整的代码

YYPlayingViewController.m文件

代码如下:

//
//  YYPlayingViewController.m
//  20-音频处理(音乐播放器1)
//
//  Created by apple on 14-8-13.
//  Copyright (c) 2014年 yangyong. All rights reserved.
//

#import "YYPlayingViewController.h"
#import "YYMusicTool.h"
#import "YYMusicModel.h"
#import "YYAudioTool.h"

@interface YYPlayingViewController ()
//进度条
@property (weak, nonatomic) IBOutlet UIView *progressView;
//滑块
@property (weak, nonatomic) IBOutlet UIButton *slider;
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *songLabel;
@property (weak, nonatomic) IBOutlet UILabel *singerLabel;
//当前播放的音乐的时长
@property (weak, nonatomic) IBOutlet UILabel *durationLabel;
//正在播放的音乐
@property(nonatomic,strong)YYMusicModel *playingMusic;
//音乐播放器对象
@property(nonatomic,strong)AVAudioPlayer *player;
//定时器
@property(nonatomic,strong)NSTimer *CurrentTimeTimer;
- (IBAction)exit;
- (IBAction)tapProgressBg:(UITapGestureRecognizer *)sender;
- (IBAction)panSlider:(UIPanGestureRecognizer *)sender;

@end

代码如下:

@implementation YYPlayingViewController
#pragma mark-公共方法
-(void)show
{
    //1.禁用整个app的点击事件
    UIWindow *window=[UIApplication sharedApplication].keyWindow;
    window.userInteractionEnabled=NO;
   
    //2.添加播放界面
    //设置View的大小为覆盖整个窗口
    self.view.frame=window.bounds;
    //设置view显示
    self.view.hidden=NO;
    //把View添加到窗口上
    [window addSubview:self.view];
   
    //3.检测是否换了歌曲
    if (self.playingMusic!=[YYMusicTool playingMusic]) {
        [self RresetPlayingMusic];
    }
   
    //4.使用动画让View显示
    self.view.y=self.view.height;
    [UIView animateWithDuration:0.25 animations:^{
        self.view.y=0;
    } completion:^(BOOL finished) {
       
        //设置音乐数据
        [self starPlayingMusic];
        window.userInteractionEnabled=YES;
    }];
}

#pragma mark-私有方法
//重置正在播放的音乐
-(void)RresetPlayingMusic
{
    //1.重置界面数据
    self.iconView.image=[UIImage imageNamed:@"play_cover_pic_bg"];
    self.songLabel.text=nil;
    self.singerLabel.text=nil;
   
    //2.停止播放
    [YYAudioTool stopMusic:self.playingMusic.filename];
    //把播放器进行清空
    self.player=nil;
   
    //3.停止定时器
    [self removeCurrentTime];
}
//开始播放音乐数据
-(void)starPlayingMusic
{
    //1.设置界面数据
   
    //如果当前播放的音乐就是传入的音乐,那么就直接返回
    if (self.playingMusic==[YYMusicTool playingMusic])
    {
        //把定时器加进去
        [self addCurrentTimeTimer];
        return;
    }
    //存取音乐
    self.playingMusic=[YYMusicTool playingMusic];
    self.iconView.image=[UIImage imageNamed:self.playingMusic.icon];
    self.songLabel.text=self.playingMusic.name;
    self.singerLabel.text=self.playingMusic.singer;
   
    //2.开始播放
    self.player = [YYAudioTool playMusic:self.playingMusic.filename];
   
    //3.设置时长
    //self.player.duration;  播放器正在播放的音乐文件的时间长度
    self.durationLabel.text=[self strWithTime:self.player.duration];
   
    //4.添加定时器
    [self addCurrentTimeTimer];
   
}

/**
 *把时间长度-->时间字符串
 */
-(NSString *)strWithTime:(NSTimeInterval)time
{
    int minute=time / 60;
    int second=(int)time % 60;
    return [NSString stringWithFormat:@"%d:%d",minute,second];
}

#pragma mark-定时器控制
/**
 *  添加一个定时器
 */
-(void)addCurrentTimeTimer
{
    //提前先调用一次进度更新,以保证定时器的工作时及时的
    [self updateCurrentTime];
   
    //创建一个定时器,每一秒钟调用一次
    self.CurrentTimeTimer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateCurrentTime) userInfo:nil repeats:YES];
    //把定时器加入到运行时中
    [[NSRunLoop mainRunLoop]addTimer:self.CurrentTimeTimer forMode:NSRunLoopCommonModes];
}
/**
 *移除一个定时器
 */
-(void)removeCurrentTime
{
    [self.CurrentTimeTimer invalidate];
   
    //把定时器清空
    self.CurrentTimeTimer=nil;
}

/**
 *  更新播放进度
 */
-(void)updateCurrentTime
{
    //1.计算进度值
    double progress=self.player.currentTime/self.player.duration;
   
    //2.计算滑块的x值
    // 滑块的最大的x值
    CGFloat sliderMaxX=self.view.width-self.slider.width;
    self.slider.x=sliderMaxX*progress;
    //设置滑块上的当前播放时间
    [self.slider setTitle:[self strWithTime:self.player.currentTime] forState:UIControlStateNormal];
   
    //3.设置进度条的宽度
    self.progressView.width=self.slider.center.x;
   
}

#pragma mark-内部的按钮监听方法
//返回按钮
- (IBAction)exit {
   
    //0.移除定时器
    [self  removeCurrentTime];
    //1.禁用整个app的点击事件
    UIWindow *window=[UIApplication sharedApplication].keyWindow;
    window.userInteractionEnabled=NO;
   
    //2.动画隐藏View
    [UIView animateWithDuration:0.25 animations:^{
        self.view.y=window.height;
    } completion:^(BOOL finished) {
        window.userInteractionEnabled=YES;
        //设置view隐藏能够节省一些性能
        self.view.hidden=YES;
    }];
}

/**
 *点击了进度条
 */
- (IBAction)tapProgressBg:(UITapGestureRecognizer *)sender {
    //获取当前单击的点
    CGPoint point=[sender locationInView:sender.view];
    //切换歌曲的当前播放时间
    self.player.currentTime=(point.x/sender.view.width)*self.player.duration;
    //更新播放进度
    [self updateCurrentTime];
}

- (IBAction)panSlider:(UIPanGestureRecognizer *)sender {
   
    //1.获得挪动的距离
    CGPoint t=[sender translationInView:sender.view];
    //把挪动清零
    [sender setTranslation:CGPointZero inView:sender.view];
   
    //2.控制滑块和进度条的frame
    self.slider.x+=t.x;
    //设置进度条的宽度
    self.progressView.width=self.slider.center.x;
   
    //3.设置时间值
    CGFloat sliderMaxX=self.view.width-self.slider.width;
    double progress=self.slider.x/sliderMaxX;
    //当前的时间值=音乐的时长*当前的进度值
    NSTimeInterval time=self.player.duration*progress;
    [self .slider setTitle:[self strWithTime:time] forState:UIControlStateNormal];
   
    //4.如果开始拖动,那么就停止定时器
    if (sender.state==UIGestureRecognizerStateBegan) {
        //停止定时器
        [self removeCurrentTime];
    }else if(sender.state==UIGestureRecognizerStateEnded)
    {
        //设置播放器播放的时间
        self.player.currentTime=time;
        //开启定时器
        [self addCurrentTimeTimer];
    }
}
@end

代码说明(一)

  调整开始播放音乐按钮,让其返回一个音乐播放器,而非BOOL型的。

代码如下:

/**
 *播放音乐
 */
+(AVAudioPlayer *)playMusic:(NSString *)filename
{
    if (!filename) return nil;//如果没有传入文件名,那么直接返回
    //1.取出对应的播放器
    AVAudioPlayer *player=[self musicPlayers][filename];
   
    //2.如果播放器没有创建,那么就进行初始化
    if (!player) {
        //2.1音频文件的URL
        NSURL *url=[[NSBundle mainBundle]URLForResource:filename withExtension:nil];
        if (!url) return nil;//如果url为空,那么直接返回
       
        //2.2创建播放器
        player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
       
        //2.3缓冲
        if (![player prepareToPlay]) return nil;//如果缓冲失败,那么就直接返回
       
        //2.4存入字典
        [self musicPlayers][filename]=player;
    }
   
    //3.播放
    if (![player isPlaying]) {
        //如果当前没处于播放状态,那么就播放
         [player play];
    }

return player;//正在播放,那么就返回YES
}

代码说明(二)

  把时间转换为时间字符串的方法:

代码如下:

/**
 *把时间长度-->时间字符串
 */
-(NSString *)strWithTime:(NSTimeInterval)time
{
    int minute=time / 60;
    int second=(int)time % 60;
    return [NSString stringWithFormat:@"%d:%d",minute,second];
}

代码说明(三)

  说明:进度控制

  监听当前的播放,使用一个定时器,不断的监听当前是第几秒。

  关于定时器的处理:这里使用了三个方法,分别是添加定时器,移除定时器,和更新播放进度。

注意细节:

(1)移除定时器后,对定时器进行清空处理。

代码如下:

/**
 *移除一个定时器
 */
-(void)removeCurrentTime
{
    [self.CurrentTimeTimer invalidate];
   
    //把定时器清空
    self.CurrentTimeTimer=nil;
}

(2)当看不到界面的时候,停止定时器。

(3)在开始播放音乐的方法中进行判断,如果当前播放的音乐和传入的音乐一致,那么添加定时器后直接返回。

(4)重置播放的音乐方法中,停止定时器。

代码说明(四)

  说明:点击和拖动进度条的处理

(1)点击进度条

  先添加单击的手势识别器。

往控制器拖线:

涉及的代码:

代码如下:

/**
 *点击了进度条
 */
- (IBAction)tapProgressBg:(UITapGestureRecognizer *)sender {
    //获取当前单击的点
    CGPoint point=[sender locationInView:sender.view];
    //切换歌曲的当前播放时间
    self.player.currentTime=(point.x/sender.view.width)*self.player.duration;
    //更新播放进度
    [self updateCurrentTime];
}

(2)拖拽进度条

  先添加拖拽手势识别器

往控制器拖线

涉及的代码:

代码如下:

/**
 *拖动滑块
 */
- (IBAction)panSlider:(UIPanGestureRecognizer *)sender {
   
    //1.获得挪动的距离
    CGPoint t=[sender translationInView:sender.view];
    //把挪动清零
    [sender setTranslation:CGPointZero inView:sender.view];
   
    //2.控制滑块和进度条的frame
    self.slider.x+=t.x;
    //设置进度条的宽度
    self.progressView.width=self.slider.center.x;
   
    //3.设置时间值
    CGFloat sliderMaxX=self.view.width-self.slider.width;
    double progress=self.slider.x/sliderMaxX;
    //当前的时间值=音乐的时长*当前的进度值
    NSTimeInterval time=self.player.duration*progress;
    [self .slider setTitle:[self strWithTime:time] forState:UIControlStateNormal];
   
    //4.如果开始拖动,那么就停止定时器
    if (sender.state==UIGestureRecognizerStateBegan) {
        //停止定时器
        [self removeCurrentTime];
    }else if(sender.state==UIGestureRecognizerStateEnded)
    {
        //设置播放器播放的时间
        self.player.currentTime=time;
        //开启定时器
        [self addCurrentTimeTimer];
    }
}

(0)

相关推荐

  • iOS利用AVPlayer播放网络音乐的方法教程

    前言 假如你现在打算做一个类似百度音乐.豆瓣电台的在线音乐类APP,你会怎样做? 首先了解一下音频播放的实现级别: (1) 离线播放:这里并不是指应用不联网,而是指播放本地音频文件,包括先下完完成音频文件再进行播放的情况,这种使用AVFoundation里的AVAudioPlayer可以满足 (2) 在线播放:使用AVFoundation的AVPlayer可以满足 (3) 在线播放同时存储文件:使用AudioFileStreamer + AudioQueue 可以满足 (4) 在线播放且带有音效

  • 讲解iOS开发中对音效和音乐播放的简单实现

    音效的播放 一.简单介绍 简单来说,音频可以分为2种 (1)音效 又称"短音频",通常在程序中的播放时长为1~2秒 在应用程序中起到点缀效果,提升整体用户体验 (2)音乐 比如游戏中的"背景音乐",一般播放时间较长 框架:播放音频需要用到AVFoundation.framework框架 二.音效的播放 1.获得音效文件的路径 复制代码 代码如下: NSURL *url = [[NSBundle mainBundle] URLForResource:@"m_

  • iOS App中实现播放音效和音乐功能的简单示例

    播放音效 iOS开发过程中可能会遇到播放音效的功能 其实很简单,iOS已经提供了一个框架直接负责播放音效 AudioToolbox.framework 新建项目  TestWeChatSounds 给新建的项目导入AudioToolbox.framework 导入成功之后如下图 项目目录如下 接下来我们给项目中添加几个caf格式的音效文件 接下来 我们打开 项目默认生成的ViewController中添加代码 导入 AudioToolbox 复制代码 代码如下: #import <AudioTo

  • 运用iOS教你轻松制作音乐播放器

    本文实例为大家分享了iOS音乐播放器制作的具体代码,供大家参考,具体内容如下 效果图 目录结构 代码 // // ViewController.m // 播放音乐 // // Created by xubh on 2017/3/24. // Copyright © 2017年 xubh. All rights reserved. // #import "ViewController.h" #import <AVFoundation/AVFoundation.h> @inte

  • ios开发:一个音乐播放器的设计与实现案例

    这个Demo,关于歌曲播放的主要功能都实现了的.下一曲.上一曲,暂停,根据歌曲的播放进度动态滚动歌词,将当前正在播放的歌词放大显示,拖动进度条,歌曲跟着变化,并且使用Time Profiler进行了优化,还使用XCTest对几个主要的类进行了单元测试. 已经经过真机调试,在真机上可以后台播放音乐,并且锁屏时,显示一些主要的歌曲信息. 根据歌曲的播放来显示对应歌词的.用UITableView来显示歌词,可以手动滚动界面查看后面或者前面的歌词. 并且,当拖动进度条,歌词也会随之变化,下一曲.上一曲依

  • iOS视频添加背景音乐同时保留原音

    话不多说,请看代码: //抽取原视频的音频与需要的音乐混合 -(void)addmusic:(id)sender { [MBProgressHUDshowHUDAddedTo:self.viewanimated:YES]; AVMutableComposition *composition =[AVMutableCompositioncomposition]; audioMixParams =[[NSMutableArrayalloc]initWithObjects:nil]; //录制的视频

  • iOS实现获取系统iTunes音乐的方法示例

    播放音乐库中的音乐 音乐是iOS的重要组成播放,无论是iPod.iTouch.iPhone还是iPad都可以在iTunes购买音乐或添加本地音乐到音乐库中同步到你的iOS设备. 本文将给大家详细介绍关于iOS获取系统iTunes音乐的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 首先来看看效果图 简介 获取类型iTune音乐非常类似于UIKit框架中UIImagePickerController图片选取器的用法,既可以直接使用系统自带的媒体选择器也可以只获取系统的数

  • iOS中关于音乐锁屏控制音乐(锁屏信息设置)的实例代码

    废话不多说了,直接给大家贴代码了,具体代码如下所示: <pre name="code" class="objc">appDelegate里面加入如下代码获取后台播放权限</pre><pre name="code" class="objc">- (void)setAudioBackstagePlay{ AVAudioSession *audioSession = [AVAudioSession

  • 实例解析iOS中音乐播放器应用开发的基本要点

    一.调整项目的结构,导入必要的素材 调整后的项目结构如下: 二.新建两个控制器 (1)新建一个控制器,用于展示音乐文件列表界面,其继承自UITableViewController (2)新建一个控制器,用于展示播放界面,其继承自UIViewController (3)在storyboard中,把之前的控制器删除,换上一个导航控制器,设置tableViewController与之前新建的控制器类进行关联 三.音乐文件列表控制器中基本界面的搭建 (1)新建一个音乐文件的模型 根据plist文件建立模

  • iOS实现播放远程网络音乐的核心技术点总结

    一.前言 这两天做了个小项目涉及到了远程音乐播放,因为第一次做这种音乐项目,边查资料边做,其中涉及到主要技术点有: 如何播放远程网络音乐 如何切换当前正在播放中的音乐资源 如何监听音乐播放的各种状态(播放器状态.播放的进度.缓冲的进度,播放完成) 如何手动操控播放进度 如何在后台模式或者锁屏情况下正常播放音乐 如何在锁屏模式下显示音乐播放信息和远程操控音乐 如果您对一块技术点有兴趣或者正在寻找相关资料,那么本篇或许能提供一些参考或启发. 二. 网络音乐播放的核心技术点 根据自己的经验和查了一些音

随机推荐