2013-05-22 10 views
15

onSurfaceTextureAvailable w VideoView nigdy nie jest wywoływany ...
Mam ten widok, który trzyma teksturę.textureview onSurfaceTextureDostępny nigdy nie jest wywoływany wewnątrz relacyjnegolayout wewnątrz fragmentu

public class MyMediaPlayer extends RelativeLayout{ 

Context mContext; 
VideoView player;//this is a custom textureview that streams video 

public MyMediaPlayer(Context context) { 
    super(context); 
    mContext = context; 
    init(); 
} 
public MyMediaPlayer(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    mContext = context; 
    init(); 
} 
public MyMediaPlayer(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    mContext = context; 
    init(); 
} 
private void init() { 
    setBackgroundColor(Color.BLACK);  
    player = new VideoView(mContext); 
    LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
    addView(player,lp); 
} 
public void setURL(String url){ 
    player.setVideoPath(url); 
} 
public void start(){ 
    player.start(); 
} 

} 

VideoView jest skonfigurowany tak:

public class VideoView extends TextureView { 

public VideoView(final Context context) { 
    super(context); 
    mContext = context; 
    initVideoView(); 
} 

public VideoView(final Context context, final AttributeSet attrs) { 
    super(context, attrs); 
    mContext = context; 
    initVideoView(); 
} 

public VideoView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    mContext = context; 
    initVideoView(); 
} 

public void initVideoView() { 
    Log.d(LOG_TAG, "Initializing video view."); 
    videoHeight = 0; 
    videoWidth = 0; 
    setFocusable(false); 
    setSurfaceTextureListener(surfaceTextureListener); 
} 
SurfaceTextureListener surfaceTextureListener = new SurfaceTextureListener() { 
    @Override 
    public void onSurfaceTextureAvailable(final SurfaceTexture surface, final int width, final int height) { 
     Log.d(LOG_TAG, "Surface texture now avaialble."); 
     surfaceTexture = surface; 
     openVideo(); 
    } 

    @Override 
    public void onSurfaceTextureSizeChanged(final SurfaceTexture surface, final int width, final int height) { 
     Log.d(LOG_TAG, "Resized surface texture: " + width + '/' + height); 
     surfaceWidth = width; 
     surfaceHeight = height; 
     boolean isValidState = (targetState == STATE_PLAYING); 
     boolean hasValidSize = (videoWidth == width && videoHeight == height); 
     if (mediaPlayer != null && isValidState && hasValidSize) { 
      start(); 
     } 
    } 

    @Override 
    public boolean onSurfaceTextureDestroyed(final SurfaceTexture surface) { 
     Log.i(LOG_TAG, "Destroyed surface number " + number); 
     return false; 
    } 

    @Override 
    public void onSurfaceTextureUpdated(final SurfaceTexture surface) { 

    } 
}; 
} 

MyMediaPlayer jest ustawiony w xml fragmentu.
Jeśli umieściłbym VideoView wewnątrz fragmentu, wszystko działa poprawnie.
Ale jeśli jest on w mymediaplayer wewnątrz fragmentu na SurfaceTextureAvailable nigdy nie jest wywoływany.

+1

czy to działa? czy możesz udostępnić przykładowe rozwiązanie lub przykładowy projekt? – keybee

Odpowiedz

3

miałem ten sam problem, dziwnie rozwiązany go z następującym kodem

videoPreview = (TextureView) linearLayout.findViewById(R.id.videoView); 
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)videoPreview.getLayoutParams(); 
params.height = 130; 
params.width = 508; 
videoPreview.setLayoutParams(params); 
videoPreview.setSurfaceTextureListener(this); 

Więcej dziwnie gdybym ustawić tylko szerokość lub wysokość, że doza pracy albo.

+0

Ale jaki jest powód rozwiązania? Aby umieścić losowy rozmiar? – PerracoLabs

+0

