草庐IT

swift:音频 slider 控件

coder 2023-09-06 原文

问题:

当我转到包含按钮和 slider 的 View Controller 时,它会使应用程序崩溃并在 slider 行上给我 Thread 1:EXC_BAD_ACCESS (code=1, address=0x38) .maximumValue = Float(audioPlayer.duration)。在 View Controller 中,我有一个播放/暂停按钮、一个停止按钮和一个控制音频播放位置的 slider 。

代码:

import UIKit
import AVFoundation

class AgnesAudioViewController: UIViewController {

var audioPlayer = AVAudioPlayer()
var toggleState = 1
@IBOutlet var slider: UISlider!

@IBAction func done(sender: AnyObject) {
    dismissViewControllerAnimated(true, completion: nil)
}

@IBAction func play(sender: AnyObject) {
    audioPlayer.play()
}

@IBAction func pause(sender: AnyObject) {
    audioPlayer.pause()
}

@IBAction func stop(sender: AnyObject) {
    audioPlayer.stop()
}

@IBAction func scrubAudio(sender: AnyObject) {
    audioPlayer.stop()
    audioPlayer.currentTime = NSTimeInterval(slider.value)
    audioPlayer.prepareToPlay()
    audioPlayer.play()
}

@IBAction func playPauseButton(sender: AnyObject) {
    var playBtn = sender as! UIButton
    if toggleState == 1 {
        audioPlayer.play()
        toggleState = 2
        playBtn.setImage(UIImage(named:"pause.png"),forState:UIControlState.Normal)
    } else {
        audioPlayer.pause()
        toggleState = 1
        playBtn.setImage(UIImage(named:"play.png"),forState:UIControlState.Normal)
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("updateSlider"), userInfo: nil, repeats: true)

    slider.maximumValue = Float(audioPlayer.duration)

    let pathString = NSBundle.mainBundle().pathForResource("agnes", ofType: "mp2")

    if let pathString = pathString {

        let pathURL = NSURL(fileURLWithPath: pathString)

        do {

            try audioPlayer = AVAudioPlayer(contentsOfURL: pathURL)

        } catch {

            print("error")
        }


    }

}

func updateSlider() {
    slider.value = Float(audioPlayer.currentTime)
}
}

最佳答案

这解决了问题:

import UIKit
import AVFoundation

class AgnesAudioViewController: UIViewController {

var audioPlayer = AVAudioPlayer()
var toggleState = 1
@IBOutlet var slider: UISlider!
@IBOutlet var playedTime: UILabel!

@IBAction func done(sender: AnyObject) {
    dismissViewControllerAnimated(true, completion: nil)
    audioPlayer.stop()
}

@IBAction func play(sender: AnyObject) {
    audioPlayer.play()
    updateTime()
}

@IBAction func pause(sender: AnyObject) {
    audioPlayer.pause()
    updateTime()
}

@IBAction func stop(sender: AnyObject) {
    audioPlayer.stop()
    updateTime()
}

@IBAction func scrubAudio(sender: AnyObject) {
    audioPlayer.stop()
    audioPlayer.currentTime = NSTimeInterval(slider.value)
    audioPlayer.prepareToPlay()
    audioPlayer.play()
}

func updateTime() {
    var currentTime = Int(audioPlayer.currentTime)
    var duration = Int(audioPlayer.duration)
    var total = currentTime - duration
    var totalString = String(total)

    var minutes = currentTime/60
    var seconds = currentTime - minutes / 60

    playedTime.text = NSString(format: "%02d:%02d", minutes,seconds) as String
}

@IBAction func playPauseButton(sender: AnyObject) {
    //1 = play
    //2 = pausw
    var playBtn = sender as! UIButton
    if toggleState == 1 {
        audioPlayer.play()
        toggleState = 2
        playBtn.setImage(UIImage(named:"pause2.png"),forState:UIControlState.Normal)
    } else {
        audioPlayer.pause()
        toggleState = 1
        playBtn.setImage(UIImage(named:"play2.png"),forState:UIControlState.Normal)
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    var updateTimer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("updateTime"), userInfo: nil, repeats: true)
    var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("updateSlider"), userInfo: nil, repeats: true)

