用AV Player 播放音效

如何點擊後播放音效

--

功能設計目標

使用者作答英文題目時:
Action: 點擊對應的中文解答按鈕
Event 1: 若點擊正確,就播放回答正確的音效
Event 2: 若點擊錯誤,就播放回答錯誤的音效

下載正解和錯誤的音效

上網從音效庫下載正解和錯誤音效。因為預想使用者在操作時會重複點擊按鈕,所以讓音效長度在1秒內,這樣AV Player重播才不會花太久時間。將音效拖曳到project navigator 的app資料夾下,並設定音效Destination和target

將correctSE.mp3 和 wrongSE.mp3拖曳到project navigator 下
勾選音效Destination 和 Add to targets

生成可以播放單次音效的AV Player

  1. 創建「正解播放器correctPlayer」和「錯誤播放器wrongPlayer
  2. 在ViewController下定義一個「點擊播放器clickPlayer」。視回答結果,將「正解播放器」或「錯誤播放器」assign給「點擊播放器」
  3. 載入音效檔案,從「App資料夾.Bundle.main」找到音效的路徑 .url
    forResource
    :音檔名
    withExtension: 音檔的副檔名
import AVFoundation

//創建兩個 AVPlayer, correctPlayer 和 wrongPlayer,它們分別用於播放正確和錯誤的音效
let correctPlayer = AVPlayer()
let wrongPlayer = AVPlayer()

//載入正解音效檔案 "correctSE.mp3",並創建對應的AVPlayerItem來播放正確的音效
let correctSEurl = Bundle.main.url(forResource: "correctSE", withExtension:"mp3")!
let correctPlayerItem = AVPlayerItem(url: correctSEurl)

//載入錯誤的音效檔案 "wrongSE.mp3",並創建對應的 AVPlayerItem來播放錯誤的音效
let wrongSEurl = Bundle.main.url(forResource: "wrongSE", withExtension:"mp3")!
let wrongPlayerItem = AVPlayerItem(url: wrongSEurl)

/*在ViewController中。同時定義一個叫做clickPlayer的AVPlayer,
用於處理點擊事件(回答正確/錯誤)的音效。*/
class ViewController: UIViewController {
var clickPlayer = AVPlayer()
}

使用者點選按鈕後,觸發AVPlayer的播放指令:點擊正解響起正解音效、錯誤響起錯誤音效

事先建好答案列表,將正解assign給案列表的第一個元素。檢查使用者點擊的按鈕選項是否等於 resultArray 中第一個元素的 rightAnswer,是的話則視為回答正確

若回答正確,則把「點擊播放器clickPlayer」設置成「正解播放器correctPlayer」再替換correctPlayer的音效為「正解音效檔案correctPlayerItem」,然後播放 clickPlayer.play()

另外因爲AV Player只能單次播放,所以播放完後要用.zero將播放進度條移回開始位置

若若選擇了錯誤答案,因clickPlayer 為變數,將對應的值設為「錯誤播放器wrongPlayer 」並同樣替換成錯誤音效後播放即可。

@IBAction func answerClicked(_ sender: UIButton) {

if sender.currentTitle == resultArray[0].rightAnswer {
clickPlayer = correctPlayer
correctPlayer.replaceCurrentItem(with: correctPlayerItem)
clickPlayer.play()
self.clickPlayer.seek(to: .zero)

}else if sender.currentTitle != resultArray[0].rightAnswer {

clickPlayer = wrongPlayer
wrongPlayer.replaceCurrentItem(with: wrongPlayerItem)
clickPlayer.play()
self.clickPlayer.seek(to: .zero)
}
}

成品

--

--