Naprawdę nie wiem .. eksperymentowałem i to mi się udało. –

+2

To rozwiązanie sprawdziło się, ale sytuacja była spowodowana większym problemem: widok nie układał się prawidłowo. Widok układu nadrzędnego (niestandardowa grupa ViewGroup) nie wywoływał poprawnie obiektu View.measure (...) w oknie nadrzędnym widoku tekstury. Po prostu musiałem naprawić moją kontrolkę ViewGroup. –

13

onSurfaceTextureAvailable nie wydaje się być wywoływana, jeśli SurfaceTexture jest już dostępna. Możesz sprawdzić, czy jest on dostępny i zadzwonić na swoją metodę onSurfaceTextureAvailable jak poniżej.

textureView.setSurfaceTextureListener(this); 

/* 
* onSurfaceTextureAvailable does not get called if it is already available. 
*/ 
if (view.isAvailable()) { 
    onSurfaceTextureAvailable(view.getSurfaceTexture(), view.getWidth(), view.getHeight()); 
} 
+0

Ale w jaki sposób powierzchnia może być dostępna i czy nie jest wywoływana opcja Powierzchnia Zasobowa niedostępna? Zajrzałem do kodu źródłowego TextureView i nie widzę, żeby było to możliwe. – PerracoLabs

+2

Jeśli wywołasz metodę 'setSurfaceTextureListener' po uzyskaniu powierzchni, nie otrzymasz wywołania zwrotnego' onSurfaceTextureAvailable'. –

+7

co to jest "widok" w twoim kontekście? – Danpe

7

Jak dla mnie kluczem do rozwiązania problemu jest to, że dodać android: hardwareAccelerated = „true” dla działalności w AndroidManifest.xml.

Możesz użyć TextureView w kontenerze przewijania (takim jak ListView, ScrollView, ViewPager itp.) Tylko wtedy, gdy działanie dla TextureView z włączoną właściwością HardwareAccelerated.

The last few words in this blog mentioned that

Nadzieję, że pracuje dla Ciebie.

+2

Mój problem został rozwiązany przez ręczne wywołanie 'onSurfaceTextureAvailable'. Nie sądzę, że ustawienie 'hardwareAccelerated =" true "' pomoże wielu nowym projektom, ponieważ akceleracja sprzętowa jest domyślnie włączona dla [Target API level> = 14] (http://developer.android.com/guide/topics/ graphics/hardware-accel.html). – VinceFior

7

W moim przypadku początkowo mój TextureView był niewidoczny, a następnie załadowany po pobraniu niektórych danych, co spowodowało, że nie można było wywołać onSurfaceTextureAvailable. Zgaduję, że aby TextureView było "dostępne", musi być widoczne. Moim rozwiązaniem było sprawienie, by TextureView było widoczne od samego początku.

+1

to działało również dla mnie –

3

Musisz włączyć przyspieszanie sprzętowe, aby korzystać z TextureView. Jeśli nie, jego metody wywołania zwrotnego nie będą wywoływane. Po prostu dbaj o to w swojej aktywnej metodzie onCreate:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); 

To zadziałało dla mnie.

-1

Spotkałem ten sam problem, onSurfaceTextureAvailable nigdy nie dzwoniłem. W końcu znalazłem, że mój textureview jest niewidoczny przed setSurfaceTextureListener. Najpierw sprawdź stan textureview.

+1

Witamy w StackOverflow! Następnym razem spróbuj opublikować poradę w ten sposób w komentarzach sekcji – cdomination

+0

Thx, będę to pamiętać. –

0

spróbuj umieścić mTextureView.setSurfaceTextureListener() w onCreate().

RootCo to: onCreate() ->drawUI ->getHardwareLayer() ->callback SurfaceTextureListener. Aby naprawić ten problem: setSurfaceTextureListener() przed rysowaniem interfejsu użytkownika lub przerysowaniem interfejsu użytkownika.

Powiązane problemy