簡體   English   中英

在iOS中使用控件播放音頻

[英]Playing audio with controls in iOS

我制作了一個帶tab bar,nav bar and table view的應用程序。

在表格視圖中,您可以選擇收聽某些音頻。

新視圖打開,我有一些控件,如:播放,暫停,音量滑塊,進度滑塊,標簽與當前時間。

它有效但不完美。 我可以播放音頻,我可以暫停音頻,我也可以使用滑塊向前或向后跳過。 但現在:

當我按下導航欄上的“后退”按鈕時,歌曲會繼續播放。 沒關系,但是當我再次回到視圖時,計時器和滑塊會自行重置。 我不能暫停這首歌,只需要等待它停止播放。

另外,當我點擊播放時,返回表格視圖,選擇要播放的另一個文件,第一個文件不會停止播放

這是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

我建議你創建一個全局播放器對象。 因為現在,每次在導航控制器上推送此視圖時,都會創建一個新視圖。 這也意味着您沒有任何對前一個玩家的引用(並且無法阻止它)。 所以:聲明AVAudioPlayer更高一步(在tableview中)。 現在,當您在其中選擇一行時,將其分配給此新視圖的屬性(您鏈接的屬性)。

你是否使用故事板? 然后你必須實現方法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)
         {
             // i.e. pause the player or do other stuff
         }
    }
}

希望這對你有所幫助。

另外 :不要發布代碼圖像。 只需在您的回復中插入代碼或將其發布到像pastebin.com這樣的網站,並在您的問題中鏈接該頁面。 這使得其他人更容易回復並提出如何更改代碼的建議。

回應你的評論 :相關的東西應該是: 在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;
}

有關播放音頻的更多幫助,您可以使用Apple示例代碼:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM