我这里简单总结下:
1.TextureView主要用来绘制流内容(比如视频,openGl场景)。
2.TextureView和surfaceView很相似,但是surfaceView是重新创建新窗口,这种方式效率高,但是不支持变化(旋转缩放等)操作,也很难再listview中使用,所以TextureView就弥补了这个缺点。
3.TextureView仅支持硬件加速,是通过GPU来绘制图形的。
TextureView简单用法
实现surfaceTextureListener,通过该接口的方法获得surfaceTexture。
surfaceTexture是用来捕获来至camera或video的图像流,如果获取不到surfaceTexture,那么TextureView就显示不了任何内容
接下来结合MediaPlayer我们来实现短视频控件
以前用surfaceView来播放视频的时候可以获得surfaceHolder对象,然后通过setDisplay方法就可以为mediaplayer指定显示的surfaceview。
但是textureview有点不同,他返回的是SurfaceTexture,这里我们需要先将SurfaceTexture转为Surface,然后通过setSurface方法为Mediaplayer指定显示的TextureView
VideoTextureView的代码:
public class VideoTextureView extends TextureView implements TextureView.SurfaceTextureListener {
private MediaPlayer mediaPlayer;
private Surface surface;
private ImageView ivTip;
private boolean isPlaying = false;
private boolean isSurfaceTextureAvailable = false;
private String videoPath;
public VideoTextureView(Context context) {
super(context);
init(context);
}
public VideoTextureView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public VideoTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
setSurfaceTextureListener(this);
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
surface = new Surface(surfaceTexture);
isSurfaceTextureAvailable = true;
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
surface=null;
onVideoTextureViewDestroy();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
public void startMediaPlayer(){
if(isPlaying || !isSurfaceTextureAvailable)
return;
if(TextUtils.isEmpty(videoPath)){
ToastUtil.showMessage("视频路径异常", Toast.LENGTH_SHORT, true);
return;
}
try {
if(videoPath.equals(App.videoPath))
mediaPlayer = MediaPlayer.create(getContext(), R.raw.test);
else {
final File file = new File(videoPath);
if (!file.exists()) {//文件不存在
ToastUtil.showMessage("视频不存在", Toast.LENGTH_SHORT, true);
return;
}
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(file.getAbsolutePath());
}
mediaPlayer.setSurface(surface);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setVolume(0, 0); //设置左右音道的声音为0
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp){
mediaPlayer.start();
showIvTip(false);
isPlaying = true;
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
stopMediaPlayer();
}
});
mediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
}
}
private void showIvTip(boolean show){
if(ivTip != null){
int visibility = show?VISIBLE : GONE;
ivTip.setVisibility(visibility);
}
}
public void stopMediaPlayer(){
if(mediaPlayer != null && isPlaying) {
mediaPlayer.stop();
mediaPlayer.reset();
}
showIvTip(true);
isPlaying = false;
}
public void setIvTip(ImageView ivTip){
this.ivTip = ivTip;
}
public boolean getPlayStatus(){
return isPlaying;
}
public void setVideoPath(String path ){
videoPath = path;
}
public void onVideoTextureViewDestroy(){
isPlaying = false;
if(mediaPlayer != null){
stopMediaPlayer();
mediaPlayer.release();
}
}
}
静态效果图
源码地址: github.com/zx391324751… 觉得可以的话,恳请各位帮忙给个星星.