У меня проблема, когда я пытаюсь поменять местами проигрыватели AudioKit - PullRequest
0 голосов
/ 02 ноября 2019

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

Допустим, у меня есть пять проигрывателей и один рекордер для этих проигрывателей, я записываю player1 один раз и player2 один раз, если япытаясь обменяться между ними, обмен удаётся. Если я записываю player1 дважды и player2 дважды, своп завершается успешно, но если я записываю player1 дважды и player2 один раз, во время свопа он говорит, что player1 не существует (ноль) - Неустранимая ошибка: неожиданно обнаружен ноль, а неявноразвертывание необязательного значения.

Другая проблема: я записал player1 дважды, player2 дважды и player3 и player4 один раз, я пытаюсь поменять местами player3 и player4, но он говорит, что player3 или player4 не существует(nil) - Неустранимая ошибка: неожиданно обнаружен nil при неявном развертывании необязательного значения. Только если player1 и player2 записаны один раз или player3 и player4 записаны дважды, это будет успешно.

Последняя проблема: я записал player1 один раз и player2 один раз, я хочу поменять местами player1 с пустым player3, это удастся. Когда я пытаюсь переключиться между player2 и player1 (который теперь должен быть пустым), он говорит, что player1 не существует (nil) - Неустранимая ошибка: неожиданно обнаружен nil при неявном развертывании необязательного значения, когда player1 теперь должен бытьпоменялись местами с записью на player2.

Помогите мне понять, почему это так расстраивает. вот код:

