在 iOS 中使用控件播放音频

2023-12-19

我制作了一个应用程序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 声明高一级(在表视图中)。现在,当您在其中选择一行时,将其分配给这个新视图(您链接的视图)的属性。

你使用故事板吗?然后你必须实现该方法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
         }
    }
}

希望这对您有帮助。

Also:不要发布代码图像。只需在您的回复中插入代码或将其发布到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];
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 iOS 中使用控件播放音频 的相关文章

随机推荐

  • 创建自托管 Web API 还是使用 Asp.Net Core Web API?

    我有两个选择 如果我使用自行托管 Web ApiOWIN Katana我可以获得性能提升 但如上所述here https forums asp net t 1908235 aspx Self hosting or IIS hosted 我必
  • Rails 按创建日期对记录进行分组

    所以我有一个模型 我想检索记录并按created at字段的日期对它们进行分组 但created at是一个日期时间字段 我只对日期部分感兴趣 所以我正在寻找类似二维数组的东西 第一层是一个以日期字符串为键的哈希 第二层是带有记录的数组 我
  • 我如何子类化 threading.Event?

    在 Python 2 7 5 中 from threading import Event class State Event def init self name super Event self init self name name d
  • Asp.Net MVC 4 中的自定义 URL 路由

    我怎样才能像这个网址一样 http www domain com friend content title http www domain com friendly content title 在 Asp Net MVC 4 中 注意 该参
  • 如何设置GAE环境特定的环境变量?

    我在 Go 中有一个 GAE 应用程序 使用martini https github com go martini martini 我需要能够设置MARTINI ENV环境变量告诉 martini 它应该使用生产设置进行初始化 根据Pyth
  • 仅包含 ASCII 字符的 UNICODE 字符串是否始终等于 ASCII 字符串?

    我注意到以下几点 gt gt gt u abc abc True gt gt gt abc u abc True 这总是正确的还是可能取决于系统区域设置 在 python 3 中字符串似乎是 unicode 例如这个问题 https sta
  • 如何删除 openlayer 中的特定标记

    这是来自 capdragon 更新的新代码 但现在它不会创建标记 我现在不知道如何解决这个问题 我认为代码片段是解决我之前识别标记问题的一种非常聪明的方法 而且它可能是我现在缺少的一个非常小的东西 任何再次帮助将不胜感激
  • 如何创建守护线程?

    java程序员可以手动创建守护线程吗 如何 java lang Thread setDaemon 布尔值 http java sun com javase 6 docs api java lang Thread html setDaemon
  • Boost.Python 和 Boost.Function

    我想包一个boost function类成员 以便可以按以下方式使用它 using namespace boost using namespace boost python struct gui button t function
  • 强制 C++ 函数的用户承认数值常量参数的语义的最佳方法是什么?

    我想编写函数接口来强制用户承认内置常量的语义 例如 我想采取 void rotate float angle Rotate the world by an angle in radians 并将其更改为 void rotate Radian
  • 允许函数指针类型的模板参数接受任何返回类型的函数

    当函数的返回值未被实际使用时 是否有一种方法允许函数指针类型的模板参数接受任何 而不是特定 返回类型的函数 这是一个 MCVE 来说明我的意思 int returnInt int return 0 void returnVoid int t
  • 恢复 scipy.optimize 中的优化?

    scipy optimize 提供了许多不同的方法用于多元系统的局部和全局优化 然而 我需要一个很长的优化运行 可能会被中断 在某些情况下 我可能想故意中断它 有什么办法可以重新启动吗 嗯 有什么办法吗 我的意思是 显然可以提供最后一组最优
  • 对于某些已保存的联系人,CallLog.Calls.CACHED_NAME 始终返回 null

    我试图在我的应用程序中显示通话记录详细信息 但 CallLog Calls CACHED NAME 对于某些联系人始终返回 null 即使它是已保存的带有姓名的联系人 内置通话记录正确显示这些联系人的姓名 这是我的代码 protected
  • jQuery.get() - 实际用途?

    我试图理解你为什么会使用jQuery get and jQuery get index http docs jquery com Core get 文档说它将 jQuery 选择转换为原始 DOM 对象 而不是将选择作为 jQuery 对象
  • 删除元组的智能方法

    我有一个元组列表 如下所述 该元组按第二个值的降序排序 from string import ascii letters myTup zip ascii letters range 10 1 threshold 5 5 gt gt gt m
  • Android:如何处理不准确的气压表?

    我一直在使用三星 Galaxy S3 开发一个应用程序 该应用程序使用气压计来估计用户的海拔高度 我使用 SensorManager getAltitude p0 p 并将 p0 设置为等于最近机场报告的海平面压力 我将 p 设置为等于气压
  • 在 python 中调用超类的 __init__ 时显式传递 Self

    这个问题与帖子有关Python 中的 super 有什么作用 https stackoverflow com questions 222877 how to use super in python 如何初始化基 超 类 https stac
  • 使用 AngularJS 过滤 Firebase 数据

    我在 firebase 中有这样的数据 firebase data JGc5X37NDuvmJylmx0s Object name John Doe age 21 JGnGJlTjyAxFT Vn48Y Object name Jane D
  • 如何在Eclipse中添加字符串资源?

    我可以让 Eclipse 在编码时添加字符串资源吗 还是必须始终切换到 string xml 并添加每个字符串 Eclipse 会帮你做这件事 所以如果你有一个字段 android text hello 选择 hello 然后转到 Refa
  • 在 iOS 中使用控件播放音频

    我制作了一个应用程序tab bar nav bar and table view 在表格视图中 您可以选择收听一些音频 新视图打开 其中有一些控件 例如 播放 暂停 音量滑块 进度滑块 带有当前时间的标签 它有效 但并不完美 我可以播放音频