Richtiger Weg, schnell zwischen Videos zu wechseln

8

Ich erstelle eine Anwendung, die ein bestimmtes Video auf der Grundlage eines externen Ereignisses anzeigt, wodurch sich das abspielende Video schnell ändern kann - einmal pro Sekunde oder mehr. Es darf jedoch keine Lücke oder Verzögerung zwischen den Videos geben.

Was ist der beste Weg, dies zu tun? Es gibt nur vier Videos mit jeweils etwa zwei Megabyte.

Ich habe erwogen, vier MPMoviePlayerControllers zu erstellen und ihre Ansichten zur Hauptansicht hinzuzufügen, aber ausgeblendet, indem Sie das aktuelle Video pausieren und ausblenden und dann das nächste Video einblenden und abspielen. Gibt es eine elegantere Lösung?

Bearbeiten

Hier finden Sie weitere Informationen zu meiner genauen Situation:

  • Die verschiedenen Videoframes teilen sich meist gemeinsame Pixel. Es ist also in Ordnung, wenn ein Bild während des Wechsels kleben bleibt, aber OK, damit schwarze Bilder erscheinen.
  • Jedes Video ist nur etwa zehn Sekunden lang und es gibt nur vier Videos. Die allgemeinen Zustandsübergänge sind 1 - 2 - 3 - 4 - 1.
  • Die Videowiedergabe sollte mit gleichzeitiger AVAudioRecorder-Aufnahme kompatibel sein. Soweit ich das beurteilen kann, ist MPMoviePlayerController nicht.
Tim 07.03.2012, 20:04
quelle

2 Antworten

2

Der MPMoviePlayerController ist ein Singleton. Vier Instanzen teilen denselben Zeiger, dieselbe Ansicht usw. Mit dem nativen Player haben Sie, glaube ich, nur zwei Alternativen: Die eine ist, die contentURL-Eigenschaft zu ändern, wenn Sie einen Übergang wünschen. Wenn die Latenz auf diese Weise inakzeptabel ist, besteht die andere Alternative darin, ein längeres Video mit den verkürzten kürzeren Clips zu erzeugen. Sie können sehr schnelle Sprünge innerhalb des einzelnen, längeren Clips erstellen, indem Sie currentPlaybackTime einstellen.

    
danh 13.03.2012, 16:14
quelle
8

Sie müssen alle Video-Streams einrichten und vorpuffern, um Schluckauf zu vermeiden, deshalb glaube ich nicht, dass Ihre MPMoviePlayerController-Lösung zu weit entfernt ist.

Diese spezifische Lösung ist jedoch möglicherweise problematisch, da jeder Movie-Player über eine eigene Benutzeroberfläche verfügt. Die UIs werden nicht miteinander synchronisiert, daher kann einer die Steuerleiste anzeigen, ein anderer nicht; man könnte sich im Vollbildmodus befinden usw. Das Umschalten zwischen ihnen führt zu visuellen Diskontinuitäten.

Da es sich anhört, dass Ihre Videoumschaltung nicht unbedingt vom Benutzer initiiert wird, schätze ich, dass Ihnen die Benutzeroberfläche des Standard-Video-Players nicht so wichtig ist.

Ich würde vorschlagen, auf die darunterliegende Ebene, AV Foundation, zu wechseln. Theoretisch können Sie einfach ein AVPlayerItem für jedes Video erstellen. Dies ist ein Stream-Management-Objekt ohne UI-Overhead, also ist es perfekt für das, was Sie tun. Sie könnten dann - wiederum theoretisch - einen AVPlayer und einen AVPlayerLayer für die Anzeige erstellen. Wenn Sie von einem AVPlayerItem-Stream zu einem anderen wechseln möchten, können Sie die replaceCurrentItemWithPlayerItem: -Nachricht des AVPlayers aufrufen, um den Datenstrom auszutauschen.

Ich habe ein kleines Testprojekt (GitHub) gemacht, um dies zu überprüfen, und leider ist die einfache Lösung nicht ganz perfekt. Es gibt keinen Videofluss, aber beim Übergang vom AVPlayer zum AVPlayer scheint die Präsentationsschicht den zuletzt gesehenen Frame des vorherigen Films in der Größe, die für den nächsten Film geeignet ist, kurz zu blinken. Es scheint hilfreich zu sein, separate AVPlayer-Objekte für jeden Film zuzuweisen und zwischen ihnen zu einer konstanten Player-Ebene zu wechseln. Es scheint immer noch einen blitzartigen Hintergrund zu geben, aber zumindest ist es ein subtiler Defekt. Hier ist der Kern des Codes:

%Vor%

Der halbe Code ist nur dazu da, um den Zustand der Spieler zu beobachten und sicherzustellen, dass die Wiedergabe erst startet, wenn alle Videos gepuffert sind.

Das Zuweisen von drei separaten AVPlayerLayern (zusätzlich zu drei AVPlayern) verhindert jegliche Art von Flash. Leider scheint ein AVPlayer, der mit einem nicht angezeigten AVPlayerLayer verbunden ist, anzunehmen, dass er keinen Videopuffer aufrechterhalten muss. Jeder Wechsel zwischen den Schichten erzeugt dann ein vorübergehendes Video-Stottern. Das ist also nicht gut.

Bei der Verwendung von AV Foundation sind einige Dinge zu beachten:

1) Das AVPlayer-Objekt bietet keine integrierte Unterstützung für die Wiedergabe in einer Schleife. Sie müssen für das Ende des aktuellen Videos beobachten und manuell bis zum Zeitpunkt Null suchen.

2) Außer dem Videorahmen gibt es keine andere Benutzeroberfläche, aber ich vermute, dass dies für Sie von Vorteil sein könnte.

    
GSnyder 10.03.2012 06:29
quelle