我有一個包含一些資料的本地JSON檔案。我需要知道,如何從本地JSON檔案加載音頻,并將其加載到表視圖中的按鈕。我的JSON檔案:
{
"beatPack"/span>:
{
"loops": [
{
"name": "Away we go",
"生產商": "Tubular Kingz",
"計數": "28",
"genre": "Lo-fi Hip Hop",
"imagename": "beatpackone".
"songName": "alien.mp3"/span>
}
]
}
}
所以它應該在表格視圖中顯示每首歌曲的按鈕。這里是我的歌曲方法,它們可以在每一行中顯示歌曲,但不是從JSON中顯示,也不是我需要的正確編號:
func playLoop(songName: String) {
let url = Bundle.main.url(forResource: songName, withExtension: ".mp3") //你應該檢查它是否有錯誤。
audioPlayer = try! AVAudioPlayer( contentsOf: url! ) //當然,你應該抓住這個錯誤并加以處理......
audioPlayer.play()
print(songName)
}
func gettingSongName() {
let folderURL = URL(fileURLWithPath: Bundle.main.resourcePath!)
do {
let songPath = try FileManager.default.contentsOfDirectory(at: folderURL, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
for song in songPath {
var mySong = song.absoluteString
if mySong.contains(" .mp3") {
let findString = mySong.component(separateBy: "/")
mySong = findString[findString.count - 1]
mySong = mySong.replacingOccurrences(of: " ", with: " ")
mySong = mySong.replacingOccurrences(of: " .mp3", with: "")
songs.append(mySong)
}
}
} catch {
}
}
這是我的表視圖:
extension BPLibraryViewController: UITableViewDataSource, UITableViewDelegate, UIScrollViewDelegate{
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 180 {
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1 {
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return loopsName.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: S. newOneCell, for: indexPath) as! BeatPackLibraryCell。
let loopsCount = loopsName[indexPath.row] //我們的陣列實體來自JSON。
cell.loopNameLabel.text = loopsCount.name
cell.producerNameLabel.text = loopsCount.producer
cell.loopsCountLabel.text = String(loopsName.count)
cell.genreLabel.text = loopsCount.genre
cell.firstBeatButtonLabel.setImage(UIImage(named: loopsCount.imagename), for: .normal)
cell.delegate = self
cell.selectionStyle = .none
cell.tag = indexPath.row
if let playingCell = currentPlayingIndex, playingCell= indexPath.row {
cell.firstBtnOutlet.setImage(UIImage(named: "pauseButtonPack.png"), for:
.normal)
} else {
cell.firstBtnOutlet.setImage(UIImage(named: "playButtonPack.png" ), for:
.normal)
}
return cell
}
在每一行中播放歌曲的按鈕:
extension BPLibraryViewController: BeatPackLibraryDelegate {
func didTapFirstSong(cell: BeatPackLibraryCell) {
let indexPath = self.tableView.indexPath(for: cell)
if currentPlayingIndex == cell.tag {
audioPlayer.pause()
currentPlayingIndex = nil
} else { /if PAUSE BUTTON
playLoop(songName: songs[cell.tag])
currentPlayingIndex = cell.tag
}
tableView.reloadData()
print("Done"/span>)
}
因此,如何從本地JSON檔案加載歌曲,并在每一行中顯示它。
uj5u.com熱心網友回復:
首先,方法playLoop不能作業,因為withExtension引數中的檔案擴展名必須不帶點。
我的建議是在Loop結構中添加一個計算屬性,以獲得應用程式捆綁的URL,例如
struct Loop : Decodable {
let name, producer, count, genre, imagename, songName : String
private enum CodingKeys : String, CodingKey { case name, producer, count, genre, imagename, songName }
var songURL : URL {
let components = songName.component(separateBy: ". ")
guard components.count == 2,
let url = Bundle.main.url(forResource: components[0], withExtension: components[1] ) else { fatalError("音頻檔案丟失") }
return url
}
}
CodingKeys是必須的,以排除songURL被解碼。
如果所有的音頻檔案都是mp3檔案,你甚至可以在JSON中省略擴展名,并且計算的屬性變得更短
struct Loop : Decodable {
let name, producer, count, genre, imagename, songName : String
private enum CodingKeys : String, CodingKey { case name, producer, count, genre, imagename, songName }
var songURL : URL {
guard let url = Bundle.main.url(forResource: songName, withExtension: "mp3") else { fatalError("音頻檔案丟失") }
return url
}
}
現在你可以把playLoop方法改為
func playLoop(songURL: URL) {
audioPlayer = try! AVAudioPlayer(contentsOf: songURL)
audioPlayer.play()
print(songURL.lastPathComponent)
}
并在tap方法中播放歌曲
。else { //IF PAUSE BUTTON
playLoop(songURL: loopsName[indexPath.row].songURL)
currentPlayingIndex = cell.tag
}
方法gettingSongName()是不需要的。順便說一下,它可以用兩行來寫
func gettingSongName() {
guard let mp3URLs = Bundle.main.urls(forResourcesWithExtension: "mo3", subdirectory: nil) else { return }
歌曲 = mp3URLs.map{$0.deletePathExtension().lastPathComponent}。
}
注意事項:
- 千萬不要在檔案系統的URL上呼叫
absoluteString,你可以用path獲得路徑。 - 給你的資料源陣列命名為
loops,給cellforRow中的專案命名為loops。你的命名是相當混亂的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/311735.html
標籤:

