Android使用TextureView播放视频
1.引言
如果你想显示一段在线视频或者任意的数据流比如视频或者OpenGL 场景,你可以用android中的TextureView做到。
1).TextureView的兄弟SurfaceView
应用程序的视频或者opengl内容往往是显示在一个特别的UI控件中:SurfaceView。SurfaceView的工作方式是创建一个置于应用窗口之后的新窗口。这种 方式的效率非常高,因为SurfaceView窗口刷新的时候不需要重绘应用程序的窗口(android普通窗口的视图绘制机制是一层一层的,任何一个子元素或者 是局部的刷新都会导致整个视图结构全部重绘一次,因此效率非常低下,不过满足普通应用界面的需求还是绰绰有余),但是SurfaceView也有一些非常
不便的限制。
因为SurfaceView的内容不在应用窗口上,所以不能使用变换(平移、缩放、旋转等)。也难以放在ListView或者ScrollView中,不能使用UI控件的一些特性比如View.setAlpha()。
2).为了解决这个问题 Android 4.0中引入了TextureView。
TextureView与SurfaceView相比,TextureView并没有创建一个单独的Surface用来绘制,这使得它可以像一般的View一样执行一些变换操作,设置透明度等。另外,Textureview必须在硬件加速开启的窗口中。
项目中碰到的问题:1.之前用SurfaceView播放视频的时候,从图片切换到播放视频,会出现黑屏的现象。
2.SurfaceView灵活性没有TextureView好。
2.项目源码
MainActivity.java文件
<span style="font-size:14px;">package com.example.textureviewvideo; import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream; import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.TextureView.SurfaceTextureListener;
import android.widget.ImageView; public class MainActivity extends Activity implements SurfaceTextureListener{
// private TextureView textureView;
private MediaPlayer mMediaPlayer;
private Surface surface; private ImageView videoImage; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextureView textureView=(TextureView) findViewById(R.id.textureview);
textureView.setSurfaceTextureListener(this);//设置监听函数 重写4个方法 // textureView=new TextureViewTest(this);
// setContentView(textureView);
videoImage=(ImageView) findViewById(R.id.video_image);
} @Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width,int height) {
System.out.println("onSurfaceTextureAvailable onSurfaceTextureAvailable");
surface=new Surface(surfaceTexture);
new PlayerVideo().start();//开启一个线程去播放视频
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,int height) {
System.out.println("onSurfaceTextureSizeChanged onSurfaceTextureSizeChanged");
} @Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
System.out.println("onSurfaceTextureDestroyed onSurfaceTextureDestroyed");
surfaceTexture=null;
surface=null;
mMediaPlayer.stop();
mMediaPlayer.release();
return true;
} @Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
// System.out.println("onSurfaceTextureUpdated onSurfaceTextureUpdated");
} private class PlayerVideo extends Thread{
@Override
public void run(){
try {
File file=new File(Environment.getExternalStorageDirectory()+"/ansen.mp4");
if(!file.exists()){//文件不存在
copyFile();
}
mMediaPlayer= new MediaPlayer();
mMediaPlayer.setDataSource(file.getAbsolutePath());
mMediaPlayer.setSurface(surface);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp){
videoImage.setVisibility(View.GONE);
mMediaPlayer.start();
}
});
mMediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
}
}
} public interface PlayerController{
public void play();
} /**
* 如果sdcard没有文件就复制过去
*/
private void copyFile() {
AssetManager assetManager = this.getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open("ansen.mp4");
String newFileName = Environment.getExternalStorageDirectory()+"/ansen.mp4";
out = new FileOutputStream(newFileName);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
}</span>
TextureView创建的时显示图片,然后初始化播放器,预加载视频,如果视频文件不存在,从assets下copy一份到sdcard目录下,视频加载完毕隐藏图片,我这边图片默认显示的是android项目自带的图片,你们可以根据需求显示想要的图片。
activity_main.xml布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" > <TextureView
android:id="@+id/textureview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/> <ImageView
android:id="@+id/video_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_launcher"/>
</RelativeLayout>
放了一个TextureView跟一个ImageView TextureView初始化显示ImageView...当视频播放的时候隐藏ImageView,并且切换过去的时候不会出现黑屏。
3.效果图
播放之前显示的图片: 播放之后显示的图片:
其他问题:如果播放在线视频出现闪屏的问题,需要开启一个线程异步播放视频,然后再用handle延时隐藏图片。我用的是延时300毫秒
private void sendEmpryMessage(){
handler.sendEmptyMessageDelayed(0,300);//给主线程发送一个隐藏图片的消息
}
推荐下自己创建的android QQ群:202928390 欢迎大家的加入.
Android使用TextureView播放视频的更多相关文章
- Windows及Android倍速播放视频软件下载
目录 1. 更多推荐 2. 关键字 3. 按 4. 软件下载 4.1. IOS应用商店 4.2. 网盘下载 5. 软件介绍 5.1. PotPlayer(Windows) 5.2. MoboPlaye ...
- 不完全解决Android微信HTML5 播放视频的问题(不显示控制条,可交互)
首先你需要知道以下内容: http://ad.weixin.qq.com/learn/2-3-3--%E9%80%9A%E7%94%A8%E5%BA%93 这是微信为广告商开放的API,我一直认为只有 ...
- android SurfaceView中播放视频 按视频的原始比例播放
OnPreparedListener mediaPlayerOnPreparedListener = new OnPreparedListener() { @Override public void ...
- Android三种播放视频的方式
在Android中,我们有三种方式来实现视频的播放: 1.使用其自带的播放器.指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型. 2.使用VideoView来播放. ...
- Android VideoView简单播放视频
给Android VideoView一个文件目录,就可以直接播放智能设备中的视频文件,现在以播放事先用手机拍好并重命名的视频文件test.mp4为例.(1) 需要在布局文件中写一个ViedoView: ...
- android采用videoView播放视频(包装)
//android播放视频.用法:于androidManifest.xml添加activity, // <activity android:name=".PlayVideo" ...
- Android 使用MediaPlayer 播放 视频
http://pan.baidu.com/s/1lgKLS package cn.bgxt.surfaceviewdemo; import java.io.File; import android.m ...
- Android videoview循环播放视频
如何在一个activity里实现videoview对一个文件夹下的所有视频文件顺序循环播放,当切换界面时暂停, 切换回来继续原来的视频播放呢.所谓的 自动循环播放就是监听到视频播放结束之后继续重新播放 ...
- Android WebView无法播放视频或直播,关闭界面后任在播放的问题;
1.设置webview属性: webView.setWebChromeClient(new MyWebChromeClient()); webSettings = webView.ge ...
随机推荐
- oracle连接问题【转载】
SQL的四种连接-左外连接.右外连接.内连接.全连接 今天在看一个遗留系统的数据表的时候发现平时查找的视图是FULL OUT JOIN的,导致平时的数据记录要进行一些限制性处理,其实也可以设置视图 ...
- iOS中push视图的时候,屏幕中间会出现一条灰色的粗线的解决方案
因为执行动画需要时间,所以在动画未完成又执行另一个切换动画,容易产生异常.所以在一个方法连续push不同的VC是没有问题的,但是不小心push同一个VC,并且animated为YES,可能多次跳转了 ...
- 6_PHP AJAX MYSQL
XAMPP套装软件: 包含Apache.MySQL.PHP等多个开源软件的集合. https://www.apachefriends.org/zh_cn/index.html 监听完整相应消息: Wi ...
- 优化curl并发使用
经典curl并发的处理流程:首先将所有的URL压入并发队列, 然后执行并发过程, 等待所有请求接收完之后进行数据的解析等后续处理. 在实际的处理过程中, 受网络传输的影响, 部分URL的内容会优先于其 ...
- Python之路第一课Day6--随堂笔记(面向对象 )
本节内容: 1. 面向对象编程介绍 2. 为什么要用面向对象进行开发? 3. 面向对象的特性:封装.继承.多态 4. 类.方法 一.面向过程 VS 面向对象 1. 编程范式 编程是 程序 员 用 ...
- 关于DOM的一些笔记(一)
这篇文章整理的是关于DOM的一些学习笔记,这样以后查找起来也方便许多.(以前js看的是入门经典和DOM编程艺术,现在在看高级程序设计,本文就以高级程序为主整理) 1.Node (1):类型 node. ...
- Usaco*Monthly Expense
Description Farmer John是一个令人惊讶的会计学天才,他已经明白了他可能会花光他的钱,这些钱本来是要维持农场每个月的正常运转的.他已经计算了他以后N(1<=N<=100 ...
- mysql自动加入添加时间列
`addtime` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- int (*p)[10] 与*p[10]的区别
定义指向具有10个整型元素的一维数组的指针格式为:int (*p)[10] ,而起初我一直以为int (*p)[10] 是定义二维数组的方法 ][],(*p)[]; p=a; /*有了这个定义后,指针 ...
- 成为OpenStack工程师
OpenStack Hacker 态度:开放.主动.沟通 影响力:能说.能写.能分享 四化:自动化.流程化.系统化.文档化 0级 掌握一些基本技能:python.c.linux.git.unittes ...