在播放动态音频之前创建 AVAudioPlayer 对象
Posted
技术标签:
【中文标题】在播放动态音频之前创建 AVAudioPlayer 对象【英文标题】:Creating AVAudioPlayer object much before playing the dynamic audio 【发布时间】:2013-08-02 11:45:07 【问题描述】:每当我播放如下音频文件时,开始播放音频需要几秒钟的时间。我从一些论坛上看到并理解,如果我们在其中分配对象,AVAudioPlayer 将需要几秒钟才能开始播放。我想在我想玩之前更早地分配这个对象(可能是 Appdelegate 本身),这样当我想玩它时,它会立即播放。
NSURL *audioPathURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:audioName ofType:@"wav"]];
audioP = [[AVAudioPlayer alloc]initWithContentsOfURL:audioPathURL error:NULL];
[appDelegate.audioP play];
但是,我在运行时动态传递音频 url,所以我想知道如何更早地分配对象,然后能够稍后传递动态音频 url 路径?
请注意,我的问题与这个问题不同Slow start for AVAudioPlayer the first time a sound is played 在现有问题中,他们正在讲述一个音频文件并在需要时播放。但是,我有许多不同的音频文件,并且 url 路径是在运行时随机生成的,所以我不知道要设置和播放的实际 url 路径是什么。所以,这里提到的答案->Slow start for AVAudioPlayer the first time a sound is played 对我的问题没有帮助。 我不能使用prepareToPlay,因为音频路径url是在运行时设置的,而不是一直使用一个音频来播放,会随机选择20多个音频文件并设置一次播放一个。所以,我需要正确的答案,这不是重复的问题。
谢谢!
【问题讨论】:
看这个:***.com/questions/9710679/… 如果您知道自己将要演奏一些东西,您可以使用 prepareToPlay: 来减少延迟。这将预加载缓冲区并获取声音硬件。 嗨,我将如何使用 prepareToPlay 来处理我的案例(音频 url 路径将仅在运行时传递)? 这就是为什么我说只有在你(稍微)提前知道你要演奏一些东西的情况下它才会对你有所帮助。但是你真的应该阅读@HinataHyuga 链接的线程 【参考方案1】:这里对于单个文件的解决方案:
在你的file.h
#import <AVFoundation/AVFoundation.h>
@interface AudioPlayer : UIViewController <AVAudioPlayerDelegate>
要与按钮一起使用,请在您的 file.h
中添加 - (IBAction)Sound:(id)sender;
现在在您的file.m
//这是一个动作,但你可以在 void 内使用来启动自动
@implementation AudioPlayer
SystemSoundID soundID;
- (IBAction)Sound:(id)sender
AudioservicesDisposeSystemSoundID(soundID);
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
//you can use here extension .mp3 / .wav / .aif / .ogg / .caf / and more
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"sound" ,CFSTR ("mp3") , NULL);
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
如果你想使用你的代码从 URL 播放音频,你可以使用这个:
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
@interface AudioPlayer : UIViewController <AVAudioPlayerDelegate>
AVPlayer *mySound;
@property (strong, nonatomic) AVPlayer *mySound;
@end
还有file.m
- (IBAction)playPause:(id)sender
if (mySound.rate == 0)
NSURL *url = [NSURL URLWithString:@"http://link.mp3"];
mySound = [[AVPlayer alloc] initWithURL:url];
[mySound setAllowsExternalPlayback:YES];
[mySound setUsesExternalPlaybackWhileExternalScreenIsActive: YES];
[mySound play];
else
[mySound pause];
希望对你有帮助!
【讨论】:
【参考方案2】:您可以做的一件事是通过加载和播放虚拟文件,在您需要它之前“启动”底层音频系统,以减少第一次加载+播放的延迟。例如,在application:didFinishLaunchingWithOptions:
中添加如下代码:
// this won't effect the problem you're seeing, but it's good practice to explicitly
// set your app's audio session category
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
NSURL *audioURL = [[NSBundle mainBundle] URLForResource:@"dummy.wav" withExtension:nil];
AVAudioPlayer *dplayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:nil];
// we don't want to hear it (alternatively, the audiofile you use for this purpose can be silence.)
dplayer.volume = 0.f;
[dplayer prepareToPlay];
[dplayer play];
[dplayer stop];
此代码完成后,AVAudioPlayer
实例的后续实例化和回放应该具有相当低的延迟(当然远低于 1 秒)
【讨论】:
您好,感谢您的建议。但是,我的问题是如何在运行时设置不同的音频文件路径,因为我们需要在运行时再次使用 '[[AVAudioPlayer alloc] initWithContentsOfURL' 部分,这不过是我们再次创建新对象,这不会导致延迟? 我尝试了这个解决方案,但我发现了同样的延迟问题。 第一次播放后的后续实例在我的测试中 更快 - 我可以在 iPhone 5 上以可接受的延迟播放鼓样本。我怀疑你的问题出在其他地方(例如,音频文件是否正确修剪?)但您也可以查看AVPlayer
而不是 AVAudioPlayer
-- replaceCurrentItemWithPlayerItem:
让您无需重新实例化即可更改项目。以上是关于在播放动态音频之前创建 AVAudioPlayer 对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在 AVAudioPlayer 开始播放音频时准确获取通知?
iPhone:AVAudioPlayer 并不总是在设备上播放音频
自定义 tableviewcell 上的 UISlider 和 UILabel 在第二次播放音频之前不会使用 avaudioplayer 更新