使用AVAudioPlayer时出现OSStatus错误2003334207

14

我正在尝试在按下按钮时播放MP3文件(在VLC / iTunes中播放正常)。 这是我的代码:

     var audioPlayer: AVAudioPlayer!
     @IBAction func playEpisode(sender: AnyObject) {
    println("now playing")
    let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
    let data: CDEpisode = fetchedResultsController.objectAtIndexPath(indexPath!) as! CDEpisode
    var err: NSError?
    let url = NSURL(string: data.localPath)
    println("The url is \(url)")

    audioPlayer = AVAudioPlayer(contentsOfURL: url, error: &err)
    if audioPlayer == nil {
        if let e = err {
            println(e.localizedDescription)
        }
    }
    audioPlayer.delegate = self
    audioPlayer.prepareToPlay()
    audioPlayer.play()
}

这里是日志记录:

now playing
The url is Optional(file:///var/mobile/Containers/Data/Application/4747A71E-A63F-4EFC-B2DF-8B361361080B/Documents/serial-s01-e12.mp3)
The operation couldn’t be completed. (OSStatus error 2003334207.)
fatal error: unexpectedly found nil while unwrapping an Optional value

audioPlayer.delegate = self时会发生EXC_BREAKPOINT错误。

其他StackoOverflow上的线程没有帮助。有什么想法吗? 谢谢

编辑:我尝试将localURL传递给contentsOfURL(而不是CDEpisode对象),但仍然失败。


我查了一下错误代码,2003334207 的 localizedDescription 是 "操作无法完成"。在我的应用程序中,我试图访问一个不存在的文件。 - Unome
7个回答

9

这可能是因为尝试加载一个不存在的文件造成的。如果添加调用url.checkResourceIsReachable(),将会记录更详细的信息以帮助解决问题。

示例代码:

    do {
        let url = URL(fileURLWithPath: dbObject.path)
        let isReachable = try url.checkResourceIsReachable()
        // ... you can set breaking points after that line, and if you stopped at them it means file exist.
    } catch let e {
        print("couldnt load file \(e.localizedDescription)")
    }

6

看起来你正在尝试解包一个空值的变量。为了防止这种情况发生,你应该使用安全解包技术。

if let data: CDEpisode = fetchedResultsController.objectAtIndexPath(indexPath!) as! CDEpisode
{
    var err: NSError?
    let url = NSURL(string: data.localPath)
    println("The url is \(url)")

    //rest of code
}

你仍然需要弄清楚为什么它返回了nil,但这是一种更安全的方法来解包变量并防止崩溃,因为需要更多上下文才能解决这个问题。
有些需要考虑的问题:
- 你确定fetchedResultsController是否返回任何对象吗? - 你确定它是CDEpisode类型吗?

谢谢,你是对的。应用程序仍然抛出相同的错误。fetchedResultsController返回了正确的CDEpisode类型对象。 - user2747220
我的CoreData数据库中出现了一个错误,现在已经修复了。谢谢你和@dan。 - user2747220

6

试试这个

var player: AVAudioPlayer = AVAudioPlayer()


@IBAction func playX(_ sender: Any) {
    let urlstring = "https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3"
    let url = URL(string: urlstring)
    let data = try! Data(contentsOf: url!)
    player = try! AVAudioPlayer(data: data)
    player.prepareToPlay()
    player.volume = 1.0
    player.play()
}

4

您正在检查 audioPlayer 是否为 nil,但随后您将其用作如果它并不是。您可能想要像这样的内容:

if audioPlayer == nil {
    if let e = err {
        println(e.localizedDescription)
    }
} else {
    audioPlayer.delegate = self
    audioPlayer.prepareToPlay()
    audioPlayer.play()
}

除了打印出错误信息之外,还需要采取一些实际措施来处理错误情况。


你说得完全正确。这只是临时代码,不是最终版本。我已经添加了一个else语句,它不再使应用程序崩溃,但仍然会抛出相同的错误。 - user2747220

0

在我的情况下,我遇到了同样的问题,并且我发现在开始录制之前需要进行这个设置。

try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)

希望能对任何人有所帮助


0
我也遇到了这个问题,在检查音频文件的URL后,发现它存储在缓存目录中。因此,音频播放器可能无法根据您的“url”找到音频文件。
请确保URL路径位于文档目录下。

0
如其他人所说,音频播放器无法找到文件。
这对我有帮助:重新构建应用程序时文档目录路径更改 基本上,您无法使用绝对引用加载文件,因为沙箱环境每次重新生成绝对文件URL。 所以,您需要添加一小段代码(见上文)以获取正确的要使用的URL。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接