xcode 如何在 iOS 中使用 Obj-C 播放 mp3

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31666475/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 07:33:54  来源:igfitidea点击:

How to play mp3 in iOS with Obj-C

iosobjective-cxcodemp3media-player

提问by Abdulrahman Jami

I've a question in Objective-C, I'm working on an iOS application that should play a specific mp3 set of files -242 mp3 files exactly-, So could someone tell me what is the best way to play them all, I mean should I put them in a server, making them all local or what ? and how should I code them in Xcode.

我在 Objective-C 中有一个问题,我正在开发一个 iOS 应用程序,该应用程序应该播放一组特定的 mp3 文件 -242 个 mp3 文件,所以有人可以告诉我播放它们的最佳方式是什么,我意思是我应该把它们放在一个服务器上,让它们都是本地的还是什么?以及我应该如何在 Xcode 中对它们进行编码。

回答by Anand Prakash

Apple provide many ways to play audio on the iPhone – System Sound Services, AVAudioPlayer, Audio Queue Services, and OpenAL. Without outside support libraries, the two easiest ways by far are System Sound Services and AVAudioPlayer.

Apple 提供了多种在 iPhone 上播放音频的方法——系统声音服务、AVAudioPlayer、音频队列服务和 OpenAL。在没有外部支持库的情况下,目前最简单的两种方法是 System Sound Services 和 AVAudioPlayer。

  1. System Sound Services

    It is useful for audio alerts and simple game sounds.

    NSString *pewPewPath = [[NSBundle mainBundle] 
    pathForResource:@"pew-pew-lei" ofType:@"caf"];
    NSURL *pewPewURL = [NSURL fileURLWithPath:pewPewPath];
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)pewPewURL,  
    &self.pewPewSound);
    AudioServicesPlaySystemSound(self.pewPewSound);
    
  1. 系统声音服务

    它对于音频警报和简单的游戏声音很有用。

    NSString *pewPewPath = [[NSBundle mainBundle] 
    pathForResource:@"pew-pew-lei" ofType:@"caf"];
    NSURL *pewPewURL = [NSURL fileURLWithPath:pewPewPath];
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)pewPewURL,  
    &self.pewPewSound);
    AudioServicesPlaySystemSound(self.pewPewSound);
    

It is important to define pewPewSound as an iVar or property, and not as a local variable so that you can dispose of it later in dealloc. It is declared as a SystemSoundID. If you were to dispose of it immediately after AudioServicesPlaySystemSound(self.pewPewSound), then the sound would never play.

2. AVAudioPlayer

将 pewPewSound 定义为 iVar 或属性而不是局部变量很重要,这样您可以稍后在 dealloc 中处理它。它被声明为 SystemSoundID。如果您在 AudioServicesPlaySystemSound(self.pewPewSound) 之后立即处理它,那么声音将永远不会播放。

2. AVAudioPlayer

It allow to play several sounds at once (using a different AVAudioPlayer for each sound), and you can play sounds even when your app is in the background..The AVAudioPlayer class is part of AVFoundation, you will need to @import AVFoundation into your project.

它允许一次播放多个声音(对每个声音使用不同的 AVAudioPlayer),即使您的应用程序在后台,您也可以播放声音..AVAudioPlayer 类是 AVFoundation 的一部分,您需要@import AVFoundation 到您的项目。

 NSError *error;
self.backgroundMusicPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:backgroundMusicURL error:&error];
[self.backgroundMusicPlayer prepareToPlay];
[self.backgroundMusicPlayer play];

ATBViewController.h

ATBViewController.h

#import <UIKit/UIKit.h>

@interface ATBViewController : UIViewController

@end

ATBViewController.m

ATBViewController.m

#import "ATBViewController.h"
#import "AudioController.h"

@interface ATBViewController ()

@property (strong, nonatomic) AudioController *audioController;

@end

@implementation ATBViewController

#pragma mark - Lifecycle