@objc func startStopClipRecording1(button: UIButton, event: UIEvent) {

    switch self.state {
       case .readyToRecord :

           if self.recorded1 == true{
           while multiPlayers.contains(player1) {
               if let itemToRemoveIndex = multiPlayers.firstIndex(of: player1) {
                   multiPlayers.remove(at: itemToRemoveIndex)
               }
           }
        }

           self.plot?.node = self.mic
           self.state = .recording

    _ = AVAudioTime(hostTime: UInt64(event.timestamp * secondsToTicks))

           guard let lastRenderHostTime = mainMixer.avAudioNode.lastRenderTime?.hostTime else { fatalError("Engine not running!") }

           let audioSession = AKSettings.session
           let bufferDurationTicks = UInt64(audioSession.ioBufferDuration * secondsToTicks)
           let outputLatencyTicks = UInt64(audioSession.outputLatency * secondsToTicks)
           let inputLatencyTicks = UInt64(audioSession.inputLatency * secondsToTicks)

           let nextRenderHostTime = lastRenderHostTime + bufferDurationTicks

           let renderAfterNextHostTime = nextRenderHostTime + bufferDurationTicks

           let startTimeHost = renderAfterNextHostTime + outputLatencyTicks

           let playbackStartTime = AVAudioTime(hostTime: startTimeHost - outputLatencyTicks)

           let recordingStartTime = AVAudioTime(hostTime: startTimeHost + inputLatencyTicks)

           metronome.beatTime = 0
           directRecorder?.currentTime = 0

        var bars = 30 / (4 * (60 / metronome.tempo))
        bars.round(.towardZero)
        let durationClipRec = bars * (4 * (60 / metronome.tempo))

           try? directRecorder?.recordClip(time: 0, duration: durationClipRec, tap: nil) { result in
               switch result {
               case .error(let error):
                   AKLog(error)
                   return
               case .clip(let clip):
                   AKLog("direct.duration \(clip.duration)")
                   AKLog("direct.StartTime \(clip.startTime)")

                   do {
                    let urlInDocs = FileManager.docs.appendingPathComponent(self.filename1).appendingPathExtension(clip.url.pathExtension)

                    if FileManager.default.fileExists(atPath: urlInDocs.path){
                        FileManager.emtpyDocumentsDirectory()
                    }

                       try FileManager.default.moveItem(at: clip.url, to: urlInDocs)

                    self.url1 = urlInDocs

                    self.clip1 = clip

                       AKLog("Direct saved at " + urlInDocs.path)
                   } catch {
                       AKLog(error)
                   }
               }
           }


           let todoDelay = 0.001

        if self.recordedButNot1 == true{


                   multiPlayers.forEach { player in
                       player.play(at: playbackStartTime) }
            metronome.play(at: recordingStartTime + todoDelay)
            directRecorder?.start(at: recordingStartTime)
            recTimer1 = Timer.scheduledTimer(timeInterval: 30.2, target:self, selector:#selector(recAction1), userInfo:nil, repeats:false)
        }else{
           metronome.play(at: recordingStartTime + todoDelay)
           directRecorder?.start(at: recordingStartTime)
            recTimer1 = Timer.scheduledTimer(timeInterval: 30.2, target:self, selector:#selector(recAction1), userInfo:nil, repeats:false)
        }

        case .recording :

            directRecorder?.stopRecording()
            directRecorder?.stop()

        recordAction1()
          }

}

@objc func recAction1(){
    recordAction1()
}

func recordAction1(){

    self.addPlayer1(withFileURL: url1)

                          self.instButton1.isHidden = false
              swapMButton.isUserInteractionEnabled = true

                          self.plot?.node = nil

                               self.recorded1 = true
                               self.firstRecordDuration = true

                               self.recordedButNot2 = true
                               self.recordedButNot3 = true
                               self.recordedButNot4 = true
                               self.recordedButNot5 = true

                          self.metronome.stop()

                                    self.setupUIForPlaying()
                                    self.setupUIForRecording1()              


    recTimer1.invalidate()
}

    private func addPlayer1(withFileURL url: URL) {
       player1 = AKPlayer(url: url)
       player1.buffering = .always
       player1.prepare()
    player1.pan = 0
       self.multiPlayers.append(self.player1)
       self.mainMixer.connect(input: self.player1)
   }

func swap(_ str1: inout URL, _ str2: inout URL) {
      (str1, str2) = (str2, str1)
    }

func swapPlayers(AKplayer: AKPlayer, urlString: URL, timeLabel1: UITextField, timeLabel2: UITextField, 
textField1: UITextField, textField2: UITextField, playerName1: String, playerName2: String, 
instrument1: InstrumentButton, instrument2: InstrumentButton, isPlayer2Recorded: Bool, button1: 
UIImageView, button2: UIImageView, maskLayer: CAShapeLayer, view: UIView){

    while self.multiPlayers.contains(AKplayer) {
                   if let itemToRemoveIndex = self.multiPlayers.firstIndex(of: AKplayer) {
                       self.multiPlayers.remove(at: itemToRemoveIndex)
                   }
               }

    if playerName1 == self.recordingName1{

        fileName = filename1
        clip6 = clip1
    }
    if playerName1 == self.recordingName2{

        fileName = filename2
        clip6 = clip2
    }
    if playerName1 == self.recordingName3{

       fileName = filename3
        clip6 = clip3
    }
    if playerName1 == self.recordingName4{

       fileName = filename4
        clip6 = clip4
    }
    if playerName1 == self.recordingName5{

        fileName = filename5
        clip6 = clip5
    }

    let myLayer = plot!.waveformLayer!
    myLayer.path = maskLayer.path
    view.layer.addSublayer(myLayer)
    self.plot?.clear()


               instTextField6.text = textField1.text
               recordingTimeLabel6.text = timeLabel1.text

               if isPlayer2Recorded == true{

                if playerName2 == self.recordingName1{
                    AKplayer2 = player1
                }
                if playerName2 == self.recordingName2{
                    AKplayer2 = player2
                }
                if playerName2 == self.recordingName3{
                    AKplayer2 = player3
                }
                if playerName2 == self.recordingName4{
                    AKplayer2 = player4
                }
                if playerName2 == self.recordingName5{
                    AKplayer2 = player5
                }
                textField1.text = textField2.text
                textField2.text = instTextField6.text

                selectedInstrumentToImage(button: instrument1, textField: textField1)
                selectedInstrumentToImage(button: instrument2, textField: textField2)

                timeLabel1.text = timeLabel2.text
                timeLabel2.text = recordingTimeLabel6.text

                   while self.multiPlayers.contains(AKplayer2) {
                       if let itemToRemoveIndex = self.multiPlayers.firstIndex(of: AKplayer2) {
                           self.multiPlayers.remove(at: itemToRemoveIndex)

                       }
                }
                       if playerName1 == self.recordingName1{
                           if playerName2 == self.recordingName2{
                            print(url1!)
                            print(url2!)
                            swap(&url1, &url2)
                            print(url1!)
                            print(url2!)
                            addPlayer1(withFileURL: url1)
                            addPlayer2(withFileURL: url2)
                           }
                           if playerName2 == self.recordingName3{
                               self.url1 = self.url3
                               self.url3 = self.url6
                            addPlayer1(withFileURL: url1)
                            addPlayer3(withFileURL: url3)
                           }
                           if playerName2 == self.recordingName4{
                               self.url1 = self.url4
                               self.url4 = self.url6
                            addPlayer1(withFileURL: url1)
                            addPlayer4(withFileURL: url4)
                           }
                           if playerName2 == self.recordingName5{
                               self.url1 = self.url5
                               self.url5 = self.url6
                            addPlayer1(withFileURL: url1)
                            addPlayer5(withFileURL: url5)
                           }
                       }

                       if playerName1 == self.recordingName2{
                           if playerName2 == self.recordingName1{
                               self.url2 = self.url1
                               self.url1 = self.url6
                            addPlayer2(withFileURL: url2)
                            addPlayer1(withFileURL: url1)
                           }
                           if playerName2 == self.recordingName3{
                               self.url2 = self.url3
                               self.url3 = self.url6
                            addPlayer2(withFileURL: url2)
                            addPlayer3(withFileURL: url3)
                           }
                           if playerName2 == self.recordingName4{
                               self.url2 = self.url4
                               self.url4 = self.url6
                            addPlayer2(withFileURL: url2)
                            addPlayer4(withFileURL: url4)
                           }
                           if playerName2 == self.recordingName5{
                               self.url2 = self.url5
                               self.url5 = self.url6
                            addPlayer2(withFileURL: url2)
                            addPlayer5(withFileURL: url5)
                           }
                       }

                       if playerName1 == self.recordingName3{
                           if playerName2 == self.recordingName1{
                               self.url3 = self.url1
                               self.url1 = self.url6
                            addPlayer3(withFileURL: url3)
                            addPlayer1(withFileURL: url1)
                           }
                           if playerName2 == self.recordingName2{
                               self.url3 = self.url2
                               self.url2 = self.url6
                            addPlayer3(withFileURL: url3)
                            addPlayer2(withFileURL: url2)
                           }
                           if playerName2 == self.recordingName4{
                               self.url3 = self.url4
                               self.url4 = self.url6
                            addPlayer3(withFileURL: url3)
                            addPlayer4(withFileURL: url4)
                           }
                           if playerName2 == self.recordingName5{
                               self.url3 = self.url5
                               self.url5 = self.url6
                            addPlayer3(withFileURL: url3)
                            addPlayer5(withFileURL: url5)
                           }
                       }

                       if playerName1 == self.recordingName4{
                           if playerName2 == self.recordingName1{
                               self.url4 = self.url1
                               self.url1 = self.url6
                            addPlayer4(withFileURL: url4)
                            addPlayer1(withFileURL: url1)
                           }
                           if playerName2 == self.recordingName2{
                               self.url4 = self.url2
                               self.url2 = self.url6
                            addPlayer4(withFileURL: url4)
                            addPlayer2(withFileURL: url2)
                           }
                           if playerName2 == self.recordingName3{
                               self.url4 = self.url3
                               self.url3 = self.url6
                            addPlayer4(withFileURL: url4)
                            addPlayer3(withFileURL: url3)
                           }
                           if playerName2 == self.recordingName5{
                               self.url4 = self.url5
                               self.url5 = self.url6
                            addPlayer4(withFileURL: url4)
                            addPlayer5(withFileURL: url5)
                           }
                       }

                       if playerName1 == self.recordingName5{
                           if playerName2 == self.recordingName1{
                               self.url5 = self.url1
                               self.url1 = self.url6
                            addPlayer5(withFileURL: url5)
                            addPlayer1(withFileURL: url1)
                           }
                           if playerName2 == self.recordingName2{
                               self.url5 = self.url2
                               self.url2 = self.url6
                            addPlayer5(withFileURL: url5)
                            addPlayer2(withFileURL: url2)
                           }
                           if playerName2 == self.recordingName3{
                               self.url5 = self.url3
                               self.url3 = self.url6
                            addPlayer5(withFileURL: url5)
                            addPlayer3(withFileURL: url3)
                           }
                           if playerName2 == self.recordingName4{
                               self.url5 = self.url4
                               self.url4 = self.url6
                            addPlayer5(withFileURL: url5)
                            addPlayer4(withFileURL: url4)
                           }
                       }

               }else{


                button1.isUserInteractionEnabled = false
                button2.isUserInteractionEnabled = true

                textField1.text = ""
                textField2.text = instTextField6.text

                selectedInstrumentToImage(button: instrument1, textField: textField1)
                selectedInstrumentToImage(button: instrument2, textField: textField2)

                timeLabel1.text = timeLabel2.text
                timeLabel2.text = recordingTimeLabel6.text


                   if playerName1 == self.recordingName1{

                    recorded1 = false
                    reverb1.outputNode.removeTap(onBus: 0)
                    delay1.outputNode.removeTap(onBus: 0)
                    player1.outputNode.removeTap(onBus: 0)
                    player1 = nil
                    delaySlider1.isEnabled = false
                    reverbSlider1.isEnabled = false
                    volumeSlider1.isEnabled = false
                    soloButton1.isEnabled = false
                    muteButton1.isEnabled = false

                       if playerName2 == self.recordingName2{
                           self.url1 = nil
                           self.clip1 = nil
                           self.url2 = self.url6
                        addPlayer2(withFileURL: url2)
                        recorded2 = true
                       }
                       if playerName2 == self.recordingName3{
                           self.url1 = nil
                           self.clip1 = nil
                           self.url3 = self.url6
                        addPlayer3(withFileURL: url3)
                        recorded3 = true
                       }
                       if playerName2 == self.recordingName4{
                           self.url1 = nil
                           self.clip1 = nil
                           self.url4 = self.url6
                        addPlayer4(withFileURL: url4)
                         recorded4 = true
                       }
                       if playerName2 == self.recordingName5{
                           self.url1 = nil
                           self.clip1 = nil
                           self.url5 = self.url6
                        addPlayer5(withFileURL: url5)
                        recorded5 = true
                       }
                   }

                   if playerName1 == self.recordingName2{

                    recorded2 = false
                    reverb2.outputNode.removeTap(onBus: 0)
                    delay2.outputNode.removeTap(onBus: 0)
                    player2.outputNode.removeTap(onBus: 0)
                    player2 = nil
                    delaySlider2.isEnabled = false
                    reverbSlider2.isEnabled = false
                    volumeSlider2.isEnabled = false
                    soloButton2.isEnabled = false
                    muteButton2.isEnabled = false

                       if playerName2 == self.recordingName1{
                           self.url2 = nil
                           self.clip2 = nil
                           self.url1 = self.url6
                        addPlayer1(withFileURL: url1)
                        recorded1 = true
                       }
                       if playerName2 == self.recordingName3{
                           self.url2 = nil
                           self.clip2 = nil
                           self.url3 = self.url6
                        addPlayer3(withFileURL: url3)
                         recorded3 = true
                       }
                       if playerName2 == self.recordingName4{
                           self.url2 = nil
                           self.clip2 = nil
                           self.url4 = self.url6
                        addPlayer4(withFileURL: url4)
                        recorded4 = true
                       }
                       if playerName2 == self.recordingName5{
                           self.url2 = nil
                           self.clip2 = nil
                           self.url5 = self.url6
                        addPlayer5(withFileURL: url5)
                        recorded5 = true
                       }
                   }

                   if playerName1 == self.recordingName3{

                    recorded3 = false
                    reverb3.outputNode.removeTap(onBus: 0)
                    delay3.outputNode.removeTap(onBus: 0)
                    player3.outputNode.removeTap(onBus: 0)
                    player3 = nil
                    delaySlider3.isEnabled = false
                    reverbSlider3.isEnabled = false
                    volumeSlider3.isEnabled = false
                    soloButton3.isEnabled = false
                    muteButton3.isEnabled = false

                       if playerName2 == self.recordingName1{
                           self.url3 = nil
                           self.clip3 = nil
                           self.url1 = self.url6
                        addPlayer1(withFileURL: url1)
                        recorded1 = true
                       }
                       if playerName2 == self.recordingName2{
                           self.url3 = nil
                           self.clip3 = nil
                           self.url2 = self.url6
                        addPlayer2(withFileURL: url2)
                        recorded2 = true
                       }
                       if playerName2 == self.recordingName4{
                           self.url3 = nil
                           self.clip3 = nil
                           self.url4 = self.url6
                        addPlayer4(withFileURL: url4)
                        recorded4 = true
                       }
                       if playerName2 == self.recordingName5{
                           self.url3 = nil
                           self.clip3 = nil
                           self.url5 = self.url6
                        addPlayer5(withFileURL: url5)
                        recorded5 = true
                       }
                   }

                   if playerName1 == self.recordingName4{

                    recorded4 = false
                    reverb4.outputNode.removeTap(onBus: 0)
                    delay4.outputNode.removeTap(onBus: 0)
                    player4.outputNode.removeTap(onBus: 0)
                    player4 = nil
                    delaySlider4.isEnabled = false
                    reverbSlider4.isEnabled = false
                    volumeSlider4.isEnabled = false
                    soloButton4.isEnabled = false
                    muteButton4.isEnabled = false

                       if playerName2 == self.recordingName1{
                           self.url4 = nil
                           self.clip4 = nil
                           self.url1 = self.url6
                        addPlayer1(withFileURL: url1)
                        recorded1 = true
                       }
                       if playerName2 == self.recordingName2{
                           self.url4 = nil
                           self.clip4 = nil
                           self.url2 = self.url6
                        addPlayer2(withFileURL: url2)
                        recorded2 = true
                       }
                       if playerName2 == self.recordingName3{
                           self.url4 = nil
                           self.clip4 = nil
                           self.url3 = self.url6
                        addPlayer3(withFileURL: url3)
                         recorded3 = true
                       }
                       if playerName2 == self.recordingName5{
                           self.url4 = nil
                           self.clip4 = nil
                           self.url5 = self.url6
                        addPlayer5(withFileURL: url5)
                        recorded5 = true
                       }
                   }

                   if playerName1 == self.recordingName5{

                    recorded5 = false
                    reverb5.outputNode.removeTap(onBus: 0)
                    delay5.outputNode.removeTap(onBus: 0)
                    player5.outputNode.removeTap(onBus: 0)
                    player5 = nil
                    delaySlider5.isEnabled = false
                    reverbSlider5.isEnabled = false
                    volumeSlider5.isEnabled = false
                    soloButton5.isEnabled = false
                    muteButton5.isEnabled = false

                       if playerName2 == self.recordingName1{
                           self.url5 = nil
                           self.clip5 = nil
                           self.url1 = self.url6
                        addPlayer1(withFileURL: url1)
                        recorded1 = true
                       }
                       if playerName2 == self.recordingName2{
                           self.url5 = nil
                           self.clip5 = nil
                           self.url2 = self.url6
                        addPlayer2(withFileURL: url2)
                        recorded2 = true
                       }
                       if playerName2 == self.recordingName3{
                           self.url5 = nil
                           self.clip5 = nil
                           self.url3 = self.url6
                        addPlayer3(withFileURL: url3)
                         recorded3 = true
                       }
                       if playerName2 == self.recordingName4{
                           self.url5 = nil
                           self.clip5 = nil
                           self.url4 = self.url6
                        addPlayer4(withFileURL: url4)
                        recorded4 = true
                       }
                   }
                let urlInDocs = FileManager.docs.appendingPathComponent(self.fileName!).appendingPathExtension(clip6!.url.pathExtension)

                if FileManager.default.fileExists(atPath: urlInDocs.path){
                    FileManager.emtpyDocumentsDirectory()
                }

               }

}

1 Ответ

0 голосов
/ 04 ноября 2019

Я нашел решение:

вместо:

FileManager.emtpyDocumentsDirectory()

в функции startStopClipRecording, которая, как я обнаружил, удаляет все файлы, мне пришлось сделатьспециальный код для URL:

if FileManager.default.fileExists(atPath: urlInDocs.path){
                              do {
                                  try FileManager.default.removeItem(at: urlInDocs)
                                 print("File deleted", urlInDocs)
                              } catch let error as NSError {
                                  print("Error: \(error.domain)")
                              }
                          }
...