我正在从服务器下载艺术品,标题和音频数据文件,并能够在表格单元格中显示。
单击表格单元格中的播放按钮,将音频数据保存到本地文件,然后尝试从文档文件路径播放。 AVAudioPlayer没有播放音频并收到错误。
搜索了很多但到目前为止还没有找到解决方案。您能否请更正我的代码并帮助解决此问题。以下是我的代码。
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)"
}
}
}
}
答案 0 :(得分:4)
请尝试此代码。
/
答案 1 :(得分:-1)
我的例子。我写了很长时间,所以代码很糟糕,但它有效。
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
}
}