我已经为这个问题苦苦挣扎了很长一段时间。
我正在尝试制作一个包含播放列表并仅播放存储在应用程序中的音乐文件的播放器。
现在,我正在使用 AVAudioPlayer 播放 mp3 文件。我的问题是,当我加载播放列表时,我无法停止播放以前的 mp3,因此我在第一个音频和我从播放列表加载的所有其他音频文件之间得到混合声音。
所以,这是我的代码:
#import "MainViewController.h"
#import <Foundation/Foundation.h>
#pragma mark Audio session callbacks_______________________
@implementation MainViewController
@synthesize artworkItem;
@synthesize userMediaItemCollection;
@synthesize playBarButton;
@synthesize pauseBarButton;
@synthesize musicPlayer;
@synthesize navigationBar;
@synthesize noArtworkImage;
@synthesize backgroundColorTimer;
@synthesize nowPlayingLabel, AudFile;
@synthesize appSoundButton;
@synthesize addOrShowMusicButton;
@synthesize appSoundPlayer;
@synthesize soundFileURL;
@synthesize interruptedOnPlayback;
@synthesize playedMusicOnce;
@synthesize playing;
#pragma mark Music control________________________________
- (IBAction) playOrPauseMusic: (id)sender {
}
- (IBAction) AddMusicOrShowMusic: (id) sender {
[audioPlayer stop];
// Load the Playlist direcly
MusicTableViewController *controller = [[MusicTableViewController alloc] initWithNibName: @"MusicTableView" bundle: nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController: controller animated: YES];
[controller release];
}
#pragma mark Application playback control_________________
- (IBAction) playAppSound: (id) sender {
// [appSoundPlayer play];
// playing = YES;
// [appSoundButton setEnabled: NO];
}
// delegate method for the audio route change alert view; follows the protocol specified
// in the UIAlertViewDelegate protocol.
- (void) alertView: routeChangeAlertView clickedButtonAtIndex: buttonIndex {
if ((NSInteger) buttonIndex == 1) {
[appSoundPlayer play];
} else {
[appSoundPlayer setCurrentTime: 0];
[appSoundButton setEnabled: YES];
}
[routeChangeAlertView release];
}
#pragma mark AV Foundation delegate methods____________
- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) appSoundPlayer successfully: (BOOL) flag {
}
- (void) audioPlayerBeginInterruption: player {
}
- (void) audioPlayerEndInterruption: player {
}
#pragma mark Table view delegate methods________________
// Invoked when the user taps the Done button in the table view.
- (void) musicTableViewControllerDidFinish: (MusicTableViewController *) controller {
[self dismissModalViewControllerAnimated: YES];
}
#pragma mark Application setup____________________________
#if TARGET_IPHONE_SIMULATOR
#warning *** Simulator mode: iPod library access works only when running on a device.
#endif
//play audio 2
- (void)playAudio2:(NSString*) name type:(NSString*)type
{
[self stopAudio];
[audioPlayer stop];
[audioPlayer release];
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:name
ofType:type]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
if (error)
{
NSLog(@"Error in audioPlayer: %@",
[error localizedDescription]);
} else {
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
}
[audioPlayer play];
}
-(void)playAudio
{
[appSoundPlayer play];
}
- (void)stopAudio
{
[appSoundPlayer stop];
}
// Configure the application.
- (void) viewDidLoad {
[super viewDidLoad];
[self setPlayedMusicOnce: NO];
[self setNoArtworkImage: [UIImage imageNamed: @"no_artwork.png"]];
[self setPlayBarButton: [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemPlay
target: self
action: @selector (playOrPauseMusic:)]];
[self setPauseBarButton: [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemPause
target: self
action: @selector (playOrPauseMusic:)]];
[addOrShowMusicButton setTitle: NSLocalizedString (@"Add Music", @"Title for 'Add Music' button, before user has chosen some music")
forState: UIControlStateNormal];
[appSoundButton setTitle: NSLocalizedString (@"Play App Sound", @"Title for 'Play App Sound' button")
forState: UIControlStateNormal];
[nowPlayingLabel setText: NSLocalizedString (@"Instructions", @"Brief instructions to user, shown at launch")];
// Configure a timer to change the background color. The changing color represents an
// application that is doing something else while iPod music is playing.
[self setBackgroundColorTimer: [NSTimer scheduledTimerWithTimeInterval: 3.5
target: self
selector: @selector (updateBackgroundColor)
userInfo: nil
repeats: YES]];
[self setupAudioSession];
}
// Invoked by the backgroundColorTimer.
- (void) updateBackgroundColor {
[UIView beginAnimations: nil context: nil];
[UIView setAnimationDuration: 3.0];
CGFloat redLevel = rand() / (float) RAND_MAX;
CGFloat greenLevel = rand() / (float) RAND_MAX;
CGFloat blueLevel = rand() / (float) RAND_MAX;
self.view.backgroundColor = [UIColor colorWithRed: redLevel
green: greenLevel
blue: blueLevel
alpha: 1.0];
[UIView commitAnimations];
}
#pragma mark Application state management_____________
- (void) didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void) viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
-(void) setupAudioSession
{
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *setCategoryError = nil;
[audioSession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
if (setCategoryError){/* Handle Error COndition*/}
NSError *activationError = nil;
[audioSession setActive:YES error:&activationError];
if (activationError){
/*handle error*/
}
}
// just for test , delete after
-(void) myInstanceMethod: (id)sender{
[self setupAudioSession];
[audioPlayer stop];
[audioPlayer release];
AudFile = sender;
NSLog(@"My Instance metthod called ok with item : %@", sender);
[self playAudio2:[NSString stringWithFormat:@"%@",AudFile] type:@"mp3"];
//[self setupApplicationAudio: sender];
NSLog(@"New Audfile is: %@", AudFile);
// [self setupApplicationAudio];
}
+(void) myClassMethod{
NSLog(@"Class Called ok");
}
- (void)dealloc {
/*
// This sample doesn't use libray change notifications; this code is here to show how
// it's done if you need it.
[[NSNotificationCenter defaultCenter] removeObserver: self
name: MPMediaLibraryDidChangeNotification
object: musicPlayer];
[[MPMediaLibrary defaultMediaLibrary] endGeneratingLibraryChangeNotifications];
*/
[[NSNotificationCenter defaultCenter] removeObserver: self
name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification
object: musicPlayer];
[[NSNotificationCenter defaultCenter] removeObserver: self
name: MPMusicPlayerControllerPlaybackStateDidChangeNotification
object: musicPlayer];
[musicPlayer endGeneratingPlaybackNotifications];
[musicPlayer release];
[artworkItem release];
[backgroundColorTimer invalidate];
[backgroundColorTimer release];
[navigationBar release];
[noArtworkImage release];
[nowPlayingLabel release];
[pauseBarButton release];
[playBarButton release];
[soundFileURL release];
[userMediaItemCollection release];
[super dealloc];
}
我正在将播放列表中的文件名发送到我的播放器
-(void) myInstanceMethod: (id)sender{
[self setupAudioSession];
[audioPlayer stop];
[audioPlayer release];
AudFile = sender;
NSLog(@"My Instance metthod called ok with item : %@", sender);
[self playAudio2:[NSString stringWithFormat:@"%@",AudFile] type:@"mp3"];
//[self setupApplicationAudio: sender];
NSLog(@"New Audfile is: %@", AudFile);
// [self setupApplicationAudio];
}
我使用方法中的 UIModalTransition 从我的主视图控制器加载我的播放列表
- (IBAction) AddMusicOrShowMusic: (id) sender {
[audioPlayer stop];
// Load the Playlist direcly
MusicTableViewController *controller = [[MusicTableViewController alloc] initWithNibName: @"MusicTableView" bundle: nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController: controller animated: YES];
[controller release];
}
正如你所看到的,当我加载我的播放列表时,我告诉播放器停止播放
[audioPlayer stop];
但由于某种原因,它无法停止播放,因此会产生声音重叠。
这是我正在尝试解决的问题。
谢谢
和最好的问候!