2013-05-22 173 views
15

onSurfaceTextureAvailableViewVideoShow永遠不會被調用...
我有這個視圖是拿着textureview。textureview onSurfaceTextureAvailable從來沒有調用裏面relativelayout裏面的片段

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設置這樣的:

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處於片段的XML設置。
如果我把VideoView放在片段中,那麼一切正常。
但如果它在mymediaplayer裏面的片段onSurfaceTextureAvailable從來沒有被調用過。

+1

現在工作嗎?你可以分享樣品解決方案還是示例項目? – keybee

回答

3

我有同樣的問題,奇怪的是用下面的代碼

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); 

解決它更奇怪的是,如果我只設置寬度或者,要麼dosent工作高度。

+0

但解決方案的原因是什麼?要放置一個隨機大小? – PerracoLabs

+0

我真的不知道..我正在試驗,這就是爲我制定的。 –

+2

該解決方案適用於我,但情況是由於一個更大的問題:視圖沒有正確放置。父佈局視圖(自定義ViewGroup)未在紋理視圖的父級上正確調用View.measure(...)。我只是修復了我的ViewGroup控件。 –

13

onSurfaceTextureAvailable似乎並沒有被調用,如果SurfaceTexture已經可用。你可以檢查它是否可用,並調用你的onSurfaceTextureAvailable方法如下。

textureView.setSurfaceTextureListener(this); 

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

但是如何使表面可用並且onSurfaceTextureAvailable不被調用?我看了一下TextureView源代碼,我看不出這是可能的。 – PerracoLabs

+2

如果在表面可用後調用'setSurfaceTextureListener',則不會獲得'onSurfaceTextureAvailable'回調。 –

+7

什麼是您的上下文中的「視圖」? – Danpe

7

至於我,解決問題的關鍵是,爲AndroidManifest.xml中的活動添加android:hardwareAccelerated =「true」。

只有當TextureView的hardwareAccelerated屬性開啓時,才能在Scrolling-Container(如ListView,ScrollView,ViewPager等)中使用TextureView。

The last few words in this blog mentioned that

希望它爲你工作。

+2

我的問題已通過手動調用'onSurfaceTextureAvailable'修復。我不認爲設置'hardwareAccelerated =「true」'會幫助很多新項目,因爲[目標API級別> = 14]的默認情況下啓用了硬件加速(http://developer.android.com/guide/topics/圖形/硬件accel.html)。 – VinceFior

7

在我的情況下,我最初有我的TextureView隱藏,然後加載後提取一些數據,這導致onSurfaceTextureAvailable不被調用。我猜測TextureView被認爲是可用的,它必須是可見的。我的解決方案是從一開始就讓TextureView可見。

+1

這也適用於我 –

3

您需要啓用硬件加速才能使用TextureView。如果你不這樣做,它的回調方法將不會被調用。只是p嘴,在你的活動onCreate方法:

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

它爲我工作。

-1

我遇到了同樣的問題,onSurfaceTextureAvailable從未叫過。最後我發現我的​​在setSurfaceTextureListener之前是隱形的。所以首先檢查​​的狀態。

+1

歡迎來到StackOverflow!下一次,請在評論部分 – cdomination

+0

Thx嘗試發佈像這樣的建議,我會介意的。 –

0

嘗試將mTextureView.setSurfaceTextureListener()放入onCreate()

RootCause是:onCreate() - >drawUI - >getHardwareLayer() - >callback SurfaceTextureListener。 所以要修復這個問題:setSurfaceTextureListener()在UI繪製或重繪UI之前。