加载 AVPlayer 时出现错误 Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) [英] Getting error Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) when loading AVPlayer

查看:37
本文介绍了加载 AVPlayer 时出现错误 Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我选择一个 collectionViewCell 时,我试图加载一个 AVPlayer,这是我在 didSelectItem 中的代码:

I am trying to load an AVPlayer when I select a collectionViewCell, Here is my code in didSelectItem :

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    if let item = items?[indexPath.item] {
        showPlayer(item: item)
    }
}

func showPlayer(item: Item) {

    let playerLauncher = PlayerLauncher()
    playerLauncher.showVideoPlayer()

    let playerView = PlayerView()
    playerView.item = item
    playerView.setupPlayerView()
}

这是我的 PlayerLauncher 文件:

This is my PlayerLauncher file:

class PlayerView: UIView {

    var item: Item? {
        didSet {
            if let id = item?.itemId {
               itemId = id
            } 
        }
    }

    var itemId = String()

    override init(frame: CGRect) {
        super.init(frame: frame)

        backgroundColor = UIColor(white: 0.3, alpha: 1)
    }

    var player: AVPlayer?

    func setupPlayerView() {

        let baseurl = "http://xample.com/play.m3u?id="

        let urlString = "\(baseurl)\(itemId)"
        print(urlString)
        if let url = URL(string: urlString) {
            player = AVPlayer(url: url)

            let playerLayer = AVPlayerLayer(player: player)
            self.layer.addSublayer(playerLayer)
            playerLayer.frame = self.frame

            let audioSession = AVAudioSession.sharedInstance()
            do{
                try audioSession.setCategory(AVAudioSessionCategoryPlayback)
            } catch let err {
                print(err)
                return
            }

            player?.play()

            player?.addObserver(self, forKeyPath: "currentItem.status", options: .new, context: nil)
        }
    }
}

class PlayerLauncher: NSObject {

    func showVideoPlayer() {
        print("Showing the player...")

        if let keyWindow = UIApplication.shared.keyWindow {
            let view = UIView(frame: keyWindow.frame)
            view.backgroundColor = UIColor.white

            view.frame = CGRect(x: keyWindow.frame.width - 10, y: keyWindow.frame.height - 10, width: 10, height: 10)

            let playerFrame = CGRect(x: 0, y: 0, width: keyWindow.frame.width, height: keyWindow.frame.height)
            let playerView = PlayerView(frame: playerFrame)
            view.addSubview(playerView)

            keyWindow.addSubview(view)

            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                view.frame = keyWindow.frame
            }, completion: { (completedAnimation) in
                //later...

            })
        }
    }
}

所以每当我选择项目时,播放器开始加载,控制台打印 URL(因为我在那里添加了打印语句),这就是它打印的内容:

So whenever I select the item, the player starts loading, console prints the URL (because I've added print statement there), This is what it prints:

http://xample.com/play.m3u?id=12345
(lldb)

然后它崩溃并在 AppDelegate 中显示 Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) 错误.我该如何解决?

and then It crashes and shows Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) error in AppDelegate. How can I fix it?

谢谢.

更新:

我稍微改变了 didSelectItem 函数.代码如下:

I changed the didSelectItem func a bit. Here is the code:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    if let item = items?[indexPath.item] {
        showPlayer(item: item)
    }
}

func showPlayer(item: Item) {
    let playerLauncher = PlayerLauncher()
    playerLauncher.showPlayer(item: item)
}

我将 PlayerView 中的 init 方法更改为:

I changed the init method in PlayerView to this:

var item: Item? {
    didSet {
        if let id = item?.itemId {
            itemId = id
        }
    }
}

init(frame: CGRect, item: Item) {
    super.init(frame: frame)
    self.item = item

    setupPlayerView()
    setupContainerView()
    backgroundColor = UIColor(white: 0.3, alpha: 1)
}

以及PlayerLauncher中所需的更改:

let playerView = PlayerView(frame: playerFrame, item: item)
view.addSubview(playerView)

我在 let playerView 行上打了个断,我可以看到从那里传递的项目 Id.但它没有传递给 PlayerView 类中的 urlString.因此,ID 仍然是 " ".

I put a break on let playerView line and I can see the item Id passed there. But it is not getting passed to the urlString in PlayerView class. Hence, ID is still " ".

推荐答案

我制作了一份指南,希望能说明您的误解.

I've made a guide that hopefully shows what you've been misunderstanding.

我向其他读者道歉,因为没有使用 MARKDOWN 文本格式,但请将此视为我对原始海报的最高尝试.我们在上一篇文章中已经进行了充分的讨论.

I apologize to other readers for not using MARKDOWN text format, but please do consider this as my upmost attempt for the original poster. We've already went through sufficient discussions in the previous post.

那么,你如何解决这个问题?我想直接给你代码也没什么好处,请根据这些信息尝试修复代码.

So, how do you fix this? I guess there's nothing good to give you codes directly, please try to fix the code based on this information.

如果您有更多问题,我会尽力帮助您:)

And if you have more questions, I'll try my best to help you :)

这篇关于加载 AVPlayer 时出现错误 Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