24

VideoView 中的 onSurfaceTextureAvailable 永远不会被调用......
我有这个持有纹理视图的视图。

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 永远不会被调用。

4

7 回答 7

25

onSurfaceTextureAvailableSurfaceTexture如果已经可用,似乎不会被调用。您可以检查它是否可用并onSurfaceTextureAvailable如下调用您的方法。

textureView.setSurfaceTextureListener(this);

/*
 * onSurfaceTextureAvailable does not get called if it is already available.
 */
if (view.isAvailable()) {
    onSurfaceTextureAvailable(view.getSurfaceTexture(), view.getWidth(), view.getHeight());
}
于 2013-09-10T22:01:35.530 回答
18

至于我,解决问题的关键是在 AndroidManifest.xml 中为活动添加 android:hardwareAccelerated="true" 。

只有在具有 hardwareAccelerated 属性的 TextureView 的 Activity 上,您才能在 Scrolling-Container(例如 ListView、ScrollView、ViewPager 等)中使用 TextureView。

这个博客的最后几句话提到了

希望对你有效。

于 2013-11-11T03:43:35.870 回答
12

您需要启用硬件加速才能使用 TextureView。如果你不这样做,它的回调方法将不会被调用。只需在您的活动的 onCreate 方法中撅嘴:

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

它对我有用。

于 2015-03-06T09:24:53.643 回答
11

就我而言,我最初是TextureView隐形的,然后在获取一些数据后加载,这导致onSurfaceTextureAvailable不被调用。我猜要说TextureView它是“可用的”,它必须是可见的。我的解决方案是从一开始就使TextureView可见。

于 2014-10-14T00:30:32.263 回答
4

我遇到了同样的问题,onSurfaceTextureAvailable从来没有打电话。最后我发现我textureview之前是看不见的setSurfaceTextureListener。所以首先检查状态textureview

于 2016-07-13T10:59:53.123 回答
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);

更奇怪的是,如果我只设置有效的宽度或高度。

于 2013-06-03T13:21:48.067 回答
0

试着放进mTextureView.setSurfaceTextureListener()onCreate()

根本原因是:onCreate()-> drawUI-> getHardwareLayer()-> callback SurfaceTextureListener。所以要解决这个问题:setSurfaceTextureListener()在 UI 绘制或重绘 UI 之前。

于 2018-01-04T03:03:53.910 回答