可可播放MP3

13

有没有简单的方法从cocoa加载、播放和控制mp3文件?我已经尝试过在谷歌上搜索,但是像所有苹果产品一样,我得到了混乱的结果,并且不知道从哪里开始。据我所知,有一个NSSound,但它有很多限制,然后还有CoreAudio,但它非常难用。所以,有人能指点我一下吗?谢谢。


抱歉,您是在开发iOS还是Mac应用? - shosti
1
是的,抱歉,忘了澄清:AVAudioPlayer不起作用:我正在开发OSX。 - Marius
1
从Mac OS X 10.7 Lion开始(可能甚至是10.6.8?),AVFoundation可以工作了!因此,AVAudioPlayer也可以使用了。请参见下面的答案。 - Mazyod
6个回答

41

使用AVFoundation!据苹果公司表示,它已经与Mac OS X Lion(我认为)集成。因此..以下是无痛播放mp3的方法:

1- 链接AVFoundation框架。

2- 在任何想播放精彩mp3的地方导入它。

#import <AVFoundation/AVFoundation.h>

3- 添加一个audioPlayer实例变量来播放声音(至少这是我喜欢的方式)

@interface WCMainWindow : ... {
    ...
    AVAudioPlayer* audioPlayer;
}

4- 在你的初始化中,请确保初始化你的audioPlayer:

NSString* path = [[NSBundle mainBundle] pathForResource:@"myFile" ofType:@"mp3"];
NSURL* file = [NSURL fileURLWithPath:path];
// thanks @gebirgsbaerbel
    
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:nil];
[audioPlayer prepareToPlay];

5- 播放您的精彩音频文件!

if ([audioPlayer isPlaying]) {
    [audioPlayer pause];
} else {
    [audioPlayer play];
}

最后,应该感谢这位


你如何测试以确定你能否使用它? - user317033
你是什么意思?按照所解释的步骤进行操作,并确保将MP3文件添加到资源中。然后,添加一个按钮(动作),该按钮将调用[audioPlayer play] - Mazyod
2
方法URLWithString总是返回空值。 使用[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"myFile" ofType:@"mp3"]];代替解决了这个问题。 - gebirgsbärbel

5
我已经用C++编写了一个框架,可能会对您有所帮助:http://github.com/sbooth/SFBAudioEngine。它支持多种音频格式,并且具有相当友好的API,并附带一个Cocoa示例。
如果您不想使用第三方框架,那么您最好使用AudioQueue来处理播放。为此,您可能会使用AudioFile来解码MP3,使用AudioQueue进行播放。苹果公司在http://developer.apple.com/mac/library/samplecode/AudioQueueTools/Introduction/Intro.html上提供了一个示例。

1

使用NSSound

你没有说明“很多限制”是什么意思,所以我不知道为什么这对你行不通。请注意,自Leopard以来,它的限制要少得多;例如,现在你可以播放到任何设备。


1
#import <Cocoa/Cocoa.h>
#import <QTKit/QTKit.h>

@interface SoundPlayer : NSObject {
  NSSound *sound;
  IBOutlet NSWindow *window;
  IBOutlet NSSlider *progress;
  BOOL loop;
}
- (IBAction)open: (id)sender;
- (IBAction)setLoop: (id)sender;
- (IBAction)play: (id)sender;
- (IBAction)stop: (id)sender;
- (IBAction)takeCurrentTimeFrom: (id)sender;
@end

#import "SoundPlayer.h"

@implementation SoundPlayer
- (IBAction)open: (id)sender
{
    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
    [openPanel runModalForTypes: [NSArray arrayWithObjects: @"aiff", @"mp3", @"m4a", nil]];
    [sound release];
    sound = [[QTMovie movieWithFile: [openPanel filename]
                              error: NULL] retain];
    [sound setAttribute: [NSNumber numberWithBool: loop]
                 forKey: QTMovieLoopsAttribute];
    [window setTitle: [[openPanel filename] lastPathComponent]];
}
- (IBAction)setLoop: (id)sender
{
    loop = ([sender state] == NSOnState);
    [sound setAttribute: [NSNumber numberWithBool: loop]
                 forKey: QTMovieLoopsAttribute];
}
- (IBAction)play: (id)sender
{
    NSTimeInterval duration;
    QTGetTimeInterval([sound duration], &duration);
    [progress setMaxValue: duration];
    [NSTimer scheduledTimerWithTimeInterval: 0.1
                                     target: self
                                   selector: @selector(updateIndicator:)
                                   userInfo: sound
                                    repeats: YES];
    [sound play];
}
- (void)updateIndicator: (NSTimer*)aTimer
{
    QTMovie *playingSound = [aTimer userInfo];
    if (!(sound == playingSound && ([sound rate] != 0)))
    {
        [aTimer invalidate];
        return;
    }
    NSTimeInterval currentTime;
    QTGetTimeInterval([sound currentTime], &currentTime);
    [progress setDoubleValue: currentTime];
}
- (IBAction)stop: (id)sender
{
    [sound stop];
}
- (IBAction)takeCurrentTimeFrom: (id)sender
{
    [sound setCurrentTime: QTMakeTimeWithTimeInterval([sender doubleValue])];
}
@end

0
除了使用 NSSound,你也可以考虑使用 QTMovieView。听起来有些奇怪,但是你可以在窗口中隐藏一个 QTMovieView 并使用它来播放 MP3。
补充说明:自 OS 10.9 起,QTMovieView 已被弃用。因此,除非你需要支持 10.7 之前的 OS 版本(当 AVFoundation 进入 Mac 时),否则你应该不使用它。

我也看过使用QTKit而没有任何视图的示例,但我不确定这是否是一个好的方法,因为我还没有找到如何寻找文件,甚至可能添加一些效果。 - Marius
我不确定你所说的“寻找文件”是什么意思。 - JWWalker
简单来说,就是前往某个特定位置并从那里继续播放。 - Marius
哦,好的...当使用QTMovieView时,您可以在关联的QTMovie上使用setCurrentTime:等QTMovie方法。 - JWWalker
@JWWalker,我知道你在2010年写了你的答案,但是现在,在2016年,我相信QTMoviewView已经被弃用了。 - Kaydell
显示剩余2条评论

0
import Cocoa
import AVFoundation

class ViewController: NSViewController {
    
    
    var audio = AVAudioPlayer()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let play = Bundle.main.path(forResource: "A" , ofType: "mb3")
        do{
            audio = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: play!))
        }
        catch{
            print(error)
        }
        
    }
    
    
    @IBAction func button(_ sender: Any)
    {
        audio.play()
    }
    
    override var representedObject: Any? {
        didSet {
            // Update the view, if already loaded.
        }
    }
    
    
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接