ios 从NavigationController中删除ViewController后,AVPlayer继续播放

ssm49v7z  于 2023-02-26  发布在  iOS
关注(0)|答案(4)|浏览(153)

所以我在我的项目中使用ARC,当我添加AVPlayerLayer时,它工作得很好,但当我从UINavigationItem弹出UIViewController时,视频继续在后台播放。有人知道你将如何处理这个问题吗?这看起来很容易,我只是忽略了。以下是我最初示例化的代码。

self.currentItem = [[AVPlayerItem alloc] initWithURL:url];

self.player = [[AVPlayer alloc]initWithPlayerItem:self.currentItem];
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:player];

self.avPlayerLayer.bounds = self.view.bounds;
self.avPlayerLayer.frame = CGRectMake(0,55, 1024, 670);

self.view.backgroundColor = [UIColor clearColor];

[self.view.layer addSublayer:avPlayerLayer];

这也是我定义属性的方式。

@property (strong) AVPlayer *player;
@property (strong) AVPlayerLayer *avPlayerLayer;
@property (strong) AVPlayerItem *currentItem;

也许这也是完全错误的。我不太清楚什么时候用(strong)和(weak)。无论如何,谢谢你的帮助。

odopli94

odopli941#

如果avPlayerLayer是唯一与avPlayer交互的类,则不需要在用于呈现它的类中使用属性来维护对它的引用(除非此类在您共享的代码之外使用它)。事实上,这可能是它无法按预期方式工作的原因。
剪辑继续播放的原因(我认为)是因为播放器没有被释放。你创建它,用类中的 strong 属性拥有它,然后它又被你交给的AVPlayerLayer类拥有。所以当AVPlayerLayer被释放时,AVPlayer失去了一个所有者。但它仍然有一个所有者(你的类),所以它不会被释放,它会继续播放。这里的解决方案是完全摆脱你拥有的 *avPlayer属性。你不需要它。创建AVPlayer并将它传递给AVPlayerLayer。这应该是所有需要的。
您还可以执行其他一些可能修复行为但不修复问题的操作,请调用:

[avPlayer pause]

在AVPlayerLayer的dealloc方法中。
回复:强与弱参考文献:强引用意味着所有权。由于ARC正在管理内存,它将执行所有的[object retaining]ing和[object release]ing,这些操作是您以前在代码中执行的,或者是您使用属性执行的,例如:

@property (retain) NSObject *iAmRetainedWhenProperyIsAssigned;

所以,现在有了ARC,我们这些普通用户在代码中或定义属性时不会使用retain(保留)或release(释放)这样的词。但我们仍然在设计软件。ARC很聪明,但还没有聪明到能够推断出我们正在定义的关系的架构含义。它仍然需要被告知一个类“拥有”对属性所引用的对象的引用。这在最基本的方面降低了我们的能力:
(strong)对ARC的含义与(retain)对ARC前的物业(拥有/保留)的含义相同
(weak)对ARC的意义是指(assign)对ARC前的财产的意义(不拥有/不保留)

nvbavucw

nvbavucw2#

也许你没有暂停。这样做,然后删除层和无效player

[player Pause];
[player removefromsuperlayer];
player = nil;
qjp7pelc

qjp7pelc3#

如果要停止加载AVPlayerItem,请使用AVQueuePlayer的removeAllItems,然后重新初始化它。

[self.avPlayer removeAllItems];
  self.avPlayer = [AVQueuePlayer playerWithURL:[NSURL URLWithString:@""]];
  self.avPlayer = nil;

这将停止加载当前项--这是我找到的完成此操作的唯一方法。

njthzxwz

njthzxwz4#

2023回答...

因为只有很古老的答案。这些天事实上:
(1)你所需要做的就是在playerLayer中将其归零:

///Unplay and return to blankness.
public func unplay() {
    playerLayer.player = nil
}

然而,正如@isaac敏锐地指出的,你几乎总是有一个变量,里面有一个玩家(让你更容易控制它)。不要忘记你当然也要把它清零。

因此,当你午餐播放器,你的代码看起来像

var handyPlayer: AVPlayer?

...
handyPlayer = AVPlayer(url: u)
playerLayer.player = handyPlayer
handyPlayer?.play()
handyPlayer? ... seek, etc etc

(2)因此,代码几乎总是:

///Unplay and return to blankness.
public func unplay() {
    playerLayer.player = nil
    handyPlayer = nil
}

没有必要暂停,释放任何东西,或其他任何东西。这就是它的全部。

相关问题