- (void)viewDidLoad {
    [super viewDidLoad];

    self.audioController = [[AudioController alloc] init];
    [self.audioController tryPlayMusic];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - IBAction

- (IBAction)spaceshipTapped:(id)sender {
    //The call below uses AudioServicesPlaySystemSound to play
    //the short pew-pew sound.
    [self.audioController playSystemSound];
    [self fireBullet];
}

- (void)fireBullet {
    // In IB, the button to top layout guide constraint is set to 229, so
    // the bullets appear in the correct place, on both 3.5" and 4" screens
    UIImageView *bullets = [[UIImageView alloc] initWithFrame:CGRectMake(84, 256, 147, 29)];
    bullets.image = [UIImage imageNamed:@"bullets.png"];
    [self.view addSubview:bullets];
    [self.view sendSubviewToBack:bullets];
    [UIView beginAnimations:@"shoot" context:(__bridge void *)(bullets)];
    CGRect frame = bullets.frame;
    frame.origin.y = -29;
    bullets.frame = frame;
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
    [UIView commitAnimations];
}

- (void) animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    UIImageView *bullets = (__bridge UIImageView *)context;
    [bullets removeFromSuperview];
}

@end

AudioController.h

音频控制器.h

#import <Foundation/Foundation.h>

@interface AudioController : NSObject

- (instancetype)init;
- (void)tryPlayMusic;
- (void)playSystemSound;

@end

AudioController.m

音频控制器.m

#import "AudioController.h"
@import AVFoundation;

@interface AudioController () <AVAudioPlayerDelegate>

@property (strong, nonatomic) AVAudioSession *audioSession;
@property (strong, nonatomic) AVAudioPlayer *backgroundMusicPlayer;
@property (assign) BOOL backgroundMusicPlaying;
@property (assign) BOOL backgroundMusicInterrupted;
@property (assign) SystemSoundID pewPewSound;

@end

@implementation AudioController

#pragma mark - Public

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self configureAudioSession];
        [self configureAudioPlayer];
        [self configureSystemSound];
    }
    return self;
}

- (void)tryPlayMusic {
    // If background music or other music is already playing, nothing more to do here
    if (self.backgroundMusicPlaying || [self.audioSession isOtherAudioPlaying]) {
        return;
    }

       [self.backgroundMusicPlayer prepareToPlay];
    [self.backgroundMusicPlayer play];
     self.backgroundMusicPlaying = YES;
}

- (void)playSystemSound {
    AudioServicesPlaySystemSound(self.pewPewSound);
}

#pragma mark - Private

- (void) configureAudioSession {
    // Implicit initialization of audio session
    self.audioSession = [AVAudioSession sharedInstance];


    NSError *setCategoryError = nil;
    if ([self.audioSession isOtherAudioPlaying]) { // mix sound effects with music already playing
        [self.audioSession setCategory:AVAudioSessionCategorySoloAmbient error:&setCategoryError];
        self.backgroundMusicPlaying = NO;
    } else {
        [self.audioSession setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];
    }
    if (setCategoryError) {
        NSLog(@"Error setting category! %ld", (long)[setCategoryError code]);
    }
}

- (void)configureAudioPlayer {
    // Create audio player with background music
    NSString *backgroundMusicPath = [[NSBundle mainBundle] pathForResource:@"background-music-aac" ofType:@"caf"];
    NSURL *backgroundMusicURL = [NSURL fileURLWithPath:backgroundMusicPath];
    self.backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:nil];
    self.backgroundMusicPlayer.delegate = self;  // We need this so we can restart after interruptions
    self.backgroundMusicPlayer.numberOfLoops = -1;  // Negative number means loop forever
}

- (void)configureSystemSound {

    NSString *pewPewPath = [[NSBundle mainBundle] pathForResource:@"pew-pew-lei" ofType:@"caf"];
    NSURL *pewPewURL = [NSURL fileURLWithPath:pewPewPath];
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)pewPewURL, &_pewPewSound);
}

#pragma mark - AVAudioPlayerDelegate methods

- (void) audioPlayerBeginInterruption: (AVAudioPlayer *) player {
        self.backgroundMusicInterrupted = YES;
    self.backgroundMusicPlaying = NO;
}

- (void) audioPlayerEndInterruption: (AVAudioPlayer *) player withOptions:(NSUInteger) flags{

      [self tryPlayMusic];
      self.backgroundMusicInterrupted = NO;
}

@end

回答by Antonis

Apple provides AVAudioPlayerfor handling audio media files. Another library you could use that works with Core Audio under the hood is EZAudio

Apple 提供AVAudioPlayer处理音频媒体文件的方法。另一个可以与 Core Audio 一起使用的库是EZAudio

回答by Burning

You could do something like this:

你可以这样做:

NSUrl *videoUrl = [NSUrl urlWithString:@"url"];
MPMoviePlayerViewController *playerViewController = 
    [[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL URLWithString: videoUrl]];
[self presentMoviePlayerViewControllerAnimated:playerViewController];