    let pathString = NSBundle.mainBundle().pathForResource("agnes", ofType: "mp3")

    if let pathString = pathString {

        let pathURL = NSURL(fileURLWithPath: pathString)

        do {

            try audioPlayer = AVAudioPlayer(contentsOfURL: pathURL)

        } catch {

            print("error")
        }


    }

    slider.maximumValue = Float(audioPlayer.duration)
}

func updateSlider() {
    slider.value = Float(audioPlayer.currentTime)
    }
}

关于swift:音频 slider 控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34971317/

有关swift:音频 slider 控件的更多相关文章

  1. micropython复现经典单片机项目(二)可视化音频 频谱解析(基本搞定) - 2

    本人是音乐爱好者,从小就特别喜欢那个随着音乐跳动的方框效果,就是这个:arduino上一大把对,我忍你很久了,我就想用mpy做,全网没有,行我自己研究。果然兴趣是最好的老师,我之前有篇博客专门讲音频,有兴趣的可以回顾一下。提到可视化频谱,必然绕不开fft,大学学过这玩意,当时一心玩,老师讲的一个字都么听进去,网上教程简略扫了一下,大该就是把时域转频域的工具,我大mpy居然没有fft函数,奶奶的,先放着。音频信息如何收集?第一种傻瓜式的ADC,模拟转数字,原始粗暴,第二种,I2S库,我之前博客有讲过,数据是PCM编码。然后又去学PCM编码,一学豁然开朗,舒服,以代码为例:audio_in=I2S

  2. 解决台式机麦克风不可用问题,只有音频输出,无音频输入 - 2

    解决台式机麦克风不可用问题戴尔灵越3880最近因为需要开线上会议,发现戴尔台式机音频只有输出没有输入,也就是只能听见声音,无法输入声音。先后尝试了各种驱动安装更新之类的调试,无果。之后通过戴尔支持解决~这里多说一句,专业的就是专业,问题描述过去,直接给了解决方案,可能是他们遇到的相似问题比较多了,但也告诉我们,有些时候是可以通过这些官方服务解决问题的,比起自己折腾效率要高很多。那就记录一下吧~问题描述:电脑只能输出声音,不能输入声音。1、前提需要准备一只带麦克风的耳机,将耳机插入面板。2、先确定是否可以听到声音,可以通过播放歌曲或者视频。3、然后确认麦克风是否可用,可以通过调用win自带麦克风

  3. ruby - 我将如何以编程方式与 VST(i) 插件交互以合成音频? - 2

    以VSTiTriforce为例,由Tweakbench提供。当加载到市场上的任何VST主机时,它允许主机向VSTi发送(大概是MIDI)信号。然后VSTi将处理该信号并输出​​由VSTi内的软件乐器创建的合成音频。例如,将A4(我相信是MIDI音符)发送到VSTi会导致它合成高于中央C的A。它将音频数据发送回VST主机,然后它可以在我的扬声器上播放或将其保存为.wav或其他一些音频文件格式。假设我有Triforce,我正在尝试用我选择的语言编写一个程序,它可以通过发送要合成的A4纸条与VSTi交互,并自动将其保存到系统上的文件?最终,我希望能够解析整个单轨MIDI文件(使用已经可用于此

  4. D类音频功放NS4110B电路设计 - 2

    特性工作电压范围:6V-14V输出功率:7W(CLASSD,7.4V/4Ω,THD=10%)10W(CLASSD,9V/4Ω,THD=10%)18W(CLASSD,12V/4Ω,THD=10%)最高可达92%效率(12V/8Ω)电平设置工作模式无需输出滤波器差分输入优异的“上电,掉电”噪声抑制过流保护、过热保护、欠压保护 eSOP-8封装典型应用电路很简单:如下是本人的设计。 输入电阻:输入电阻主要是确定增益,即输出功率,所以一定要确定输入信号的幅度,喇叭的幅度,前后使用有效值计算。此设计搭配的喇叭是8R3W,额定功率3W,额定电压4.89V(有效值),最大功率4W。我们先确定输入信号的赋值,

  5. ruby - 有效地处理数字数组的 "scale"或 "resize"的算法(音频重采样) - 2

    做音频处理(虽然它也可以是图像处理)我有一个一维数字数组。(它们恰好是代表音频样本的16位有符号整数,这个问题同样适用于float或不同大小的整数。)为了匹配不同频率的音频(例如,将44.1kHz样本与22kHz样本混合),我需要拉伸(stretch)或压缩值数组以满足特定长度。将数组减半很简单:每隔一个样本丢弃一次。[231,8143,16341,2000,-9352,...]=>[231,16341,-9352,...]将数组宽度加倍稍微不那么简单:将每个条目加倍(或可选地在相邻的“真实”样本之间执行一些插值)。[231,8143,16341,2000,-9352,...]=>[2

  6. javascript - 如何将两个输入 channel 连接到 ScriptProcessorNode? (网络音频 API,JavaScript) - 2

    我正在尝试实现一个具有两个输入channel和一个输出channel的ScriptProcessorNode。varsource=newArray(2);source[0]=context.createBufferSource();source[0].buffer=buffer[0];source[1]=context.createBufferSource();source[1].buffer=buffer[1];vartest=context.createScriptProcessor(4096,2,1);source[0].connect(test,0,0);source[1].c

  7. javascript - Angular2 表单控件 valueChanges 可观察完成从未调用 - 2

    我目前正在尝试在搜索进行时在我的搜索栏上显示一个简单的加载程序。我计划在从我的表单控件观察到的valueChanges的订阅回调中将一个变量设置为值“loading”,并在完整的回调中将其设置为一个空字符串。但是,永远不会调用完整的回调。我也尝试在finally上添加一个回调,但它也从未被调用过。我的代码:searchBox:Control=newControl();loadingClass:string="";constructor(){this.searchBox.valueChanges.debounceTime(400).distinctUntilChanged().subsc

  8. javascript - __doPostBack 只有在页面上有 LinkBut​​ton、Calendar 或 WizardStep 控件时才有效 - 2

    我发现了__doPostBack的问题并找到了解决方法。我正在寻求原因的解释和/或比我的工作更好的解决方案。场景:我有一个下拉菜单,其中填充了这些值;“-选择-”、“一”和“二”。如果用户选择“一个”,则执行客户端脚本。如果用户选择“两个”,则执行服务器端脚本。问题:客户端脚本通过调用__doPostBack启动回发。但是,除非页面上还有LinkBut​​ton、Calendar或WizardStep控件,否则实际上不会发生回发。我实际上浏览了VisualStudio工具箱中的所有标准工具并测试了它们。它必须是这三个之一。解决方法:添加一个由显示设置为无的跨度包围的链接按钮。LinkB

  9. c# - 我怎样才能让一个禁用的控件重新启用使用 Javascript - 2

    我已经编写了一个代码来在用户单击控件时禁用控件。在我的表单上,我有一个TextBox和一个DropDown。当用户单击TextBox时,我将禁用DropDown就像单击DropDown时一样,我将禁用TextBox效果很好。但是当用户点击Disabled控件时,我想启用该控件。意味着如果我点击被禁用的TextBox我想像dropdown一样Enable..我的示例脚本如下functiontoggleDropDownList1(){vard=document.getElementById("");if(d.disabled){d.disabled=false;}else{document

  10. javascript - 如何将 JS 文件与 dotnetnuke 中的模块、控件和模板链接起来? - 2

    我是dotnetnuke的新手,所以我不知道如何将js文件与模块链接,在dotnetnuke中控制模板。谁能帮帮我... 最佳答案 如果你想包含JS文件,你应该将它们放入模块中的文件夹(通常是JS文件夹)然后在代码隐藏中你可以使用下面的语法ClientResourceManager.RegisterScript(Parent.Page,"~/Resources/Shared/scripts/knockout.js");ClientResourceManager.RegisterScript(Parent.Page,"~/deskto

随机推荐