[英]How can I make audio play when the button is pressed and immediately stop when I take my finger off the same button?
My current code for the button is. 我当前的按钮代码是。
-(IBAction)playsnare;
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundfileURLRef;
soundfileURLRef =CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"snare", CFSTR ("wav"), NULL);
UInt32 SoundID;
AudioServicesCreateSystemSoundID(soundfileURLRef, &SoundID);
AudioServicesPlaySystemSound(SoundID);
}
What can I add to this to make the button play when pressed and stop when not pressed. 我可以添加些什么来使按钮在按下时播放,在不按下时停止。
Your implementation for playing audio samples does not allow for this. 您的播放音频样本的实现不允许这样做。 Because you are using AudioServicesPlaySystemSound from the AudioToolbox framework, there is no way to stop playback once the audio sample is triggered.
因为您正在使用AudioToolbox框架中的AudioServicesPlaySystemSound ,所以一旦触发音频样本,就无法停止播放。 You can only get a callback once it has finished playing.
一旦播放完毕,您将只能获得回调。
This way of playing sounds has other limitations also (taken from the docs) 这种播放声音的方式也有其他限制(摘自文档)
In addition, when you use the AudioServicesPlaySystemSound function:
此外,当您使用AudioServicesPlaySystemSound函数时:
Sounds play at the current system audio volume, with no programmatic volume control available
声音以当前系统音频音量播放,没有可编程的音量控制
Sounds play immediately
声音立即播放
Looping and stereo positioning are unavailable
循环和立体声定位不可用
Simultaneous playback is unavailable: You can play only one sound at a time
无法同时播放:一次只能播放一个声音
The sound is played locally on the device speakers;
声音在设备扬声器上本地播放; it does not use audio routing.
它不使用音频路由。
To have control over stopping the sound once triggered, you'll need to use another API. 要控制触发后停止声音,您需要使用其他API。 For a high level API try AVAudioPlayer class from AVFoundation framework.
对于高级API,请尝试AVFoundation框架中的AVAudioPlayer类。 You will then be able to hook up events from a button such as
touch down
to start playing the sound, and also events such as touch up inside
and touch drag outside
to stop the sound playing. 然后,您将可以挂接按钮上的事件(例如,
touch down
以开始播放声音),还可以挂起事件(例如在touch up inside
touch drag outside
和touch drag outside
以停止声音播放)。
You may or may not encounter performance issues depending on what else you're doing. 您可能会或可能不会遇到性能问题,具体取决于您在做什么。 For better performance ( and a lot more writing of code ) AudioUnits would be the preferred choice.
为了获得更好的性能( 以及更多的代码编写 ), AudioUnits将是首选。
A short example using AVAudioPlayer class would be something like this- 使用AVAudioPlayer类的简短示例如下所示:
The following code assumes a property of type AVAudioPlayer named loopPlayer that is initialised with a file called some_audio_loop_file.wav in a UIViewController sub-class.
下面的代码假定了一个名为loopPlayer的 AVAudioPlayer类型的属性,该属性是使用UIViewController子类中名为some_audio_loop_file.wav的文件初始化的。
yourViewController.h yourViewController.h
@property (nonatomic, strong) AVAudioPlayer *loopPlayer;
yourViewController.m yourViewController.m
// set up loopPlayer property in for example viewDidLoad
NSURL* audioFileURL = [[NSBundle mainBundle] URLForResource:@"some_audio_loop_file" withExtension:@"wav"];
self.loopPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL error:nil];
// called from a UIButton touch down event
-(IBAction)startAudioSample:(id)sender {
[self.loopPlayer play];
}
// called from a UIButton touch up inside and touch drag outside events
-(IBAction)stopAudioSample:(id)sender {
if (self.loopPlayer.isPlaying) {
[self.loopPlayer stop];
self.loopPlayer.currentTime = 0;
self.loopPlayer.numberOfLoops = -1;
[self.loopPlayer prepareToPlay];
}
Try: 尝试:
-(IBAction)longPress:(UILongPressGestureRecognizer*)playsnare;
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundfileURLRef;
soundfileURLRef =CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"snare", CFSTR ("wav"), NULL);
UInt32 SoundID;
AudioServicesCreateSystemSoundID(soundfileURLRef, &SoundID);
AudioServicesPlaySystemSound(SoundID);
}
UILongPressGestureRecognizer is a continuous event recognizer. UILongPressGestureRecognizer是连续事件识别器。 You have to look at the state to see if this is the start, middle or end of the event and act accordingly.
您必须查看状态以查看这是事件的开始,中间还是结束,并采取相应的措施。 ie you can through away all events after the start, or only look at movement as you need.
即,您可以在开始之后消除所有事件,或者仅根据需要查看运动。 From the Class Reference:
从类参考:
Long-press gestures are continuous. 长按手势是连续的。 The gesture begins (UIGestureRecognizerStateBegan) when the number of allowable fingers (numberOfTouchesRequired) have been pressed for the specified period (minimumPressDuration) and the touches do not move beyond the allowable range of movement (allowableMovement).
当在指定时间段内(minimumPressDuration)按下了允许的手指数(numberOfTouchesRequired),并且触摸没有移动超出允许的移动范围(allowableMovement)时,手势即开始(UIGestureRecognizerStateBegan)。 The gesture recognizer transitions to the Change state whenever a finger moves, and it ends (UIGestureRecognizerStateEnded) when any of the fingers are lifted.
每当手指移动时,手势识别器都会转换为“更改”状态,并且在任何手指抬起时手势识别器都会终止(UIGestureRecognizerStateEnded)。
Now You Can Track The State Like This 现在您可以像这样跟踪状态
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
NSLog(@"UIGestureRecognizerStateEnded");
//Do Whatever You want on End of Gesture
}
else if (sender.state == UIGestureRecognizerStateBegan){
NSLog(@"UIGestureRecognizerStateBegan.");
//Do Whatever You want on Began of Gesture
}
}
detail from: https://stackoverflow.com/a/3320351/1255945 详细信息来自: https : //stackoverflow.com/a/3320351/1255945
Create a property 创建一个属性
bool isPlaying
and then as in your IBAction function 然后像您的IBAction函数中
if(isPlaying){
stop();
}else{
play();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.