2011-11-23 15 views
7

Tôi đã tạo một ứng dụng với tab bar,nav bar and table view.Phát âm thanh có các nút điều khiển trong iOS

Ở chế độ xem bảng, bạn có thể chọn nghe một số âm thanh.

Chế độ xem mới mở ra và ở đó tôi có một số điều khiển như: phát, tạm dừng, thanh trượt âm lượng, thanh trượt tiến trình, nhãn với thời gian hiện tại.

Nó hoạt động nhưng không hoàn hảo. Tôi có thể phát âm thanh, tôi có thể tạm dừng âm thanh, tôi cũng có thể sử dụng thanh trượt để bỏ qua hoặc tua lại. Nhưng bây giờ:

Khi tôi nhấn nút Quay lại trên thanh điều hướng, bài hát tiếp tục phát. Đó là ok, nhưng khi tôi trở lại xem lần nữa, bộ đếm thời gian và thanh trượt thiết lập lại chính mình. Tôi không thể tạm dừng bài hát, chỉ cần chờ đợi nó sẽ ngừng chơi.

Ngoài ra, khi tôi nhấn phát, quay lại chế độ xem bảng, chọn một tệp khác để phát, tệp đầu tiên sẽ không dừng phát.

Đây là mã 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 

Đây là mã 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 

Đây là 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 

Và 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 
+0

, Cũng [Xem của Apple Đốc.] (Http://developer.apple.com/library/ios/#documentation/mediaplayer/reference/MPMusicPlayerController_ClassReference/Reference/Reference.html) – HDdeveloper

Trả lời

9

Tôi khuyên bạn nên tạo đối tượng trình phát toàn cầu. Bởi vì ngay bây giờ, mỗi lần bạn đẩy chế độ xem này trên bộ điều khiển điều hướng, bạn tạo một chế độ xem mới. Điều này cũng có nghĩa là bạn không có bất kỳ tham chiếu nào đến trình phát trước đó (và không thể dừng nó). Vì vậy: khai báo AVAudioPlayer một bước cao hơn (trong bảng xem trước). Bây giờ, khi bạn chọn một hàng trong đó, gán nó vào một thuộc tính của khung nhìn mới này (cái mà bạn đã liên kết).

Bạn có làm việc với bảng phân cảnh không? Sau đó, bạn phải triển khai phương thức prepareForSegue:. Cung cấp cho segue của bạn trên bảng phân cảnh một định danh (như showPlayer và kiểm tra cho rằng với if (segue.identifier isEqualToString:@"showPlayer")).

Bây giờ, hãy thực hiện kiểm tra nếu audioPlayer là không. Nếu bạn

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

Hy vọng điều này sẽ giúp bạn.

Cũng: Không đăng hình ảnh mã. Chỉ cần chèn mã vào phản hồi của bạn hoặc đăng nó lên một trang như pastebin.com và liên kết trang đó trong câu hỏi của bạn. Điều này giúp người khác phản hồi và đưa ra đề xuất cách thay đổi mã của bạn dễ dàng hơn.

Đáp lại bình luận của bạn: Các công cụ liên quan nên là: Trong AudioTableViewController.h:

@property (strong, nonatomic) AVAudioPlayer *audioPlayer; 

Trong 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]; 
+0

Hey @ pxldlx, tnx cho câu trả lời.Tôi đã cố gắng nhưng thất bại. Nó chỉ đơn giản là những gì bạn nói, và nó có ý nghĩa. Nhưng tôi chỉ không nhận được nó, tôi nghĩ. Tôi đã tuyên bố AVAudioPlayer trong AudioTableViewController.h từ Audio1DetailViewController.h Sau đó, tôi chuyển toàn bộ mã (không phải là phần viewDidLoad) từ Audio1DetailViewController.m để AudioTableViewController.m Tôi cũng đã thay đổi File'sOwner trong tệp xib.I có thể phát bài hát, nhưng không phải bằng cách nhấn nút phát, nhưng bằng cách di chuyển thanh trượt tiến trình. Tôi đã thử một số thứ khác nhưng sau 2 ngày, tôi đã từ bỏ và xóa tất cả các thay đổi. – iHilas

+0

@iHilas Mh, ok. Nếu không nhìn vào mã của bạn, tôi có thể không thực sự giúp bạn nhiều. Bạn có thể chỉnh sửa câu hỏi ban đầu của mình và thêm một số mã (chủ yếu là mã mà bạn đã đăng dưới dạng hình ảnh nhưng lần này là văn bản vui lòng :)). Oh và một điều: Tôi không nghĩ rằng bạn phải thay đổi nhiều. Mọi thứ vẫn như cũ, nhưng bạn thay đổi "chủ sở hữu" của audioPlayer của bạn thành người giám sát đó (theo nghĩa là bộ điều khiển này có thuộc tính strong). Khi bạn đi qua bộ điều khiển mới, bạn đưa audioPlayer tham chiếu đến bộ điều khiển mới. –

+0

Tôi đã thêm mã của – iHilas

1

Đáng ngạc nhiên là các MPMoviePlayerController cũng đóng máy nghe nhạc MP3 với các điều khiển !!!

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]; 
+0

Đây là cách chính xác và dễ hiểu nhất để xử lý phát lại bằng các nút điều khiển. Trong iOS8, Apple đã thêm tính linh hoạt cao hơn cho những điều khiển bạn hiển thị (phát sóng, v.v.) –