如何阻止AVAudioPlayer与其他ViewController的其他声音碰撞?

时间:2018-08-04 05:24:23

标签: swift avaudioplayer

我有两个此应用程序的视图控制器。第一个按钮可以单击以播放视频。第二个有一个可以播放的歌曲列表。我的问题是,当我从第二个控制器播放歌曲时,背景音乐与视频声音发生冲突。我希望第二个控制器发出的音乐停止播放,而不与第一个控制器发出的视频声音发生冲突。

我试图在第一个控制器中使用此代码,但是它不起作用:

audioPlayer.stop()

显示错误消息“ EXC_BAD_ACCESS Swift”

有人可以帮助我吗?谢谢:)

1 个答案:

答案 0 :(得分:0)

根据我的理解,您需要在整个应用中管理一个播放器。在我的一个项目中,我设法以下列方式使用它。请检查是否对您有帮助

struct Manager
{    
    //Required Objects - AVFoundation
    ///AVAudio Session
    static var recordingSession: AVAudioSession!

    ///AVAudio Recorder
    static var recorder: AVAudioRecorder?

    ///AVAudio Player
    static var player: AVAudioPlayer?

    ///Bool to check an audio is being played or not
    static var recordingalreadyPlayedStatus = Bool()
}

从MainSource中选择文件并播放

//MARK: Button Handler
/**
 Function is used to play selected Row music Audio File
 - parameter sender : UIButton Reference
 */
@objc func playButtonHandler(sender: UIButton)
{
    let buttonPosition : CGPoint = sender.convert(CGPoint.zero, to: self.recordingListTableView)
    let indexPath : IndexPath = self.recordingListTableView.indexPathForRow(at: buttonPosition)!

    ///Check is Recorder is Recording Sound ?
    if (Manager.recorder != nil) {
        return
    }

    ///Check Audio Already Playing ?
    /// Bool Used to check is anything getting Played
    if (Manager.recordingalreadyPlayedStatus) {
        ///If yes
        ///Stop From Playing
        if self.currentIndexPath == indexPath {
            ///Time to stop playing music
            var cell = self.recordingListTableView.dequeueReusableCell(withIdentifier: "Cell") as! recordingListCell
            cell = self.recordingListTableView.cellForRow(at: self.currentIndexPath) as! recordingListCell
            cell.playButton.setImage(#imageLiteral(resourceName: "start"), for: .normal)
            Manager.player?.stop()
            Manager.recordingalreadyPlayedStatus = false
            self.currentIndexPath = indexPath
            print("Stopped Playing Current Sound")
        }
        else {
            ///Time to stop playing music
            var cell = self.recordingListTableView.dequeueReusableCell(withIdentifier: "Cell") as! recordingListCell
            cell = self.recordingListTableView.cellForRow(at: self.currentIndexPath) as! recordingListCell
            cell.playButton.setImage(#imageLiteral(resourceName: "start"), for: .normal)
            Manager.player?.stop()
            Manager.recordingalreadyPlayedStatus = false

            ///Play music at new index
            self.playMusic(indexPath: indexPath)
        }
    }
    else  {
        /// NoThing was Played lets play Directly
        self.playMusic(indexPath: indexPath)
    }
    print("Starting to Play Sound")        
}

播放音频

//MARK: Play Music
    /**
     This Function get the URL of Audio and Plays it in View
     */
    func playMusic(indexPath: IndexPath)
    {
        //get cell Index Status Using CGPoint
        var cell = self.recordingListTableView.dequeueReusableCell(withIdentifier: "Cell") as! recordingListCell
        cell = self.recordingListTableView.cellForRow(at: indexPath) as! recordingListCell

        //Set Current value so we can change status if any other audio being played
        self.currentIndexPath = indexPath

        coreClassObject.initWithData(data: fileNameArray, index: indexPath.row)

        //Play music now
        let isMusicPlayed = RecordingManager.shared.playRecording(fileName: coreClassObject.audioFileName)

        //Change Button status
        if (isMusicPlayed)
        {
            //yes being played
            //time to change button Text
            cell.playButton.setImage(#imageLiteral(resourceName: "stop"), for: .normal)
        }
        else
        {
            //music is not played
            cell.playButton.setImage(#imageLiteral(resourceName: "start"), for: .normal)
        }
    }

用于检查的功能是否正在录制,否则播放音频

//MARK: Play Recording at selected Index
/**
 This function is used to check is any file being currently Played ?
 if no, Play File else return bool that another file is being already played
 - parameter fileName : File Name refer to Audio File name which is to be played
 - returns : Bool That file is Successfully played or not
 */
func playRecording(fileName:String) -> Bool {

    /// Just a bool used here to check is recording being played
    /// Used to Update timer in TableView Cell
    var recordingPlayed = Bool()

    /// Whenever we need to play an audio file we will allocate player
    /// Optional will let you compare that player is nil ?
    if Manager.recorder == nil  {
        /// Player is found nil 
        /// Thus no Audio is being Played here
        /// Yes, We can Play Sound
        recordingPlayed = true
        Manager.recordingalreadyPlayedStatus = true

        //Set player with audio File
        do {
            try Manager.player = AVAudioPlayer.init(contentsOf: returnPathAtSelectedIndex(fileName: fileName))
            //Set required delegates and Values

            Manager.player?.delegate = self
            Manager.player?.volume = 1.0
            Manager.player?.prepareToPlay()
            Manager.player?.play()
        }
        catch  {
            print("Error while playing music: \(error.localizedDescription)")
        }
    }
    else   {
        /// Player is already playing a file
        /// Can not play audio for now
        recordingPlayed = false
        Manager.recorder = nil
        Manager.recordingalreadyPlayedStatus = false
    }
    return recordingPlayed
}