Textureview onSurfaceTextureAvailable никогда не вызывается внутри relativelayout внутри фрагмента

onSurfaceTextureAvailable в VideoView никогда не называется...
У меня есть это представление, которое удерживает текстуру.

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

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

Ответ 2

Что касается меня, ключом к решению проблемы является то, что add android: hardwareAccelerated = "true" для активности в AndroidManifest.xml.

Вы можете использовать TextureView в прокручиваемом контейнере (например, ListView, ScrollView, ViewPager и т.д.), только если для объекта TextureView с включенным аппаратным ограничением есть активность.

Последние несколько слов в этом блоге упомянули, что

Надеюсь, что это сработает для вас.

Ответ 3

В моем случае я изначально имел TextureView невидимый, а затем загружался после извлечения некоторых данных, и это вызывало onSurfaceTextureAvailable. Я предполагаю, что для TextureView, который должен быть "доступен", он должен быть видимым. Мое решение состояло в том, чтобы просто сделать TextureView видимым с самого начала.

Ответ 4

У меня была та же проблема, странно разрешила ее с помощью следующего кода

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

Более странно, если я устанавливаю только ширину или высоту, которую работает дозатор.

Ответ 5

Вам нужно включить аппаратное ускорение для использования TextureView. Если вы этого не сделаете, методы обратного вызова не будут вызваны. Просто надуть, что в вашей деятельности onCreate метод:

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

Это сработало для меня.

Ответ 6

попробуйте поставить mTextureView.setSurfaceTextureListener() в onCreate().

RootCause таков: onCreate()drawUIgetHardwareLayer()callback SurfaceTextureListener. Поэтому, чтобы исправить эту проблему: setSurfaceTextureListener() до того, как пользовательский интерфейс нарисует или перерисует пользовательский интерфейс.

Ответ 7

Я встретил ту же проблему, onSurfaceTextureAvailable никогда не вызывал. Наконец, я обнаружил, что мой textureview невидим до setSurfaceTextureListener. Поэтому сначала проверьте статус textureview.