我已经读过,我们现在可以在监视器3中的苹果手表上播放自定义声音。
根据Apple发布的声明显然有但我没有一个例子来测试它:使用SCNAudioSource或SCNAudioPlayer实现的3D空间音频。相反,使用playAudioSource:waitForCompletion:或WatchKit声音或触觉API。在此处找到:https://developer.apple.com/library/prerelease/content/releasenotes/General/WhatsNewInwatchOS/Articles/watchOS3.html
有人可以举一个简单的例子。我没有在我的应用程序中使用SceneKit,因为我不需要它,但如果这是播放自定义声音的唯一方法,那么我想知道完成此操作所需的最少代码。最好是在目标c中,但我会把它带到任何形状。如果这也更容易,我可以使用SpriteKit。
这是我到目前为止所做的,但它不起作用:
SCNNode * audioNode = [[SCNNode alloc] init];
SCNAudioSource * audioSource = [SCNAudioSource audioSourceNamed:@"mysound.mp3"];
SCNAudioPlayer * audioPlayer = [SCNAudioPlayer audioPlayerWithSource:audioSource];
[audioNode addAudioPlayer:audioPlayer];
SCNAction * play = [SCNAction playAudioSource:audioSource waitForCompletion:YES];
[audioNode runAction:play];
答案 0 :(得分:6)
这是Objective-c但可以翻译成Swift
我最终使用AVAudioEngine
和AVAudioPlayerNode
在Apple手表上播放音频。
如何做到这一点的要点如下:
我在我的AudioPlayer的init
方法中调用以下内容(它是一个NSObject子类来封装功能)
_audioPlayer = [[AVAudioPlayerNode alloc] init];
_audioEngine = [[AVAudioEngine alloc] init];
[_audioEngine attachNode:_audioPlayer];
AVAudioFormat *stereoFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:44100 channels:2];
[_audioEngine connect:_audioPlayer to:_audioEngine.mainMixerNode format:stereoFormat];
if (!_audioEngine.isRunning) {
NSError* error;
[_audioEngine startAndReturnError:&error];
}
我有一个缓存设置,因此每次我想播放声音时都不会重新创建AVAudioFile
资源但是你不需要。
接下来创建一个AVAudioFile
对象:
NSError *error;
NSBundle* appBundle = [NSBundle mainBundle];
NSURL *url = [NSURL fileURLWithPath:[appBundle pathForResource:key ofType:@"aifc"]];
AVAudioFile *asset = [[AVAudioFile alloc] initForReading:url &error];
然后播放该文件:
[_audioPlayer scheduleFile:asset atTime:nil completionHandler:nil];
[_audioPlayer play];
更新:如果应用程序进入睡眠状态或被置于后台,则音频可能会停止播放/淡出。通过激活音频会话,这将被阻止。
NSError *error;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
if (error) {
NSLog(@"AVAudioSession setCategory ERROR: %@", error.localizedDescription);
}
[[AVAudioSession sharedInstance] setActive:YES error:&error];
if (error) {
NSLog(@"AVAudioSession setActive ERROR: %@", error.localizedDescription);
}
我没有过去处理任何错误,但这应该有效。不要忘记在实施文件的顶部#import <AVFoundation/AVFoundation.h>
。
答案 1 :(得分:6)
我可以确认,@ ApperleyA解决方案确实有效!
这是swift版本:
var _audioPlayer : AVAudioPlayerNode!
var _audioEngine : AVAudioEngine!
func playAudio()
{
if (_audioPlayer==nil) {
_audioPlayer = AVAudioPlayerNode()
_audioEngine = AVAudioEngine()
_audioEngine.attach(_audioPlayer)
let stereoFormat = AVAudioFormat(standardFormatWithSampleRate: 44100, channels: 2)
_audioEngine.connect(_audioPlayer, to: _audioEngine.mainMixerNode, format: stereoFormat)
do {
if !_audioEngine.isRunning {
try _audioEngine.start()
}
} catch {}
}
if let path = Bundle.main.path(forResource: "test", ofType: "mp3") {
let fileUrl = URL(fileURLWithPath: path)
do {
let asset = try AVAudioFile(forReading: fileUrl)
_audioPlayer.scheduleFile(asset, at: nil, completionHandler: nil)
_audioPlayer.play()
} catch {
print ("asset error")
}
}
}
答案 2 :(得分:0)
这在模拟器中对我有用
let soundPath = Bundle.main.path(forResource: "cheerMP3", ofType: "mp3")
let soundPathURL = URL(fileURLWithPath: soundPath!)
let audioFile = WKAudioFileAsset(url: soundPathURL)
let audioItem = WKAudioFilePlayerItem(asset: audioFile)
let audioPlayer = WKAudioFilePlayer.init(playerItem: audioItem)
if audioPlayer.status == .readyToPlay
{
audioPlayer.play()
}
else
{
print("Not ready!!")
}
但是只有我在audioPlayer.play()和最后一个}之后都有断点。
dunqan,你在文件的顶部放了什么,import语句?我无法包括导入AVFoundation
使用Xcode 8.2.1
时没有错误