TextureView+MediaPlayer播放本地视频
来源:互联网 发布:图解java多线程 pdf 编辑:程序博客网 时间:2024/04/30 08:21
TextureView介绍
应用程序的视频或者opengl内容往往是显示在一个特别的UI控件中:SurfaceView。SurfaceView的工作方式是创建一个置于应用窗口之后的新窗口。这种方式的效率非常高,因为SurfaceView窗口刷新的时候不需要重绘应用程序的窗口(android普通窗口的视图绘制机制是一层一层的,任何一个子元素或者是局部的刷新都会导致整个视图结构全部重绘一次,因此效率非常低下,不过满足普通应用界面的需求还是绰绰有余),但是SurfaceView也有一些非常不便的限制。因为SurfaceView的内容不在应用窗口上,所以不能使用变换(平移、缩放、旋转等)。也难以放在ListView或者ScrollView中,不能使用UI控件的一些特性比如View.setAlpha()
。
与SurfaceView相比,TextureView并没有创建一个单独的Surface用来绘制,这使得它可以像一般的View一样执行一些变换操作,设置透明度等。另外,Textureview必须在硬件加速开启的窗口中。
具体做法是先创建TextureView对象,然后实现SurfaceTextureListener接口
@Override public void onSurfaceTextureAvailable(SurfaceTexture arg0, int arg1, int arg2) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) { } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,int arg2) { } @Override public void onSurfaceTextureUpdated(SurfaceTexture arg0) { }
下面写一个使用TextureView播放视频Demo
效果图:
代码:
主界面:
package com.lly.videodemo.activitys.fragment;import android.graphics.SurfaceTexture;import android.media.AudioManager;import android.media.MediaPlayer;import android.os.Bundle;import android.support.annotation.Nullable;import android.util.Log;import android.view.Surface;import android.view.TextureView;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.ListView;import com.lly.videodemo.R;import com.lly.videodemo.activitys.BaseFragment;import com.lly.videodemo.activitys.adapter.VideoInfoAdapter;import com.lly.videodemo.activitys.entity.Video;import com.lly.videodemo.activitys.utils.Utils;import com.lly.videodemo.activitys.utils.VideoProvider;import org.xutils.view.annotation.ContentView;import org.xutils.view.annotation.Event;import org.xutils.view.annotation.ViewInject;import java.io.IOException;import java.util.ArrayList;import java.util.List;/** * @author 雷子 */@ContentView(R.layout.fragment_videoplay_layout)public class VideoFragment extends BaseFragment implements TextureView.SurfaceTextureListener { @ViewInject(R.id.id_textureview) private TextureView mTextureView; private Surface mSurface; private MediaPlayer mediaPlayer; //播放器是否准备好 private boolean isPrepared; @ViewInject(R.id.listview) private ListView mListView; private List<Video> mVideos; @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); initView(); //扫描本地视频 scanVideo(); } /** * 扫描本地视频 */ private void scanVideo() { new Thread() { @Override public void run() { super.run(); mVideos = new ArrayList<>(); VideoProvider videoProvider = new VideoProvider(getActivity()); mVideos = videoProvider.getList(); getActivity().runOnUiThread(new Runnable() { @Override public void run() { if (mVideos.size() > 0) { setAdapter(); } else {// showToast("木有扫描到视频!"); } } }); } }.start(); } /** * 填充数据 */ private void setAdapter() { VideoInfoAdapter infoAdapter = new VideoInfoAdapter(getActivity(), mVideos); mListView.setAdapter(infoAdapter); mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String path = mVideos.get(position).getPath(); Log.v("test", "Path:=" + path); if (path != null) { changePlay(path); } } }); } /** * 初始化View */ private void initView() { mTextureView.setSurfaceTextureListener(this); //设置16:9 int screenWeight = Utils.getWindowWidth(getActivity()); ViewGroup.LayoutParams layoutParams = mTextureView.getLayoutParams(); layoutParams.height = screenWeight * 9 / 16; mTextureView.setLayoutParams(layoutParams); } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { mSurface = new Surface(surface); initMediaPlayer(); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { mTextureView = null; mSurface = null; mediaPlayer.stop(); mediaPlayer.release(); return true; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } /** * 初始化播放器 */ public void initMediaPlayer() { mediaPlayer = new MediaPlayer(); try { mediaPlayer.setSurface(mSurface); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { isPrepared = true; } }); } catch (Exception e) { e.printStackTrace(); } } /** * 切换播放 * * @param path */ public void changePlay(String path) { try { mediaPlayer.reset(); mediaPlayer.setDataSource(path); mediaPlayer.prepare(); mediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); } } /** * 播放or暂停视频 */ public void play() { if (mediaPlayer != null) { if (mediaPlayer.isPlaying()) { mediaPlayer.stop(); } else { try { mediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } mediaPlayer.start(); } } } @Event(value = R.id.id_textureview) private void onViewClick(View v) { switch (v.getId()) { case R.id.id_textureview: if (isPrepared) { play(); } break; } }}
扫描本地视频代码(网上找的):
实体:
package com.lly.videodemo.activitys.entity;import java.io.Serializable;public class Video implements Serializable { /** * */ private static final long serialVersionUID = -7920222595800367956L; private int id; private String title; private String album; private String artist; private String displayName; private String mimeType; private String path; private long size; private long duration; /** * */ public Video() { super(); } /** * @param id * @param title * @param album * @param artist * @param displayName * @param mimeType * @param size * @param duration */ public Video(int id, String title, String album, String artist, String displayName, String mimeType, String path, long size, long duration) { super(); this.id = id; this.title = title; this.album = album; this.artist = artist; this.displayName = displayName; this.mimeType = mimeType; this.path = path; this.size = size; this.duration = duration; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAlbum() { return album; } public void setAlbum(String album) { this.album = album; } public String getArtist() { return artist; } public void setArtist(String artist) { this.artist = artist; } public String getDisplayName() { return displayName; } public void setDisplayName(String displayName) { this.displayName = displayName; } public String getMimeType() { return mimeType; } public void setMimeType(String mimeType) { this.mimeType = mimeType; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public long getSize() { return size; } public void setSize(long size) { this.size = size; } public long getDuration() { return duration; } public void setDuration(long duration) { this.duration = duration; }}
package com.lly.videodemo.activitys.utils;import android.content.Context;import android.database.Cursor;import android.provider.MediaStore;import com.lly.videodemo.activitys.entity.Video;import java.util.ArrayList;import java.util.List;public class VideoProvider { private Context mContext; public VideoProvider(Context context) { this.mContext = context; } public List<Video> getList() { List<Video> list = null; if (mContext != null) { Cursor cursor = mContext.getContentResolver().query( MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null, null, null); if (cursor != null) { list = new ArrayList<Video>(); while (cursor.moveToNext()) { int id = cursor.getInt(cursor .getColumnIndexOrThrow(MediaStore.Video.Media._ID)); String title = cursor .getString(cursor .getColumnIndexOrThrow(MediaStore.Video.Media.TITLE)); String album = cursor .getString(cursor .getColumnIndexOrThrow(MediaStore.Video.Media.ALBUM)); String artist = cursor .getString(cursor .getColumnIndexOrThrow(MediaStore.Video.Media.ARTIST)); String displayName = cursor .getString(cursor .getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)); String mimeType = cursor .getString(cursor .getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE)); String path = cursor .getString(cursor .getColumnIndexOrThrow(MediaStore.Video.Media.DATA)); long duration = cursor .getInt(cursor .getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)); long size = cursor .getLong(cursor .getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)); Video video = new Video(id, title, album, artist, displayName, mimeType, path, size, duration); list.add(video); } cursor.close(); } } return list; }}
下面Listview适配器:
package com.lly.videodemo.activitys.adapter;import android.content.Context;import android.graphics.Bitmap;import android.media.ThumbnailUtils;import android.provider.MediaStore;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import com.lly.videodemo.R;import com.lly.videodemo.activitys.entity.Video;import java.text.SimpleDateFormat;import java.util.Date;import java.util.List;/** * VideoInfoAdapter[v 1.0.0] * classes:com.lly.miss.adapter.VideoInfoAdapter * * @author lileiyi * @date 2016/1/26 * @time 11:48 * @description */public class VideoInfoAdapter extends BaseAdapter { private Context mContext; private List<Video> videos; private LayoutInflater mLayoutInflater; public VideoInfoAdapter(Context context, List<Video> videos) { this.mContext = context; this.videos = videos; mLayoutInflater = LayoutInflater.from(mContext); } @Override public int getCount() { return videos.size(); } @Override public Object getItem(int position) { return videos.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { viewHolder = new ViewHolder(); convertView = mLayoutInflater.inflate(R.layout.fragment_videolist_item, parent, false); viewHolder.imge_pic = (ImageView) convertView.findViewById(R.id.imge_pic); viewHolder.tv_duration = (TextView) convertView.findViewById(R.id.tv_duration); viewHolder.tv_title = (TextView) convertView.findViewById(R.id.tv_title); viewHolder.tv_type = (TextView) convertView.findViewById(R.id.tv_type); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } Video video = videos.get(position); viewHolder.tv_duration.setText(transferLongToDate("HH:mm:ss", video.getDuration())); viewHolder.tv_title.setText(video.getTitle()); viewHolder.tv_type.setText(video.getMimeType()); Bitmap bitmap = getVideoThumbnail(video.getPath(), 80, 80, MediaStore.Video.Thumbnails.MINI_KIND); if (bitmap != null) { viewHolder.imge_pic.setImageBitmap(bitmap); } return convertView; } private class ViewHolder { private ImageView imge_pic; private TextView tv_duration; private TextView tv_title; private TextView tv_type; } /** * 获取视频缩略图 * * @param videoPath * @param width * @param height * @param kind * @return */ private Bitmap getVideoThumbnail(String videoPath, int width, int height, int kind) { Bitmap bitmap = null; bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind); bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height, ThumbnailUtils.OPTIONS_RECYCLE_INPUT); return bitmap; } private String transferLongToDate(String dateFormat, Long millSec) { SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); Date date = new Date(millSec); return sdf.format(date); }}
Demo下载地址:http://download.csdn.net/detail/ght199266/9419620
1 0
- TextureView+MediaPlayer播放本地视频
- MediaPlayer+TextureView全屏播放视频
- MediaPlayer+TextureView全屏播放视频
- TextureView SurfaceView和MediaPlayer的视频播放
- TextureView+MediaPlayer实现在线短视频播放
- MediaPlayer+TextureView实现小视频居中(不拉伸)播放
- android 视频播放器 TextureView , MediaPlayer , SurfaceView 的坑
- TextureView实现视频播放
- Android MediaPlayer本地视频播放器
- Android MediaPlayer本地视频播放器
- 安卓本地视频播放SurfaceView+MediaPlayer
- MediaPlayer/MediaPlayer 视频播放
- 用MediaPlayer+TextureView封装一个实现全屏、小窗口的视频播放器
- Android使用TextureView播放视频
- 视屏播放_使用原生MediaPlayer+TextureView实现全屏、小窗口、视频列表、m3u8监控播放
- Android SurfaceView+MediaPlayer 播放本地raw文件夹下的视频
- SurfaceView和Mediaplayer实现播放网络和本地视频 一
- Android SurfaceView+MediaPlayer 本地视频播放器(卡拉OK功能)
- 信息流聚合类系统(如RSS阅读器)中数据同步的架构设计
- (转)UEFI系统的启动过程
- Maximum execution time of 30 seconds exceeded解决办法
- 虚拟机配置网卡网桥
- C语言学习之程序运行是内存的5大分区
- TextureView+MediaPlayer播放本地视频
- Wireshark
- 使用webview调起QQ临时会话
- ThinkPHP中的分表使用
- 1.CocoaPods的安装
- 2468: 统计各分数段的人数
- 文件描述符,文件句柄的区别
- 结合Xcode与Bitbucket进行版本管理
- 集训队专题(1)1001 Immediate Decodability