0

Ich habe ein Speicherleck, das ich nicht diagnostizieren kann. Ich habe mehrere Ansätze zum Erstellen eines nahtlos geloopten Videos ausprobiert - Neben AVPlayerLooper, alle Ansätze, die ich getroffen und versucht habe, erstellen einen Beobachter zu sehen AVPlayerItemDidPlayToEndTimeNotification und dann entweder auf den Anfang des Videos (im Falle von AVPlayer) oder Einfügen des Videos, das in die Video-Warteschlange geloopt werden soll (im Fall von AVQueuePlayer). Beide scheinen eine ähnliche Leistung zu haben, aber beide haben auch einen konsistenten Speicher, der mit der seekToTime-Methode (im Fall von AVPlayer) und der insertItem-Methode (im Fall von AVQueuePlayer) in Beziehung steht. Mein Endziel ist es, eine Unterklasse von SKVideoNode zu erstellen, die standardmäßig eine Schleife bildet. Unten ist mein Code für die Unterklasse:Speicherleck von SKVideoNode (nur am aktuellen Gerät)

#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 

Und hier ist, wie die Unterklasse in didMoveToView initialisiert wird:

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]; 
+0

Eine andere seltsame Sache, die ich bemerkt habe - dieser Speicherverlust zeigt sich nur auf einem Gerät - wenn auf dem Simulator ausgeführt wird, gibt es keinen Speicherverlust. –

Antwort

2

Kurze Antwort ist, werden Sie nicht, dass mit AVPlayer Arbeit bekommen können. Glaub mir, ich habe es versucht. Stattdessen ist es möglich, Seamless-Looping durchzuführen, indem die H264-Hardware zum Decodieren und erneutes Codieren jedes Videoframes als Keyframe, github link here, verwendet wird. Ich habe auch eine nahtlose Looping-Schicht gebaut, die einen vollen Alpha-Kanal unterstützt. Leistung sogar für Vollbild 1x1 Video auf und iPad oder iPad Pro ist super. Mit diesem Code tritt auch kein Speicherverlust auf.

+0

Danke für die Antwort! Ist das dein Projekt? Ich habe das Projekt heute früh heruntergeladen und angesehen - das Looping ist großartig, aber weißt du, wie man das geloopte Video in einen SKVideoNode einbindet? Der gewünschte Effekt, den ich anstrebe, ist ein Video-Hintergrund in Sprite Kit. –

+0

Die obige Schleife funktioniert gut, aber die Initialisierung eines SKVideoNode mit dem AVQueuePlayer und das Hinzufügen eines Videos zur Warteschlange verursacht eine Speicherverbindung in jeder Videoschleife. –

+0

Nein, Sie können das nicht direkt in einen SKVideoNode einbetten. Sie können jedoch ein Videobild dekodieren und dann in einen Pixelpuffer rendern und dann diesen Pixelpuffer als Textur für einen normalen SKSpriteNode-Knoten festlegen. Für eine minimale Speicherverwendung könnte man SKMutableTexture verwenden und darauf warten, dass der asynchrone Callback den Inhalt des Pixelpuffers kopiert. – MoDJ

Verwandte Themen