2011-11-23 13 views
7

He creado una aplicación con tab bar,nav bar and table view.Reproducción de audio con controles en iOS

En la vista de tabla puede elegir escuchar algo de audio.

Se abre una nueva vista y allí tengo algunos controles como: reproducir, pausar, deslizador de volumen, control deslizante de progreso, etiqueta con la hora actual.

Funciona, pero no es perfecto. Puedo reproducir el audio, puedo pausar el audio, también puedo usar el control deslizante para saltar hacia adelante o hacia atrás. Pero ahora:

Cuando presiono el botón Atrás en la barra de navegación, la canción sigue sonando. Está bien, pero cuando vuelvo a la vista, el temporizador y el deslizador se reinician. No puedo pausar la canción, solo necesito esperar a que deje de reproducirse.

Además, cuando golpeo juego, volver a la vista de tabla, elija otro archivo para jugar, la primera archivo no se detendrá.

Este es el código 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 

Este es el código 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 

Aquí está el 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 

Y el 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

, también [Ver Manzana Doc.] (Http://developer.apple.com/library/ios/#documentation/mediaplayer/reference/MPMusicPlayerController_ClassReference/Reference/Reference.html) – HDdeveloper

Respuesta

9

Le sugiero que cree un objeto de jugador global. Porque ahora mismo, cada vez que presionas esta vista en el controlador de navegación, creas una nueva. Esto también significa que no tiene ninguna referencia al jugador anterior (y no puede detenerlo). Entonces: declare el AVAudioPlayer un paso más arriba (en la vista de tabla). Ahora, cuando seleccione una fila en él, asígnelo a una propiedad de esta nueva vista (la que ha vinculado).

¿Usted trabaja con el guión gráfico? Luego debe implementar el método prepareForSegue:. Dé a su segue en el guión gráfico un identificador (como showPlayer y verifique eso con if (segue.identifier isEqualToString:@"showPlayer")).

Ahora en su viewDidLoad haga una comprobación si audioPlayer es nulo. Si

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

Espero que esto te ayude.

También: No publique imágenes del código. Simplemente inserte el código en su respuesta o publíquelo en un sitio como pastebin.com y enlace esa página en su pregunta. Esto hace que sea más fácil para otros responder y hacer sugerencias sobre cómo modificar su código.

En respuesta a tu comentario: El material debe ser relevante: En AudioTableViewController.h:

@property (strong, nonatomic) AVAudioPlayer *audioPlayer; 

En 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 para la respuesta. Lo he intentado pero fallado. Parece simple lo que dijiste, y tiene sentido. Pero creo que no lo entiendo. que han declarado la AVAudioPlayer en el AudioTableViewController.h del Audio1DetailViewController.h Luego se trasladó todo el código (no la parte viewDidLoad) de la Audio1DetailViewController.m a AudioTableViewController.m También ha cambiado la File'sOwner en el archivo xib. Puedo reproducir la canción, pero no presionando el botón reproducir, sino moviendo el control deslizante de progreso. Intenté algunas otras cosas, pero después de 2 días, me di por vencido y deshice todos los cambios. – iHilas

+0

@iHilas Mh, está bien. Sin mirar tu código realmente no puedo ayudarte mucho. ¿Puedes editar tu pregunta original y agregar algún código (principalmente ese código que ya has publicado como imagen, pero esta vez como texto, por favor :)). Ah, y una cosa: no creo que tengas que cambiar tanto. Todo permanece igual, pero cambia el "propietario" de su audioPlayer a esa supervista (en el sentido de que este controlador tiene una propiedad strong). Cuando atraviesa ese nuevo controlador, pasa la referencia audioPlayer al nuevo controlador. –

+0

He agregado el código – iHilas

1

Sorprendentemente, el MPMoviePlayerController también juega reproductor de MP3 con mandos !!!

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

Esta es la manera correcta y más directa de lidiar con la reproducción con controles. En iOS8, Apple agregó aún más flexibilidad a los controles que se muestran (cobertura aérea, etc.) –

Cuestiones relacionadas