4

Ich habe einen einfachen Android Media Player, der mehrere Videos gleichzeitig auf einem einzigen Bildschirm wiedergeben kann. Im Grunde ist ein einzelner Media-Player-Bildschirm in 4 Teile unterteilt, wobei 4 mediaPlayer Instanzen miteinander verklebt sind und jeder Teil ein bestimmtes Video abspielt.Meine Android MediaPlayer Synchronisationsprobleme

Es funktioniert fast in Ordnung, wenn meine Videodateien lokal auf dem Gerät gespeichert sind. Es gibt Synchronisationsprobleme, aber geringfügige. Aber wenn ich eine URL für HTTP-Streaming eingib, gibt es erhebliche Synchronisationsprobleme. Was ist das Problem? Im Allgemeinen, wie kann ich die Synchronisierungsprobleme entfernen?

Das einzige, was ich tun konnte, war die Instantiierung der Mediaplayer und prepare() sie nacheinander, dann rufen Sie start() nacheinander, so dass zumindest die Startzeiten nahe beieinander liegen. Es hat jedoch nicht viel Wirkung.

Hier habe ich eine Methode, die jeder der mediaplayer Instanzen zurück:

MediaPlayer mediaPreparation(String filename, boolean setMute) { 
    String url = "myURL"; // your URL here 
    // create mediaplayer instance 
    MediaPlayer mediaPlayer = new MediaPlayer(); 
    if (setMute) { 
     mediaPlayer.setVolume(0, 0); 
    } 
    try { 

     mediaPlayer.setDataSource(url); 
     mediaPlayer.prepare(); 

    } catch (IOException e) { 
    } 

    mediaPlayer.setLooping(true); 
    // mediaPlayer.start(); 
    return mediaPlayer; 
} 

Und dann eines beginne ich sie nach dem anderen:

mp[0].start(); 
mp[1].start(); 
mp[2].start(); 
mp[3].start(); 

enter image description here

+0

Tina J, hast du es geschafft, mit diesem Problem umzugehen? Ich habe das gleiche Problem und ich frage mich, ob es eine Lösung dafür gibt. – Mohru

Antwort

1

Ich bin nicht sicher wenn ein Android Media Player diese Funktionalität bietet.

Ich vermute, dass es auch Geräteabhängigkeiten gibt, da verschiedene Geräte unterschiedliche Fähigkeiten in der HW haben können, um mehrere Videos zu dekodieren und abzuspielen, und wenn einige Ihrer Videos SW-Dekodierung verwenden müssen, werden sie viel langsamer sein.

Es entspricht möglicherweise nicht Ihren Anforderungen, aber eine gängige Methode, ein solches Video auf einem Endgerät bereitzustellen, besteht darin, die Videos auf der Serverseite zusammenzuführen und als einzigen Videostream an das Gerät zu senden.

aktualisiert

Eine andere Sache bewusst sein, wenn MediaCodec verwenden und den HW-Codecs nutzen - wenn die Videos verschiedene Videoprofile haben diese auch unterschiedliche Dekodierungs Latenz verursachen können.

Dies hat damit zu tun, wie die Videos codiert sind - in einfachen Worten, wenn ein bestimmter Frame auf Informationen aus einem nachfolgenden Frame verweist (ein üblicher Komprimierungsansatz), muss der Decoder den Frame puffern, bis er den referiert, um auch zu rahmen. Einfachere Komprimierungsansätze für die Verwendung des Baseline-Profils verwenden diese Technik nicht, müssen also nicht puffern und haben daher möglicherweise eine geringere Latenz. Dies scheint auch für verschiedene HW-Anbieter anders zu sein - siehe diese Notiz von Intel, insbesondere die Low-Latency-Abschnitt am Ende:

Ich vermute, dass der beste Ansatz zu diesem besonderen Aspekt ist Ziel ist es, auf den kleinsten gemeinsamen Dominator zu zielen - verwenden Sie entweder nur das Baseline-Profil oder versuchen Sie, die gesamte Videoanzeige um einen Faktor zu verzögern, der länger ist als die maximale Latenz, die Sie von einem einzelnen Video erwarten können.

+0

Es ist bereits implementiert. Die Frage ist, wie man die Synchronisation verbessern kann ... –

+0

Danke für das nützliche Update. Tatsächlich verwenden alle meine Videos das exakt gleiche Profil und haben tatsächlich die gleiche Größe und Auflösung. –

1

In Streaming Cases besteht immer die Gefahr, dass Daten nicht ständig verfügbar sind. Daher puffern Spieler einige Frames, bevor sie mit der Wiedergabe beginnen. Und in diesem Fall benötigen mehrere Streams möglicherweise andere Zeit, um für eine ausreichende Menge gepuffert zu werden. Ich sehe einen Weg, wie du es versuchen kannst, Mediacodec. Siehe hierzu https://developer.android.com/reference/android/media/MediaCodec.html.

Gehen Sie insbesondere durch, releaseOutputBuffer() und seine Varianten. Sie haben mehr Kontrolle über das Rendern (ändern Sie den Zeitstempel, falls erforderlich, aber ich rate nicht, da die Wiedergabe nicht glatt ist). Sie können verfolgen, ob alle 4 Instanzen einen bestimmten zeitgestempelten Rahmen dekodiert haben oder nicht und sie dann sofort rendern.

+0

Interessanter Einblick! Wie funktioniert das URL-basierte Streaming? Beim Aufruf von 'prepare()' lädt es nur die ersten paar Sekunden runter, nicht das ganze, oder? Ich werde jetzt eine separate Frage dazu stellen ... –

+0

Also wie kann ich verfolgen, ob alle 4 Instanzen einen bestimmten zeitgestempelten Frame dekodiert haben ?! Irgendwelche Beispiele oder etwas? –

+1

Dies ist nur dekodieren. Wenn Sie den decodierten Frame erhalten, erhalten Sie einen entsprechenden Zeitstempel. Verfolgen Sie den Zeitstempel für alle 4 und wenn alle einen bestimmten Zeitstempel decodieren, werden alle gerendert. Basic decodieren und rendern ist in Android-Dokumentation, Tracking-Logik, müssen Sie schreiben. –