Aj Ar
Aj Ar

Reputation: 21

AVAudioPlayer not working. Error Domain=NSOSStatusErrorDomain Code=1954115647 "(null)" in swift2

I am downloading artwork, title and audio data file from server and able to display in table cell.

On click of play button in table cell, saving audio data into local file and then trying to play from documents file path. Audio is not playing and getting error at AVAudioPlayer.

Searched a lot but didn't find solution so far. Could you please correct my code and help in fixing this issue. Below is my code.

class AudioViewController: UIViewController,UITableViewDataSource, UITableViewDelegate, AVAudioPlayerDelegate {

var audioPlayer: AVAudioPlayer?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let myCell:AudioTableViewCell = tableView.dequeueReusableCellWithIdentifier("audioCell", forIndexPath: indexPath) as! AudioTableViewCell

    myCell.lblAudioTitle.text = arrDictAudios[indexPath.row]["title"] as? String

    let artworkData = arrDictAudios[indexPath.row]["artwork"] as? NSData
    myCell.imgArtwork.image = UIImage(data: artworkData!)

    myCell.btnOutletPlay.tag = indexPath.row
    myCell.btnOutletPlay.addTarget(self, action: "playButtonClicked:", forControlEvents: UIControlEvents.TouchUpInside)

    return myCell
}

func playButtonClicked(sender: AnyObject) {

    let buttonRow = sender.tag
    let buttonRowNSNumber = buttonRow as NSNumber

    let audioData = arrDictAudios[buttonRow]["data"] as? NSData
    print(audioData?.length)


    let audioFileNameWithExt = NSString(format: "/%@.m4a",buttonRowNSNumber.stringValue)
    var documentsDirectory:String?

    var paths:[AnyObject] = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)

    if paths.count > 0 {

        documentsDirectory = paths[0] as? String

        let savePath = documentsDirectory! + (audioFileNameWithExt as String)

        NSFileManager.defaultManager().createFileAtPath(savePath, contents: audioData, attributes: nil)

        print("savedPath %@", savePath)
/var/mobile/Containers/Data/Application/8A6AEAAE-B144-4EB2-A70C-99520A0AD9D3/Documents/1.m4a


        do {
            audioPlayer =   try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: savePath), fileTypeHint: AVFileTypeAppleM4A)
            audioPlayer!.prepareToPlay()
            audioPlayer!.play()
        }
         catch let error as NSError{
            print(error.description)
//Error Domain=NSOSStatusErrorDomain Code=1954115647 "(null)"
        }

    }

}
}

Upvotes: 2

Views: 5638

Answers (2)

Ramkumar chintala
Ramkumar chintala

Reputation: 958

Please try this code .

func play() {

    if let data = NSData(contentsOfURL: savePath) {
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: .AllowBluetooth)
            try AVAudioSession.sharedInstance().setActive(true)
            audioPlayer =   try AVAudioPlayer(data: data, fileTypeHint: AVFileTypeAppleM4A)
            audioPlayer!.prepareToPlay()
            audioPlayer!.play()

        } catch let error as NSError {
            print("Unresolved error \(error.debugDescription)")
        }
    }
}

Upvotes: 6

Alexander Khitev
Alexander Khitev

Reputation: 6851

My example. I wrote a very long time, so the code is horrible, but it works

    class PlayMusicVC: UIViewController, AVAudioPlayerDelegate, ADBannerViewDelegate {


    // MARK: - override functions
    override func viewDidLoad() {
        super.viewDidLoad()
        self.tabBarController?.tabBar.hidden = true
        mpVolumeView()
        play()
        timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "timeForLabels", userInfo: nil, repeats: true)
        bannerView.delegate = self
        bannerView.hidden = true
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        self.tabBarController?.tabBar.hidden = true
        self.becomeFirstResponder()
        UIApplication.sharedApplication().beginReceivingRemoteControlEvents()
    }

    override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
