这篇文章主要围绕在iOSSwift中进行简单的低延迟音频播放和在iosswift中进行简单的低延迟音频播放设置展开,旨在为您提供一份详细的参考资料。我们将全面介绍在iOSSwift中进行简单的低延迟音
这篇文章主要围绕在iOS Swift中进行简单的低延迟音频播放和在ios swift中进行简单的低延迟音频播放设置展开,旨在为您提供一份详细的参考资料。我们将全面介绍在iOS Swift中进行简单的低延迟音频播放的优缺点,解答在ios swift中进行简单的低延迟音频播放设置的相关问题,同时也会为您带来iOS 9音频应用播放音频之iOS 9音频播放进度、iOS swift 简单的对象存储和读取、ios – 在swift中延迟运行动画、ios – 如何在swift中进行多重继承?的实用方法。
本文目录一览:- 在iOS Swift中进行简单的低延迟音频播放(在ios swift中进行简单的低延迟音频播放设置)
- iOS 9音频应用播放音频之iOS 9音频播放进度
- iOS swift 简单的对象存储和读取
- ios – 在swift中延迟运行动画
- ios – 如何在swift中进行多重继承?
在iOS Swift中进行简单的低延迟音频播放(在ios swift中进行简单的低延迟音频播放设置)
我是iOS的初学者,正在尝试使用Swift设计鼓组应用。我设计了一个带有单个按钮的视图,并在下面编写了代码,但是它存在一些问题:
- 当我像鼓声一样快速触摸按钮时,会丢失一些声音。
- 仍然在“鼓声滚动”中,每次触摸该按钮都会中断声音,而不是让样本播放到结束为止。例如,c滚动太糟糕了。即使我再次触摸该按钮,我也希望听到所有采样的声音。
- 触摸和声音之间存在延迟。我知道这
AVAudioPlayer
是不是低延迟音频的最佳选择,但作为一个初学者,它很难学OpenAL
,AudioUnit
没有代码示例或教程Swift
。\
代码:
override func viewDidLoad() { super.viewDidLoad() // Enable multiple touch for the button for v in view.subviews { if v.isKindOfClass(UIButton) { v.multipleTouchEnabled = true } } // Init audio audioURL = NSBundle.mainBundle().URLForResource("snareDrum", withExtension: "wav")! do { player = try AVAudioPlayer(contentsOfURL: audioURL) player?.prepareToPlay() } catch { print("AVAudioPlayer Error") }}override func viewDidDisappear(animated: Bool) { super.viewDidDisappear(animated) player?.stop() player = nil}@IBAction func playSound(sender: UIButton) { player?.currentTime = 0 player?.play()}
答案1
小编典典如果您需要极低的延迟,我在AVAudioSession单例中发现了一个非常简单的解决方案(当应用启动时会自动实例化):
首先,使用此类方法获取对应用程序的AVAudioSession单例的引用:
(来自AVAudioSession类参考):
获取共享的音频会话
声明SWIFT
class func sharedInstance() -> AVAudioSession
然后,尝试使用此实例方法将首选IO缓冲区持续时间设置为非常短的时间(例如.002):
设置首选的音频I / O缓冲区持续时间(以秒为单位)。
声明SWIFT
func setPreferredIOBufferDuration(_ duration: NSTimeInterval) throws
参量
duration
您要使用的音频I / O缓冲区持续时间(以秒为单位)。
outError
输入时,指向错误对象的指针。如果发生错误,则将指针设置为描述该错误的NSError对象。如果您不想要错误信息,请输入nil。返回值如果成功发出请求,则为true,否则为false。讨论区
此方法请求更改I /
O缓冲区持续时间。要确定更改是否生效,请使用IOBufferDuration属性。有关详细信息,请参阅配置音频会话。
请紧记上面的注释- IOBufferDuration
属性是否 实际上 设置为传递给funcsetPrefferedIOBufferDuration(_ duration: NSTimeInterval)throws
方法的值,取决于函数是否不返回错误, 并且 我还不太清楚的其他因素。另外-在我的测试中-
我发现,如果将此值设置为极低的值,则确实会设置该值(或接近它的值),但是在播放文件(例如使用AVAudioPlayerNode)时,声音不会被演奏。没有错误,只有声音。这显然是一个问题。而且,除了注意到在实际设备上进行测试时听不到声音的声音之外,我还没有发现如何测试此问题的方法。我会调查一下。但就目前而言,我建议将首选时长设置为不小于.002或.0015。.0015的值似乎适用于我正在测试的iPad
Air(型号A1474)。低至.0012似乎可以在我的iPhone 6S上正常工作。
从CPU开销角度考虑的另一件事是音频文件的格式。播放时,未压缩的格式将具有非常低的CPU开销。苹果公司建议您为获得最高质量和最低开销而使用CAF文件。对于压缩文件和最低开销,您应该使用IMA4压缩:
(来自iOS多媒体编程指南):
iOS中的首选音频格式对于未压缩(最高质量)的音频,请使用打包在CAF文件中的16位,小字节序,线性PCM音频数据。您可以使用afconvert命令行工具在Mac
OS X中将音频文件转换为这种格式,如下所示:
/usr/bin/afconvert -f caff -d LEI16 {INPUT} {OUTPUT}
当需要同时播放多个声音时,为了减少内存使用量,请使用IMA4(IMA /
ADPCM)压缩。这样可以减小文件大小,但在解压缩期间对CPU的影响最小。与线性PCM数据一样,将IMA4数据打包在CAF文件中。
您也可以使用afconvert转换为IMA4:
/usr/bin/afconvert -f AIFC -d ima4 [file]
iOS 9音频应用播放音频之iOS 9音频播放进度
iOS 9音频应用播放音频之iOS 9音频播放进度
iOS 9音频应用开发播放进度
音频文件在播放后经过了多久以及还有多久才可以播放完毕,想必是用户所关注的问题。为了解决这一问题,在很多的音乐播放器中都会有一个播放进度,如图2.32所示。本节将讲解两种查看播放进度的方法。
图2.32 QQ音乐
iOS 9音频应用开发通过进度时间查看进度
通过时间查看进度就是在图2.32中出现的两个时间,它有一个当前播放的时间,还有一个音频文件的总时间。通过这两个时间,用户就可以知道音频文件播放了多久,还需要多久播放完毕。
1.显示音频总时间
对于音频文件中总时间的获取可以使用到AVAudioPlayer类的duration属性,其语法形式如下:
var duration: NSTimeInterval { get }
其中,该属性是一个只读属性,获取的值是一个NSTimeInterval类型(又名Double)的值,它是以秒为单位的。如果要想出现图2.32中时间的效果,就需要将该值进行转换,转换的具体步骤如下:
(1)获取分钟数:由于使用duration属性获取的值为以秒为单位的,不是用户所理解的时间。由于音频文件往往都是几分钟,所以就不需要小时。将秒转换为分钟,只需要将duration属性获取的值除以60就可以了。其转换格式如下:
AVAudioPlayer对象名.duration/60
注意:用户所理解的时间格式如下:
时:分:秒
(2)将分钟数转换为整型:由于duration是NSTimeInterval类型即双精度类型,而分钟数往往没有小数点,所以需要将此类型的值转换为整型,转换格式如下:
Int(分钟数)
(3)获取秒数:对于秒数的获取就直接使用音频文件的总时间减去转换为整型的分钟数,其语法形式如下:
AVAudioPlayer对象名.duration - Int(分钟数)
(4)将秒数转为为整型:和为分钟数转换类型一样,需要将获取的秒数转换为整型,转换格式如下:
Int(秒数)
【示例2-7】以下将以第一个实例为基础,获取音频文件的总时间,并显示在Duration Label标注中。具体的操作步骤如下:
(1)将主视图中的Duration Label标签控件与插座变量durationTime进行关联。
(2)打开ViewController.swift文件,编写代码,实现音频总时间的获取。代码如下:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
moreSettingsView.hidden=true
let path=NSBundle.mainBundle().pathForResource("Liekkas", ofType: "mp3")
……
audioEffect?.pan = -1.0
let durationMinutes:Int=Int(audioEffect!.duration/60) //获取分钟数
let durationSeconds=Int(audioEffect!.duration - Double(durationMinutes * 60)) //获取秒数
durationTime.text="\(durationMinutes):\(durationSeconds)"
}
此时运行程序,会看到如图2.33所示的效果。
图2.33 主视图
2.获取iOS 9音频应用开发当前播放的时间
获取当前播放的时间,我们在2.3.2小节中提到过需要使用到AVAudioPlayer类中的currentTime属性。
注意:此时获取的当前播放时间也是NSTimeInterval类型(又名Double)。所以也需要进行转换,类型与音频文件总时间的转换。
【示例2-8】下面将以第一个实例为基础,获取音频文件当前播放的时间,并显示在Current Time Label标注中。具体的操作步骤如下:
(1)将主视图中的Current Time Label标签控件与插座变量currentTime进行关联。
(2)打开ViewController.swift文件,声明一个时间定时器,代码如下:
var timer:NSTimer?=nil
(3)在playAudio()动作中,添加一行代码,实现定时器的创建,代码如下:
@IBAction func playAudio(sender: AnyObject) {
audioEffect?.play() //播放声音
playButton.setBackgroundImage(UIImage(named: "pauseImage.png"), forState: UIControlState.Normal)
playButton.addTarget(self, action: ("pauseAudio"), forControlEvents: UIControlEvents.TouchUpInside)
//创建定时器
timer=NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: ("updateProgress"), userInfo: nil, repeats: true)
}
(4)添加updateProgress()方法,实现当前播放时间的更新。代码如下:
func updateProgress(){
let currentTimeMinutes=Int(self.audioEffect!.currentTime/60) //获取分钟数
let currentTimeSeconds=Int(audioEffect!.currentTime - Double(currentTimeMinutes*60))//获取秒数
currentTime.text="\(currentTimeMinutes):\(currentTimeSeconds)"
}
此时运行程序,会看到如图2.34所示的效果。当轻拍播放按钮后,会看到当前时间在不停的进行更新,如图2.35所示。
图2.34 初始状态 图2.35 更新当前播放时间
注意:当用户轻拍暂停按钮后,此时的音频文件就会暂停播放,当前播放的时间停止更新,此时需要在pauseAudio()动作中添加一行代码,实现此功能,代码如下:
func pauseAudio(){
audioEffect?.stop() //暂停
playButton.setBackgroundImage(UIImage(named: "playImage.png"), forState: UIControlState.Normal)
playButton.addTarget(self, action: ("playAudio:"), forControlEvents: UIControlEvents.TouchUpInside)
timer?.invalidate() //让定时器失效
}
iOS 9音频应用通过进度条查看进度
通过进度条查看进度可以让用户更为直接的看出音频文件播放了多少,还剩余多少,在图2.32中也使用到了此方法。在iOS中有两个控件可以实现进度条的功能:一种是Progress View控件;另一种是Slider控件。在本书中为了更为直观的看到音频文件多放了多少,还剩多少没有播放,我们采用Slider实现进度条的功能。
【示例2-9】以下将以第一个实例为基础,实现通过进度条查看进度的功能。具体的操作步骤如下:
(1)将主视图中的Progress Slider滑块控件与插座变量progressSlider进行关联。
(2)打开ViewController.swift文件,在updateProgress()方法中添加一行代码,对Slider控件的值进行设置,代码如下:
func updateProgress(){
let currentTimeMinutes=Int(self.audioEffect!.currentTime/60)
let currentTimeSeconds=Int(Double(audioEffect!.currentTime) - Double(currentTimeMinutes*60))
currentTime.text="\(currentTimeMinutes):\(currentTimeSeconds)"
self.progressSlider.value=Float(self.audioEffect!.currentTime/self.audioEffect!.duration)
}
此时运行程序,会看到如图2.36所示的效果。当轻拍播放按钮后,会看到当前时间在不停的进行更新,如图2.37所示。
图2.36 初始状态 图2.37 更新进度
iOS 9音频应用拖动进度条播放
在音乐应用中,用户都可以以拖动进度条的方式指定音频文件播放的位置。此功能的实现还需要使用到currentTime属性。
【示例2-10】以下将以第一个实例为基础,实现拖动进度条实现播放的功能。具体的操作步骤如下:
@IBAction func dragPlayAudio(sender: AnyObject) {
if(audioEffect!.playing){
//设置当前播放的时间
audioEffect!.currentTime=Double(progressSlider.value) * Double(audioEffect!.duration)
}else{
let alertController = UIAlertController(title: "提示", message: "音乐没有播放,拖动无效", preferredStyle: UIAlertControllerStyle.Alert)
let action = UIAlertAction(title: "知道了", style: UIAlertActionStyle.Default){
(action: UIAlertAction!) -> Void in
self.audioEffect?.currentTime=0.0
self.progressSlider.value=0.0
}
alertController.addAction(action)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
此时运行程序,在出现的模拟器界面中轻拍播放按钮,此时iOS 9音频应用开发音频文件就会播放。当开发者拖动进度条中的滑块后,音频文件就会播放滑块所在位置处的声音。
注意:拖动iOS 9音频应用开发进度条播放并需要在音频文件播放时实现,否则就会出现“音乐没有播放,拖动无效”的警告视图,如图2.38所示。
图2.38 警告视图
本文选自:iOS 9音频应用开发基础教程大学霸内部资料,转载请注明出处,尊重技术尊重IT人!
iOS swift 简单的对象存储和读取
第一步:定义一个对象,并且把它序列化。
class Person:NSObject,NSCoding
{
override init()
{
}
var name = "zhang"
var ega:Int32 = 22
required init(coder aDecoder: NSCoder){
super.init()
self.name = aDecoder.decodeObjectForKey("name") as! String
self.ega = aDecoder.decodeInt32ForKey("ega")
}
func encodeWithCoder(aCoder: NSCoder)
{
aCoder.encodeObject(self.name, forKey: "name")
aCoder.encodeInt32(self.ega, forKey: "ega")
}
}
对象格式定义好,就可以把它储存了。
方法一 :使用NSUserDefaults
func keepNSUserDefaultsLocal()
{
var vperson = Person()
vperson.ega = 55
vperson.name = "李四"
var personData = NSKeyedArchiver.archivedDataWithRootObject(vperson)
NSUserDefaults.standardUserDefaults().setObject(personData, forKey: "person1")
//读取
/**
//当第一次使用,要设置默认值可以采用
NSUserDefaults.standardUserDefaults().registerDefaults(["key1":"222","key2":55])
*/
var personData2 = NSUserDefaults.standardUserDefaults().objectForKey("person1") as! NSData
var person = NSKeyedUnarchiver.unarchiveObjectWithData(personData2) as! Person
}
方法二:把对象储存在本地文件
func keepLocalFile()
{
var vperson = Person()
vperson.ega = 45
vperson.name = "王五"
var pathStr = NSHomeDirectory().stringByAppendingPathComponent("person.data")
NSKeyedArchiver.archiveRootObject(vperson, toFile: pathStr)
//读出
var personNew = NSKeyedUnarchiver.unarchiveObjectWithFile(pathStr) as! Person
}
方法三:多个对象直接存储并且分别读出单个值。
func muchPersonLocal()
{
var person1 = Person()
person1.ega = 51
person1.name = "李四"
var person2 = Person()
person2.ega = 52
person2.name = "王五"
var person3 = Person()
person3.ega = 53
person3.name = "赵六"
var data = NSMutableData()
var archive = NSKeyedArchiver(forWritingWithMutableData: data)
archive.encodeObject(person1, forKey: "lisi")
archive.encodeObject(person2, forKey: "wangwu")
archive.encodeObject(person3, forKey: "zhaoliu")
archive.finishEncoding()
var writePath = NSHomeDirectory().stringByAppendingPathComponent("muchperson.data")
data.writeToFile(writePath, atomically: true)
//分别读出数据
var readData = NSData(contentsOfFile: writePath)
var unarchiver = NSKeyedUnarchiver(forReadingWithData: readData!)
var Lisi = unarchiver.decodeObjectForKey("lisi") as! Person
var wangwu = unarchiver.decodeObjectForKey("wangwu") as! Person
var zhaoliu = unarchiver.decodeObjectForKey("zhaoliu") as! Person
print(Lisi.name)
print(wangwu.name)
print(zhaoliu.name)
}
ios – 在swift中延迟运行动画
NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(3),target: self,selector: "functionHere",userInfo: nil,repeats: false)
如果您有任何想法,请告诉我.
let pulseAnimation = CABasicAnimation(keyPath: "opacity") pulseAnimation.duration = 1 pulseAnimation.fromValue = 0 pulseAnimation.tovalue = 1 pulseAnimation.timingFunction = camediatimingFunction(name: kcamediatimingFunctionEaseInEaSEOut) pulseAnimation.autoreverses = true pulseAnimation.repeatCount = FLT_MAX XBoxOneL.layer.addAnimation(pulseAnimation,forKey: "animateOpacity") XBoxOneR.layer.addAnimation(pulseAnimation,forKey: "animateOpacity")
解决方法
func performMyAnimation() { UIView.animate(withDuration: {$duration},animations: { /* Animation Here */ },completion: { _ in self.performSegue(withIdentifier: "segueIdentifierHere",sender: nil) } }
您的动画在动画块中运行.完成后,您将执行segue到下一个屏幕.
编辑:由于问题现在包括动画代码,使用CABasicAnimation,然后可能this answer for CAAnimation回调可能适合您.
基本上,您需要使用CATransaction包装CABasicAnimation调用.
CATransaction.begin() CATransaction.setCompletionBlock({ self.performSegue(withIdentifier: "segueIdentifierHere",sender: nil) }) // Your animation here CATransaction.commit()
ios – 如何在swift中进行多重继承?
解决方法
protocol Motion { func move() } extension Motion where Self: PetViewController { func move() { //Open mouth } } class PetViewController: UIViewController,Motion{ var isLoud: Bool? func speak(){ //Open Mouth } } class DogViewController:PetViewController { func bark() { self.speak() //Make Bark Sound } } class CatViewController: PetViewController { func meow() { self.speak() //Make Meow Sound } } //.... let cat = CatViewController() cat.move() cat.isLoud = false cat.meow()
关于在iOS Swift中进行简单的低延迟音频播放和在ios swift中进行简单的低延迟音频播放设置的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于iOS 9音频应用播放音频之iOS 9音频播放进度、iOS swift 简单的对象存储和读取、ios – 在swift中延迟运行动画、ios – 如何在swift中进行多重继承?的相关知识,请在本站寻找。
本文标签: