Как записать индекс звуков на табличном виде (Swift 4) - PullRequest
0 голосов
/ 15 января 2019

Этот код ниже записывает один и только один звук для воспроизведения через кнопку действия. Я хочу, чтобы этот код записывал несколько звуков и размещал их все в виде таблицы. Поэтому, когда пользователь выбирает ячейку табличного представления, он воспроизводит звук. Каждый звук должен быть в списке, начиная с одного, а затем вверх. 1,2,3,4 и т. Д.

   import UIKit
import AVFoundation

class ViewController: UIViewController , AVAudioPlayerDelegate , AVAudioRecorderDelegate {

@IBOutlet weak var recordBTN: UIButton!
@IBOutlet weak var playBTN: UIButton!
    @IBOutlet var theT : UITableView!


  var arrayOfAudioFiles : [String]!



var soundRecorder : AVAudioRecorder!
var soundPlayer : AVAudioPlayer!

var fileName: String = "audioFile.m4a"

override func viewDidLoad() {
    super.viewDidLoad()

    setupRecorder()
    playBTN.isEnabled = false
}

func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}

func setupRecorder() {
    let audioFilename = getDocumentsDirectory().appendingPathComponent(fileName)
    let recordSetting = [ AVFormatIDKey : kAudioFormatAppleLossless,
                          AVEncoderAudioQualityKey : AVAudioQuality.max.rawValue,
                          AVEncoderBitRateKey : 320000,
                          AVNumberOfChannelsKey : 2,
                          AVSampleRateKey : 44100.2] as [String : Any]

    do {
        soundRecorder = try AVAudioRecorder(url: audioFilename, settings: recordSetting )
        soundRecorder.delegate = self
        soundRecorder.prepareToRecord()
    } catch {
        print(error)
    }
}

func setupPlayer() {
    let audioFilename = getDocumentsDirectory().appendingPathComponent(fileName)
    do {
        soundPlayer = try AVAudioPlayer(contentsOf: audioFilename)
        soundPlayer.delegate = self
        soundPlayer.prepareToPlay()
        soundPlayer.volume = 1.0
    } catch {
        print(error)
    }
}

func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
    playBTN.isEnabled = true
}

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
    recordBTN.isEnabled = true
    playBTN.setTitle("Play", for: .normal)
}

@IBAction func recordAct(_ sender: Any) {

    if recordBTN.titleLabel?.text == "Record" {
        soundRecorder.record()
        recordBTN.setTitle("Stop", for: .normal)
        playBTN.isEnabled = false
    } else {
        soundRecorder.stop()
        recordBTN.setTitle("Record", for: .normal)
        playBTN.isEnabled = false
    }
}

@IBAction func playAct(_ sender: Any) {

    if playBTN.titleLabel?.text == "Play" {
        playBTN.setTitle("Stop", for: .normal)
        recordBTN.isEnabled = false
        setupPlayer()
        soundPlayer.play()
    } else {
        soundPlayer.stop()
        playBTN.setTitle("Play", for: .normal)
        recordBTN.isEnabled = false
    }
}




func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return arrayOfAudioFiles.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? AudioCell else {
        return UITableViewCell()
    }

    // It will display files name to table view list.
    cell.textLabel.text = "\(arrayOfAudioFiles[indexPath.row])"
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)  {
    let fileName = arrayOfAudioFiles[indexPath.row]
    setupPlayer(fileName)
}

func setupPlayer(_ fileName:String) {
    // Acces audio file using file directory and play the audio file.
    let audioFilename = getDocumentsDirectory().appendingPathComponent(fileName)
    do {
        soundPlayer = try AVAudioPlayer(contentsOf: audioFilename)
        soundPlayer.delegate = self
        soundPlayer.prepareToPlay()
        soundPlayer.volume = 1.0
    } catch {
        print(error)
    }
}

}

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Вы используете общий FileName для каждой записи, следовательно, он отменяет предыдущую. Чтобы вести список записей и отображать их в tableView, вам нужно поддерживать массив имен записей. Вот код:

