如何在 AVAudioPlayer 中循环播放多个音频文件?
Posted
技术标签:
【中文标题】如何在 AVAudioPlayer 中循环播放多个音频文件?【英文标题】:How to play multiple audio files in sequence by loop in AVAudioPlayer? 【发布时间】:2013-02-05 08:55:24 【问题描述】:我想通过循环播放多个文件。 我在下面写了代码.. 请帮帮我!!...
soundList = [[NSArray alloc] initWithObjects:@"mySong1.mp3",@"mySong2.mp3",@"mySong3.mp3",@"mySong4.mp3",@"mySong5.mp3",@"mySong6.mp3",@"mySong7.mp3",@"mySong8.mp3",@"mySong9.mp3", nil];
for (i=0; i<=([soundList count] - 1); )
while(i<[soundList count])
NSLog(@"File is : %@",[soundList objectAtIndex:i]);
mediaPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:[soundList objectAtIndex:i] ofType:nil]] error:&error];
[mediaPlayer setDelegate:self];
self.lblCurrentSongName.text = [soundList objectAtIndex:i];
[mediaPlayer prepareToPlay];
i++;
请给我建议.!!..
【问题讨论】:
【参考方案1】:我会给你一个指导方针,但要注意它不是经过测试的代码。您提供的代码由于多种原因无法正常工作,1.您没有在 avaudioplayer 上调用 play 2.while 循环执行速度太快,歌曲将相互重叠,或者因为您没有存储对先前 avaudioplayer 的引用它可能会造成麻烦(不知道确切)
NSInteger currentSoundsIndex; //Don't forget to set this in viewDidLoad or elsewhere
//In viewDidLoad add this line
...
currentSoundsIndex = 0;
...
-(void) playCurrentSong
NSError *error;
mediaPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:[soundList objectAtIndex:currentSoundsIndex] ofType:nil]] error:&error];
if(error !=nil)
NSLog(@"%@",error);
//Also possibly increment sound index and move on to next song
else
self.lblCurrentSongName.text = [soundList objectAtIndex:currentSoundsIndex];
[mediaPlayer setDelegate:self];
[mediaPlayer prepareToPlay]; //This is not always needed, but good to include
[mediaPlayer play];
//This is the delegate method called after the sound finished playing, there are also other methods be sure to implement them for avoiding possible errors
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
//Increment index but don't go out of bounds
currentSoundsIndex = ++currentSoundsIndex % [soundList count];
[self playCurrentSong];
【讨论】:
HI guenis .. 我试过了,它是成功的,但它不会自动播放下一首歌。我应该为此采取行动。请帮我自动播放所有歌曲。再次感谢.. 我已经编辑了代码,注意到 [mediaPlayer setDelegate:self] 现在在 playCurrentSong 中。事实证明,当您分配新的 avaudioplayer 时,您需要再次将委托设置为 vc,否则不会调用 audioPlayerDidFinishPlaying 方法并且它不会自动播放下一首歌曲,我的错误 别忘了在你的界面上设置。 只需在.play()
为我工作之前添加 .prepareToPlay()
【参考方案2】:
先声明
AVAudioPlayer *audioPlayer;
NSMutableArray *audioQueue;
然后使用下面的代码
-(void) addToPlayerQueue: (NSString *) file
if ( [audioQueue count] == 0 )
[audioQueue addObject:file];
[self playSound: file];
else
[audioQueue addObject:file];
-(void) playSound : (NSString *) soundFile
NSURL *soundUrl = [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:soundFile ofType:@"caf"]];
if ( soundUrl )
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
[audioPlayer setDelegate:self];
[audioPlayer setVolume: playerVolume];
[audioPlayer play];
#pragma mark -
#pragma mark AVAudioPlayer Delegate Method
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
NSLog(@"Just got done playing %@", [audioQueue objectAtIndex:0]);
[audioPlayer release];
[audioQueue removeObjectAtIndex:0];
if ( [audioQueue count] > 0 )
NSString *file = [audioQueue objectAtIndex:0];
[self playSound:file];
【讨论】:
【参考方案3】:可能没有最优雅的解决方案,但您会在这里找到一个共同的想法。这是一个完全有效的代码,您可以将其复制/粘贴到您的项目中,它应该可以工作。当然,您必须更改文件名。如果您有任何问题,请告诉我。
#import "MainViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface MainViewController () <AVAudioPlayerDelegate>
@property (nonatomic, strong) AVAudioPlayer *audioPlayer;
@property (nonatomic, strong) NSMutableArray *soundsPathsList;
@property (nonatomic, assign) NSInteger curSoundIdx;
@end
@implementation MainViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
// Custom initialization
NSArray *soundList = [[NSArray alloc] initWithObjects:@"myAudioFile 1", @"myAudioFile 2", @"myAudioFile 3",
@"myAudioFile 4", @"myAudioFile 5", @"myAudioFile 6", @"myAudioFile 7",
@"myAudioFile 8", @"myAudioFile 9", @"myAudioFile 10", nil];
self.soundsPathsList = [NSMutableArray new];
for (NSString *fileName in soundList)
NSString *pathToFile = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp3"];
NSURL *url = [NSURL fileURLWithPath:pathToFile];
[self.soundsPathsList addObject:url];
[self playNext];
return self;
- (void) playNext
if (self.curSoundIdx >= [self.soundsPathsList count])
self.curSoundIdx = 0;
// destroy player object
[self.audioPlayer stop];
self.audioPlayer = nil;
// create new player object
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:
[self.soundsPathsList objectAtIndex:self.curSoundIdx] error:nil];
self.audioPlayer.delegate = self;
[self.audioPlayer play];
self.curSoundIdx++;
#pragma mark - AVAudioPlayerDelegate
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
[self playNext];
@end
【讨论】:
【参考方案4】:simply do it by using recursion ..
@property (nonatomic, strong) NSArray *arrTrackList;
@property (nonatomic, strong) NSMutableArray *arrAduioQueue;
@property (nonatomic, strong) AVAudioPlayer *audioPlayer;
@property (nonatomic) NSUInteger itemIndex;
@end
@implementation PLayMultipleTrackViewController
- (void)viewDidLoad
[super viewDidLoad];
self.arrTrackList = [NSArray arrayWithObjects:@"apple_ring",@"shukriya_pakistan",@"pakistan_anthem", nil];
self.itemIndex = 0;
- (IBAction)TrackToPlay:(id)sender
self.btnPlayAll.enabled = NO;
NSString *trackFile = [self.arrTrackList objectAtIndex:self.itemIndex];
[self AddToPlayList:trackFile];
-(void)AddToPlayList:(NSString *)file
[self.arrAduioQueue addObject:file];
[self playTrack:file];
-(void)playTrack:(NSString *)soundFile
NSString *soundFilePath =[[NSBundle mainBundle] pathForResource: soundFile ofType: @"m4r"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
self.audioPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL: fileURL error: nil];
[self.audioPlayer prepareToPlay];
[self.audioPlayer setDelegate:self];
self.audioPlayer.volume = 1.0;
[self.audioPlayer play];
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
[self.arrAduioQueue removeObjectAtIndex:0];
self.itemIndex++;
NSUInteger trackListIndex = [self.arrTrackList count];
if (self.itemIndex < trackListIndex)
NSString *nextTrack = [self.arrTrackList objectAtIndex:self.itemIndex];
[self AddToPlayList:nextTrack];
else
NSLog(@"PLaylist empty");
@end
【讨论】:
以上是关于如何在 AVAudioPlayer 中循环播放多个音频文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何让用户选择 AVAudioPlayer 播放音频的循环次数
如何使用 AVAudioPlayer 连续播放多个音频文件?