//        timer.invalidate()
        self.resignFirstResponder()
        UIApplication.sharedApplication().endReceivingRemoteControlEvents()
    }

    override func canBecomeFirstResponder() -> Bool {
        return true
    }

    override func remoteControlReceivedWithEvent(event: UIEvent?) {
        if event!.type == UIEventType.RemoteControl {
            switch event!.subtype {
            case UIEventSubtype.RemoteControlPlay:
                play()
            case UIEventSubtype.RemoteControlPause:
                pause()
            case UIEventSubtype.RemoteControlNextTrack:
                next()
            case UIEventSubtype.RemoteControlPreviousTrack:
                previous()
            default: break
            }
        }
    }

    // MARK: - var and let
    var timer: NSTimer!
    var fileManager = NSFileManager.defaultManager()
//    var (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer = AVAudioPlayer()
    var nameSongForLabel: String!
    var artistSongForLabel: String!
    var albumSongForLabel: String!
    var dataImageForImageView: NSData!

    // data from table
    var currentIndex = Int()
    var arrayOfSongs = [String]()

    // MARK: - IBOutlet weak
    @IBOutlet weak var nameSongLabel: UILabel!
    @IBOutlet weak var imageOfArtwork: UIImageView!
    @IBOutlet weak var durationView: UIView!
    @IBOutlet weak var switchView: UIView!
    @IBOutlet weak var volumeView: UIView!
    // button
    @IBOutlet weak var playPauseButton: UIButton!
    // left and right labels
    @IBOutlet weak var leftLabelTime: UILabel!
    @IBOutlet weak var rightLabelTime: UILabel!
    @IBOutlet weak var sliderDuration: UISlider!

    // MARK: - ADBanner 
    @IBOutlet weak var bannerView: ADBannerView!

    // MARK: - IBAction func and switch functions
    @IBAction func previousTrack(sender: UIBarButtonItem) {
        previous()
    }

    var playingSong = true
    @IBAction func playTrack(sender: UIBarButtonItem) {
        if playingSong == false /* true*/ {
            play()
            playingSong = true
            controlCenter()
        } else {
            pause()
            playingSong = false
            controlCenter()
        }
    }

    @IBAction func nextTrack(sender: UIBarButtonItem) {
        next()
    }

    @IBAction func sliderD(sender: UISlider) {
        (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.currentTime = NSTimeInterval(sender.value)
        controlCenter()
    }


    func previous() {
        maximumCount = false 
//        var allDigit = arrayOfSongs.count-1
        if currentIndex > 0 {
            newIndex = currentIndex-- - 1
        }
        play()
        controlCenter()
    }

    // MARK: - data for control
    var titleSongForControl: String!
    var titleArtistForControl: String!

    var currentPause: NSTimeInterval!
    var imageForControlCenter: UIImage!
    var maximumCount = false

    func play() {
        playPauseButton.setImage(UIImage(named: "Pause32.png"), forState: UIControlState.Normal)
        var currentSong: String!
        if newIndex == nil {
            currentSong = arrayOfSongs[currentIndex]
            if currentIndex == arrayOfSongs.endIndex-1 {
                maximumCount = true
            }
        } else {
            currentSong = arrayOfSongs[newIndex]
            if newIndex == arrayOfSongs.endIndex-1 {
                maximumCount = true 
            }
            newIndex = nil 
        }

            let directoryFolder = fileManager.URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask)
            var superURL: NSURL!
            let url: NSURL = directoryFolder.first!
            superURL = url.URLByAppendingPathComponent(currentSong)
            let playerItem = AVPlayerItem(URL: superURL)
            let commonMetaData = playerItem.asset.commonMetadata 
            for item in commonMetaData {
                if item.commonKey == "title" {
                    nameSongForLabel = item.stringValue
                }
                if item.commonKey == "artist" {
                    artistSongForLabel = item.stringValue
                }
                if item.commonKey == "album" {
                    albumSongForLabel = item.stringValue
                }
                if item.commonKey == "artwork" {
                    dataImageForImageView = item.dataValue
                }
            }
            titleSongForControl = nameSongForLabel
            titleArtistForControl = artistSongForLabel
            nameSongLabel.text = "\(artistSongForLabel) - \(nameSongForLabel)"
        if dataImageForImageView != nil {
            imageOfArtwork.image = UIImage(data: dataImageForImageView)
            imageForControlCenter = UIImage(data: dataImageForImageView)
        } else {
            imageOfArtwork.image = UIImage(named: "Notes100.png")
        }
            (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer = try? AVAudioPlayer(contentsOfURL: superURL)
            do {
                try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            } catch _ {
            }
            do {
                try AVAudioSession.sharedInstance().setActive(true)
            } catch _ {
            }
        if currentPause == nil {
            (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.play()
            controlCenter()
        } else {
            (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.currentTime = currentPause
            (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.play()
            currentPause = nil
        }
    }

    func timeForLabels() {
        let timeForRightLabel: NSTimeInterval = (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.duration - (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.currentTime
        let timeForLeftLabel = (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.currentTime

        let calendar: NSCalendarUnit = [NSCalendarUnit.Minute, NSCalendarUnit.Second]
//        var time: NSTimeInterval = 0
        let dateFormatter = NSDateComponentsFormatter()
        dateFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyle.Positional
        dateFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehavior.Pad
        dateFormatter.allowedUnits = calendar
        let timeRight = dateFormatter.stringFromTimeInterval(timeForRightLabel)!
        rightLabelTime.text = "-\(timeRight)"
        let timeLeft = dateFormatter.stringFromTimeInterval(timeForLeftLabel)!
        leftLabelTime.text = timeLeft

        sliderDuration.minimumValue = 0.0
        sliderDuration.value = Float((UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.currentTime)
        sliderDuration.maximumValue = Float((UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.duration)
        // auto next sound
        if rightLabelTime.text == "-0:00" && maximumCount == false {
            next()
        }
        //
       if (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.playing == false {
            playPauseButton.setImage(UIImage(named: "Play32.png"), forState: UIControlState.Normal)
            playingSong = false
        }
    }

    func pause() {
        playPauseButton.setImage(UIImage(named: "Play32.png"), forState: UIControlState.Normal)
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        } catch _ {
        }
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch _ {
        }
        (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.pause()
        currentPause = (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.currentTime
    }

    var newIndex: Int!
    var newSong: String!
    func next() {
        let allDigit = arrayOfSongs.count-1
        if arrayOfSongs.count > 1 {
        if currentIndex < allDigit {
            if newIndex == nil {
                newIndex = currentIndex++ + 1
            } else {
                newIndex = currentIndex++
            }
            play()
            controlCenter()
        } else if currentIndex == arrayOfSongs.endIndex {
            (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.stop()
            }
        }
    }

    func controlCenter() {
        let mpPlaysCenter = MPNowPlayingInfoCenter.defaultCenter()
        mpPlaysCenter.nowPlayingInfo = [MPMediaItemPropertyArtist: titleArtistForControl, MPMediaItemPropertyTitle: titleSongForControl, MPMediaItemPropertyPlaybackDuration: (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.duration, MPMediaItemPropertyPlayCount: (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.currentTime, MPNowPlayingInfoPropertyElapsedPlaybackTime: (UIApplication.sharedApplication().delegate as! AppDelegate).mainAudioPlayer.currentTime]
    }

    // MARK: - swipe functions 

    @IBAction func leftSwipe(sender: UISwipeGestureRecognizer) {
        sender.direction = UISwipeGestureRecognizerDirection.Left
        next()
    }

    @IBAction func rightSwipe(sender: UISwipeGestureRecognizer) {
        sender.direction = UISwipeGestureRecognizerDirection.Right
        previous()
    }

    // MARK: - functions

    func mpVolumeView() {
        let mpView = MPVolumeView(frame: CGRectMake(8, 15, self.view.bounds.size.width-16, self.volumeView.bounds.size.height))
        volumeView.addSubview(mpView)
    }

    // MARK: - banner view function
    func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
        NSLog("Banner error is %@", error)
    }

    func bannerViewDidLoadAd(banner: ADBannerView!) {
        bannerView.hidden = false
    }

    func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
        return true
    }

}

Upvotes: -1

Related Questions