2013-04-02 15 views
21

Używam komponentu VideoView do odtwarzania wideo. Nie mogę wyczyścić ekranu VideoView po ręcznym wywołaniu funkcji stopPlayback(). Chciałbym zresetować VideoView, aby oryginalne tło było widoczne.Wyraźny wyświetlacz Android VideoView po stopPlayback()

  1. Odtwórz wideo w komponencie VideoView.
  2. Wybierz nowy film do odtworzenia.
  3. VideoView zatrzymuje się na ostatniej klatce pierwszego filmu, dopóki nie rozpocznie się następne wideo. Jeśli wystąpi błąd w następnym filmie, statyczny obraz z pierwszego filmu pozostaje w tym miejscu.
  4. Jeśli pozwolę, aby odtwarzanie wideo zakończyło się, ekran zostanie wyczyszczony.

Kod używam:

private VideoView videoViewer = null; 

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
... 
    if (videoViewer != null) { 
    videoViewer.setOnPreparedListener(new OnPreparedListener()); 
    } 
... 
} 

public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
    if (videoViewer != null) { 
    videoViewer.stopPlayback(); 
    videoViewer.setVideoURI(Uri.parse("http://my_vido_url/playlist.m3u8")); 
    } 
} 

private class OnPreparedListener implements MediaPlayer.OnPreparedListener { 
    @Override 
    public void onPrepared(MediaPlayer mp) { 
    videoViewer.start(); 
    } 
} 

Należy zauważyć, że na podstawie źródła VideoView.java, stopPlayback() wykonuje następujące działania na podstawowej MediaPlayer:

public void stopPlayback() { 
    if (mMediaPlayer != null) { 
    mMediaPlayer.stop(); 
    mMediaPlayer.release(); 
    mMediaPlayer = null; 
    } 
} 

Odpowiedz

9

The Rozwiązanie, na które się zdecydowałem, chyba że ktoś może zaoferować coś lepszego, to użyć setBackgroundResource, który wydaje się dziwnie nazwany, ponieważ wydaje się, że zmienia zasób pierwszego planu.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
... 
    videoViewer.setBackgroundResource(R.drawable.viewer_background); 
... 
} 

public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
    if (videoViewer != null) { 
    videoViewer.stopPlayback(); 
    // Set the background back to the drawable resource to clear the current video when switching to a new one. 
    videoViewer.setBackgroundResource(R.drawable.viewer_background); 
    videoViewer.setVideoURI(Uri.parse("http://my_vido_url/playlist.m3u8")); 
    } 
} 

private class OnPreparedListener implements MediaPlayer.OnPreparedListener { 
    @Override 
    public void onPrepared(MediaPlayer mp) { 
    videoViewer.start(); 
    // Clear the background resource when the video is prepared to play. 
    videoViewer.setBackgroundResource(0); 
    } 
} 

odkształcalne ja przedstawieniu jest prosty layer-list z niestandardowych niebieskim tle i logo środku obrazu.

odkształcalne \ viewer_background.xml:

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 
    <item> 
    <shape android:shape="rectangle"> 
     <solid android:color="@color/custom_blue" /> 
    </shape> 
    </item> 
    <item> 
    <bitmap android:src="@drawable/img_logo" 
     android:gravity="center" /> 
    </item> 
</layer-list> 

Alternatywnie Byłem również w stanie wykorzystać setZOrderOnTop kontrolować gdzie widok powierzchni jest umieszczona (można również zdefiniować inny pogląd na górze VideoViewer i przełączyć widoczność że sposób):

videoViewer.setZOrderOnTop(false); 
videoViewer.setZOrderOnTop(true); 

Ewentualnie mogę też użyć setBackgoundColor aby osiągnąć to samo jak setBackgroundResource:

videoViewer.setBackgroundColor(getResources().getColor(R.color.custom_blue)); 
videoViewer.setBackgroundColor(Color.TRANSPARENT); 
+0

Kiedy Robię to, kolejne odtwarzanie nadal pokazuje ostatnią klatkę poprzedniej. Jakieś pomysły, dlaczego tak się dzieje? – slhck

+0

Rzeczywista klatka wideo jest rysowana na powierzchni "pod" VideoView. Ustawienie tła w VideoView spowoduje ukrycie ramki, ale jej nie skasuje.Po wyczyszczeniu tła stara ramka nadal tam jest. – William

12

Dla mnie to, co działało, było po prostu ukryć, a następnie pokazać VideoView przy użyciu setVisibility.

public void clearCurrentFrame() { 
    videoView.setVisibility(GONE); 
    videoView.setVisibility(VISIBLE); 
} 

to było dlatego, że chciał VideoView stać się przejrzysty, a nie być w jednolitym kolorze. Ustawienie tła na przezroczyste nie działa - ramka wideo nadal się wyświetla.

+0

Właśnie otrzymałem sugerowaną zmianę od anonimowego użytkownika, mówiącego, żeby umieścić 'videoView.stopPlayback();' jako ostatnią linię kodu. Nie mogę zweryfikować, czy jest to konieczne, chociaż wideo musi już zostać zatrzymane, aby moja odpowiedź zadziałała. Chciałem go zostawić tutaj, na wypadek gdyby to pomogło komuś :) – William

1

Cóż, dla mnie żadne z rozwiązań z tego wątku pracował, więc próbowałem coś innego, a poniżej jest rozwiązanie, że pracował dla mnie,

new Handler().postDelayed(new Runnable() { 

    @Override 
    public void run() { 
     mVideoViewPlayList.setVisibility(View.GONE); 
     mVideoViewPlayList.setVisibility(View.VISIBLE); 
     mVideoViewPlayList.setVideoURI(Uri.parse(path)); 
    } 
}, 500); 
+0

Bez obrazy. Naprawdę zastanawiam się, jaki jest cel tych linii. mVideoViewPlayList.setVisibility (View.GONE); mVideoViewPlayList.setVisibility (View.VISIBLE); –

+2

@PsyCoder w niektórych urządzeniach, mVideoViewPlayList.setVideoURI (Uri.parse (path)) nie działało, dopóki zmiana widoczności nie zmieni się co najmniej raz! –

+0

Dziękuję za wyjaśnienie. To może pewnego dnia uratować mój czas :) –

0

właśnie ten kod:

videoView.setVideoURI(null); 
+0

Proszę dodać więcej szczegółów do swojej odpowiedzi! –

+2

java.lang.NullPointerException: uriString to kreuje moją aplikację, gdy ustawię wartość NULL. –

+0

Działa dla mnie dzięki –

Powiązane problemy