class ViewController: UIViewController , AVAudioPlayerDelegate , AVAudioRecorderDelegate {

    var aryRecordingNames:[String] = [] //to store recording filenames
    .....
    .....

    func preprareAndBeginNewRecording() {
        let fileName = "audioFile_" + "\(aryRecordingNames.count)" + ".m4a"
        aryRecordingNames.append(fileName)
        let audioFilename = getDocumentsDirectory().appendingPathComponent(fileName)
        let recordSetting = [ AVFormatIDKey : kAudioFormatAppleLossless,
                              AVEncoderAudioQualityKey : AVAudioQuality.max.rawValue,
                              AVEncoderBitRateKey : 320000,
                              AVNumberOfChannelsKey : 2,
                              AVSampleRateKey : 44100.2] as [String : Any]

        do {
            soundRecorder = try AVAudioRecorder(url: audioFilename, settings: recordSetting )
            soundRecorder.delegate = self
            soundRecorder.prepareToRecord()
            soundRecorder.record()
        } catch {
            print(error)
        }
    }

    func prepareAndPlayAudioAtIndex(_ index:Int) {
        let fileName = "audioFile_" + "\(index)" + ".m4a"
        let audioFilename = getDocumentsDirectory().appendingPathComponent(fileName)
        do {
            soundPlayer = try AVAudioPlayer(contentsOf: audioFilename)
            soundPlayer.delegate = self
            soundPlayer.prepareToPlay()
            soundPlayer.volume = 1.0
            soundPlayer.play()
        } catch {
            print(error)
        }
    }
}

Каждый раз, когда вы собираетесь запустить новую запись, используя preprareAndBeginNewRecording(), вы фактически создаете новое имя файла и добавляете его в aryRecordingNames и в методе делегата audioRecorderDidFinishRecording() перезагружаете tableView, чтобы получить новую запись на список.

Если вы хотите воспроизвести файл для определенной записи, то у вас должен быть индекс из tableViewCell (из которого выбрана кнопка воспроизведения), просто вызовите метод prepareAndPlayAudioAtIndex с этим индексом.

Вот код для отображения списка и воспроизведения записи с использованием UITableView

extension ViewController:UITableViewDataSource,UITableViewDelegate{
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return aryRecordingNames.count
    }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "RecordingCell") as? RecordingCell else {
            return UITableViewCell()
        }

        // configure your cell here
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)  {
       //you can do this work on button click as well, I am assuming playback begins on UITableViewCell did select
       prepareAndPlayAudioAtIndex(indexPath.row)
    }
}
0 голосов
/ 15 января 2019

Решение этого требования заключается в реализации методов делегата и источника данных табличного представления.

Перед реализацией методов делегирования табличного представления и источника данных необходимо сохранить аудиозапись в локальный каталог файлов. и получить этот локальный путь к аудиофайлам в один массив (т.е. arrayOfAudioFiles) это будет источник данных для вашего табличного представления

//Declare a variable which will hold audio paths into it.
//Every time when you record audio files add it to below array.

 var arrayOfAudioFiles : [String]!

Ниже приведены методы табличного представления, которые вам нужно реализовать.

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return arrayOfAudioFiles.count
    }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "AudioCell") as? AudioCell else {
            return UITableViewCell()
        }

     // It will display files name to table view list.
        cell.textLabel.text = "\(arrayOfAudioFiles[indexPath.row])"
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)  {
       let fileName = arrayOfAudioFiles[indexPath.row]
       setupPlayer(fileName)
    } 

    func setupPlayer(_ fileName:String) {
      // Acces audio file using file directory and play the audio file.
        let audioFilename = getDocumentsDirectory().appendingPathComponent(fileName)
        do {
            soundPlayer = try AVAudioPlayer(contentsOf: audioFilename)
            soundPlayer.delegate = self
            soundPlayer.prepareToPlay()
            soundPlayer.volume = 1.0
        } catch {
            print(error)
        }
    }

Ссылка для хранения файлов в каталоге файлов и воспроизведения аудиофайлов:

https://mobikul.com/play-audio-file-save-document-directory-ios-swift/

...