Objective C编写音乐播放器

        前段时间因为从手机上传的音乐都是.aac格式的,以前也不知道还有这种格式的音乐,还好mac上有自带的播放器来播放音乐,但是那个播放器确实不是很好用,每个aac文件都需要打开一个播放器,然后手动播放。确实很不好用,抱怨之余,就想着自己来动手编写一个播放器。仅供自己娱乐,肯定会有很多编程不当的地方,也给自己以后写代码一个参考吧。话不多说,开始动手了。

首先新建singleview工程,在viewcontroller里添加相应的按钮(播放,下一首,上一首,单曲循环),tableview用于显示歌曲列表,label用于显示当前的歌曲。界面如下图:

          在ViewController的类里添加tableview的两个代理<UITableViewDataSource,UITableViewDelegate>,然后在viewdidload里设置代理对象为self,注意一定要在viewdidload里设置。代码如下: 

    self.musicListTable.delegate = self;

    self.musicListTable.dataSource = self;

因为在xib中添加的控件都是在viewdidload前创建的,比init早,所以如果在init中设置代理对象的话,那个时候tableview的对象musicListTable还是nil。
   除了tableview所必需的两个代理,还有播放音乐对象的代理< AVAudioPlayerDelegate >后边会介绍相应的代理回调方法。
   设置属性及变量如下:

{

    AVAudioPlayer *_myMusicPlayer;

    NSInteger _currentMusicCount;       // 当前曲目位置

    NSInteger _allSongsNum;             // 所有曲目数

}


@property (strong, nonatomic) NSMutableArray *allSongsPathArray;

@property (strong, nonatomic) IBOutlet UIButton *playMusicButton;

@property (strong, nonatomic) IBOutlet UILabel  *MusicInfoShow;

@property (strong, nonatomic) IBOutlet UITableView *musicListTable;

@property (strong, nonatomic) NSMutableArray *musicNameArray;

@property (strong, nonatomic) IBOutlet UISlider *progressSlider;



 接着在ViewController的init方法里写入:

-(id)init

{

    self = [super init];

    if (self) {

        self.allSongsPathArray  = [[NSMutableArray alloc] initWithCapacity:0];

        self.musicNameArray = [[NSMutableArray alloc] initWithCapacity:0];

        _currentMusicCount = 0;

    }

    return self;

}


在initmusic的方法里写入:

-(void)initMusic

{

    NSString *path = MUSIC_PATH;   // MUSIC_PATH为音乐文件所在的路径

    NSArray *fileList = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil]

                         

                         pathsMatchingExtensions:[NSArray arrayWithObjects:@"aac",@"mp3", nil]];

    

    [fileList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        NSString *musicPath = [NSString stringWithFormat:@"%@/%@",path,(NSString *)obj];

//        [musicPath componentsSeparatedByString:@"/"];

        [self.musicNameArray addObject:obj];             // 设置数组存储所有的歌曲名

        [self.allSongsPathArray addObject:musicPath];    // 设置数组存储所有的歌曲所在的路径

    }];

    _allSongsNum = self.musicNameArray.count;

}


接下来是加载歌曲的方法

-(void)loadMusic:(NSString*)musicPath

{

    if ([[NSFileManager defaultManager] fileExistsAtPath:musicPath])

    {

        NSURL *musicURL = [NSURL fileURLWithPath:musicPath];

        NSError *myError = nil;

        // 创建播放器

        _myMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:musicURL error:&myError];

        _myMusicPlayer.delegate = self;


        if (_myMusicPlayer == nil)

        {

            NSLog(@"error %@",[myError description]);

        }

        

        [_myMusicPlayer setVolume:1];

        _myMusicPlayer.numberOfLoops = 0;

        [_myMusicPlayer prepareToPlay];

    }

}



下面分别是播放按键,下一首,上一首按键的响应事件

- (IBAction)play:(id)sender

{

    if(_myMusicPlayer.playing)

    {

        [sender setTitle:@"Pause"];

        [_myMusicPlayer pause];

    }

    else

    {

        [sender setTitle:@"Play"];

        [_myMusicPlayer play];

    }

}


- (IBAction)nextOne:(id)sender

{

    if (_currentMusicCount < _allSongsNum - 2) {

        _currentMusicCount++;

    }

    else

        _currentMusicCount = 0;

    

    [self musicPlayWithInfoShow];

}


- (IBAction)preforeOne:(id)sender

{

    if(_currentMusicCount > 0)

        _currentMusicCount--;

    else

        _currentMusicCount = _allSongsNum - 1;

    

    [self musicPlayWithInfoShow];

}


在viewdidload方法里写入

- (void)viewDidLoad {

    [super viewDidLoad];

    [self.navigationController setNavigationBarHidden:YES];

    self.musicListTable.delegate = self;

    self.musicListTable.dataSource = self;

    

    self.progressSlider.minimumValue = 0;

    self.progressSlider.maximumValue = 4.5;

    

    [self.musicListTable reloadData];

    [self initMusic];

    self.MusicInfoShow.text = [self.musicNameArray objectAtIndex:_currentMusicCount];

    [self loadMusic:[self.allSongsPathArray objectAtIndex:_currentMusicCount]];

    [_myMusicPlayer play];

}


单曲循环对应的事件

- (IBAction)singleCircleSwitch:(id)sender

{

    if ([sender isOn])

    {

        _myMusicPlayer.numberOfLoops = -1;

    }

    else

    {

        _myMusicPlayer.numberOfLoops = 0;

    }

}




因为有很几个方法都需要加载音乐,故而写一个方法,减少胶水代码

-(void)musicPlayWithInfoShow

{

    [self loadMusic:[self.allSongsPathArray objectAtIndex:_currentMusicCount]];

    self.MusicInfoShow.text = [self.musicNameArray objectAtIndex:_currentMusicCount];

    NSIndexPath *currentIndexPath = [NSIndexPath indexPathForRow:_currentMusicCount inSection:0];

    [self.musicListTable selectRowAtIndexPath:currentIndexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];

    [_myMusicPlayer play];

}



后边就是几个代理回调的方法实现啦

#pragma mark- 

#pragma Table View delegate


-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

    return _allSongsNum;

}


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    static NSString *CellIdentifier = @"MY_MUSIC_PLAYER_CELL_IDENTIFIER";

    

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)

    {

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    }

    

    cell.textLabel.text = [self.musicNameArray objectAtIndex:indexPath.row];

    return cell;

}


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

    _currentMusicCount = indexPath.row;

    [self musicPlayWithInfoShow];

}


- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

    return indexPath;

}


#pragma mark-

#pragma AVAudioPlayer Delegate

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag

{

    if (!flag) {

        return;

    }

    

    if(_currentMusicCount < _allSongsNum - 2)

        _currentMusicCount++;

    

    [self musicPlayWithInfoShow];

}


到此整个过程结束了。















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值