[英]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.