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永远不会被调用。
答案 0 :(得分:19)
onSurfaceTextureAvailable
已经可用,则似乎无法调用{p> 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());
}
答案 1 :(得分:14)
至于我,解决问题的关键是为AndroidManifest.xml中的活动添加android:hardwareAccelerated =“true”。
只有在具有hardwareAccelerated属性的TextureView的活动上,才能在Scrolling-Container(如ListView,ScrollView,ViewPager等)中使用TextureView。
The last few words in this blog mentioned that
希望它适合你。
答案 2 :(得分:8)
在我的情况下,我最初让我的TextureView
不可见,然后在获取一些数据后加载,这导致onSurfaceTextureAvailable
不被调用。我猜测TextureView
被称为'可用',它必须是可见的。我的解决方案是从一开始就让TextureView
可见。
答案 3 :(得分:6)
您需要启用硬件加速才能使用TextureView。如果不这样做,则不会调用其回调方法。只需在你的活动的onCreate方法中噘嘴:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
它对我有用。
答案 4 :(得分: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);
更奇怪的是,如果我只设置剂量工作的宽度或高度。
答案 5 :(得分:1)
我遇到了同样的问题,onSurfaceTextureAvailable
从未打过电话。最后,我发现我的textureview
在setSurfaceTextureListener
之前是不可见的。因此,请先检查textureview
的状态。
答案 6 :(得分:0)
尝试将mTextureView.setSurfaceTextureListener()
放入onCreate()
。
RootCause是:onCreate()
- > drawUI
- > getHardwareLayer()
- > callback SurfaceTextureListener
。
因此,要在UI绘制或重绘UI之前修复此问题:setSurfaceTextureListener()
。