在iOS中使用控件播放audio

我做了一个tab bar,nav bar and table view的应用程序。

在表格视图中,您可以select听某些audio。

新的视图打开,我有一些控制,如:播放,暂停,音量滑块,进度滑块,标签与当前时间。

它工作,但不完美。 我可以播放audio,我可以暂停audio,也可以使用滑块前进或后退。 但现在:

当我点击导航栏上的“后退”button时,歌曲继续播放。 没关系,但是当我再次回到视图时,计时器和滑块会自行重置。 我不能暂停这首歌,只需等待util就停止播放。

另外,当我打了,回到桌面视图,select另一个文件播放,第一个文件不会停止播放

这是Audio1DetailViewController.h代码:

  #import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @interface Audio1DetailViewController: UIViewController <AVAudioPlayerDelegate> { IBOutlet UISlider *volumeControl; IBOutlet UILabel *timerLabel; IBOutlet UISlider *progressBar; AVAudioPlayer *audioPlayer; NSTimer *playbackTimer; } @property (nonatomic, retain) IBOutlet UISlider *volumeControl; @property (nonatomic, retain) IBOutlet UILabel *timerLabel; @property (nonatomic, retain) IBOutlet UISlider *progressBar; @property (nonatomic, retain) NSTimer *playbackTimer; @property (nonatomic, retain) AVAudioPlayer *audioPlayer; -(IBAction) playAudio; -(IBAction) stopAudio; -(IBAction) adjustVolume; -(IBAction) sliderChanged; @end 

这是Audio1DetailViewController.m代码:

  #import "Audio1DetailViewController.h" @implementation Audio1DetailViewController @synthesize volumeControl, timerLabel, playbackTimer, progressBar, audioPlayer; -(void)playAudio { playbackTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime) userInfo:nil repeats:YES]; [audioPlayer play]; } -(void)stopAudio { [playbackTimer invalidate]; [audioPlayer stop]; } -(void)adjustVolume { if (audioPlayer != nil) { audioPlayer.volume = volumeControl.value; } } -(void)updateTime { float minutes = floor(audioPlayer.currentTime/60); float seconds = audioPlayer.currentTime - (minutes * 60); float duration_minutes = floor(audioPlayer.duration/60); float duration_seconds = audioPlayer.duration - (duration_minutes * 60); NSString *timeInfoString = [[NSString alloc] initWithFormat:@"%0.0f.%0.0f / %0.0f.%0.0f", minutes, seconds, duration_minutes, duration_seconds]; timerLabel.text = timeInfoString; [timeInfoString release]; } - (void)viewDidLoad { [super viewDidLoad]; NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"001Fatiha" ofType:@"MP3"]]; NSError *error; audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; [[AVAudioSession sharedInstance] setActive: YES error: nil]; if (error) { NSLog(@"Error in audioPlayer: %@", [error localizedDescription]); } else { audioPlayer.delegate = self; [audioPlayer prepareToPlay]; } playbackTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateSlider) userInfo:nil repeats:YES]; progressBar.maximumValue = audioPlayer.duration; // Set the valueChanged target [progressBar addTarget:self action:@selector(sliderChanged:) forControlEvents: UIControl EventValueChanged]; } - (void)updateSlider { // Update the slider about the music time progressBar.value = audioPlayer.currentTime; } - (IBAction)sliderChanged:(UISlider *)sender { // Fast skip the music when user scroll the UISlider [audioPlayer stop]; [audioPlayer setCurrentTime:progressBar.value]; [audioPlayer prepareToPlay]; [audioPlayer play]; } -(void)audioPlayerDidFinishPlaying: (AVAudioPlayer *)player successfully:(BOOL)flag { } -(void)audioPlayerDecodeErrorDidOccur: (AVAudioPlayer *)player error:(NSError *)error { } -(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player { } -(void)audioPlayerEndInterruption:(AVAudioPlayer *)player { } -(void)viewDidUnload { audioPlayer = nil; volumeControl = nil; } -(void)dealloc { [audioPlayer release]; [volumeControl release]; [playbackTimer release]; [super dealloc]; } @end 

这是AudioTableViewController.h

  #import <UIKit/UIKit.h> @class Audio1DetailViewController; @interface AudioTableViewController : UITableViewController <UITableViewDelegate,UITableViewDataSource>{ IBOutlet UITableView *audioTableView; NSMutableArray *audioArray; Audio1DetailViewController *audio1DetailViewController; } @property (nonatomic, retain) NSMutableArray *audioArray; @property (nonatomic, retain) Audio1DetailViewController *audio1DetailViewController; @end 

