循环SKVideoNode导致内存泄漏(仅限实际设备)

时间:2016-11-16 16:14:10

标签: objective-c memory-leaks avplayer avqueueplayer skvideonode

我有一个无法诊断的内存泄漏。我已经尝试了多种方法来创建无缝循环视频 - 除了AVPlayerLooper之外,我遇到并尝试过的所有方法都涉及创建一个观察者来观察AVPlayerItemDidPlayToEndTimeNotification,然后寻找视频的开头(在这种情况下) AVPlayer)或将要循环的视频插入视频队列(在AVQueuePlayer的情况下)。两者似乎都具有相似的性能,但两者都有一致的内存保持与seekToTime方法(在AVPlayer的情况下)和insertItem方法(在AVQueuePlayer的情况下)相关。我的最终目标是创建一个默认循环的SKVideoNode子类。下面是我的子类代码:

#import "SDLoopingVideoNode.h"
#import <AVFoundation/AVFoundation.h>


@interface SDLoopingVideoNode()
@property AVQueuePlayer *avQueuePlayer;
@property AVPlayerLooper *playerLooper;
@end

@implementation SDLoopingVideoNode

-(instancetype)initWithPathToResource:(NSString *)path withFiletype:(NSString *)filetype
{
if(self == [super init])
{
    NSString *resourcePath = [[NSBundle mainBundle] pathForResource:path ofType:filetype];
    NSURL *videoURL = [NSURL fileURLWithPath:resourcePath];
    AVAsset *videoAsset = [AVAsset assetWithURL:videoURL];
    AVPlayerItem * videoItem  = [AVPlayerItem playerItemWithAsset:videoAsset];


    self.avQueuePlayer = [[AVQueuePlayer alloc] initWithItems:@[videoItem]];

    NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter];
    [noteCenter addObserverForName:AVPlayerItemDidPlayToEndTimeNotification
                            object:nil
                             queue:nil
                        usingBlock:^(NSNotification *note) {
                            AVPlayerItem *video = [[AVPlayerItem alloc] initWithURL:videoURL];
                            [self.avQueuePlayer insertItem:video afterItem:nil];
                            NSLog(@"Video changed");
                        }];

    self = (SDLoopingVideoNode*)[[SKVideoNode alloc] initWithAVPlayer: self.avQueuePlayer];
    return self;
}
return nil;
}


@end

以下是在didMoveToView中初始化子类的方法:

SDLoopingVideoNode *videoNode = [[SDLoopingVideoNode alloc]initWithPathToResource:@"147406" withFiletype:@"mp4"];
[videoNode setSize:CGSizeMake(self.size.width, self.size.height)];
[videoNode setAnchorPoint:CGPointMake(0.5, 0.5)];
[videoNode setPosition:CGPointMake(0, 0)];
[self addChild:videoNode];
[videoNode play];

1 个答案:

答案 0 :(得分:2)

简短的回答是,你将无法使用AVPlayer。相信我,我试过了。相反,可以通过使用H264硬件解码然后将每个视频帧重新编码为关键帧github link here来进行无缝循环。我还构建了一个支持完整alpha通道的无缝循环层。即使是全屏1x1视频和iPad或iPad专业版的性能也很棒。此外,此代码没有内存泄漏。