和AudioTableViewController.m

  #import "AudioTableViewController.h" #import "Audio1DetailViewController.h" #import "DEQAppDelegate.h" @implementation AudioTableViewController @synthesize audioArray; @synthesize audio1DetailViewController; - (id)initWithStyle:(UITableViewStyle)style { self = [super initWithStyle:style]; if (self) { // Custom initialization { return self; } - (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. } #pragma mark - View lifecycle - (void)viewDidLoad{ [super viewDidLoad]; self.title = NSLocalizedString(@"Audio", @"Audio"); self.audioArray = [[NSArray alloc] initWithObjects: @"1. Het Begin", @"2. De Mensen", //etcetera nil]; // Uncomment the following line to preserve selection between presentations. self.clearsSelectionOnViewWillAppear = NO; // Uncomment the following line to display an Edit button in the navigation bar for this view controller. // self.navigationItem.rightBarButtonItem = self.editButtonItem; } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. self.audioArray = nil; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { #warning Potentially incomplete method implementation. // Return the number of sections. return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { #warning Incomplete method implementation. // Return the number of rows in the section. return [self.audioArray count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier] autorelease]; } // Configure the cell... cell.textLabel.text = [self.audioArray objectAtIndex:[indexPath row]]; return cell; } #pragma mark - Table view delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Navigation logic may go here. Create and push another view controller. NSUInteger row = indexPath.row; if (row == 0) { Audio1DetailViewController *audio1DetailViewController =[[Audio1DetailViewController alloc] initWithNibName:@"Audio1DetailViewController" bundle:nil]; audio1DetailViewController.title = @"Audio"; [self.navigationController pushViewController:audio1DetailViewController animated:YES]; [audio1DetailViewController release]; } if (row == 1) { //etcetera } } - (void)dealloc{ [audioArray release]; [super dealloc]; } @end 

我build议你创build一个全局播放器对象。 因为现在,每当您在导航控制器上推送此视图时,都会创build一个新视图。 这也意味着你没有任何参考前面的玩家(并不能阻止它)。 所以:声明AVAudioPlayer更高一级(在tableview中)。 现在,当你select一行时,把它分配给这个新视图(你链接的那个)的一个属性。

你使用故事板吗? 那么你必须实现prepareForSegue:方法。 给你的故事板上的segue一个标识符(如showPlayer和检查与if (segue.identifier isEqualToString:@"showPlayer") )。

现在在viewDidLoad检查audioPlayer是否为零。 如果你

 - (void)viewDidLoad { [super viewDidLoad]; if (audioPlayer == nil) { // your init (audioplayer =[[AVAudioPlayer ... } else { if (audioPlayer.isPlaying) { // ie pause the player or do other stuff } } } 

希望这可以帮助你。

另外 :不要张贴图片的代码。 只需在您的回复中插入代码或将其发布到像pastebin.com这样的网站,并在您的问题中链接该网页即可。 这使得其他人更容易回应,并提出如何改变你的代码的build议。

在回应你的评论 :相关的东西应该是: 在AudioTableViewController.h

 @property (strong, nonatomic) AVAudioPlayer *audioPlayer; 

在AudioTableViewController.m中

 @synthesize audioPlayer; ... - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Navigation logic may go here. Create and push another view controller. NSUInteger row = indexPath.row; if (row == 0) { self.audio1DetailViewController =[[Audio1DetailViewController alloc] initWithNibName:@"Audio1DetailViewController" bundle:nil]; self.audio1DetailViewController.title = @"Audio"; self.audio1DetailViewController.audioPlayer = self.audioPlayer; [self.navigationController pushViewController:self.audio1DetailViewController animated:YES]; [self.audio1DetailViewController release]; ... 

Audio1DetailViewController.m

 - (void)viewDidLoad { [super viewDidLoad]; NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"001Fatiha" ofType:@"MP3"]]; NSError *error; // this is the important part: if we already have something playing, stop it! if (audioPlayer != nil) { [audioPlayer stop]; } // everything else should happen as normal. audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; [[AVAudioSession sharedInstance] setActive: YES error: nil]; 

要停止同时播放2首歌曲,你应该这样做:

 - (void)viewWillDisappear:(BOOL)animated { audioPlayer = nil; volumeControl = nil; } 

为了更多的帮助播放audio,你可以使用苹果示例代码:

http://developer.apple.com/library/ios/#samplecode/avTouch/Introduction/Intro.html

令人惊讶的是MPMoviePlayerController还播放与控制的MP3播放器!

 self.moviePlayer=[[MPMoviePlayerController alloc] initWithContentURL:url]; [self.moviePlayer.view setFrame:CGRectMake(0, 0, self.videoContainer.bounds.size.width, self.videoContainer.bounds.size.height)]; self.moviePlayer.controlStyle=MPMovieControlStyleDefault; [self.videoContainer addSubview:self.moviePlayer.view]; [self.moviePlayer prepareToPlay]; [self.moviePlayer play];