Android 播放SD卡视频 Demo
Android播放视频有好几种方式,比如VideoView,SurfaceView,Android自带的播放器,第三方播放器(比如vitamio等等 之前毕设用过,挺不错)
公司需要编写相关的测试代码,简单研究了一下。做做笔记,备忘。(注:部分代码来源于互联网)
使用VideoView播放视频:
布局文件:很简单,VideoView+几个button,用线性布局简单控制一下
<LinearLayout 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"android:orientation="vertical"tools:context=".MainActivity" ><VideoView
android:id="@+id/videoview"android:layout_width="fill_parent"android:layout_height="200dp" /><LinearLayout
android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><Button
android:id="@+id/play"android:text="play"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1" /><Button
android:id="@+id/pause"android:text="pause"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1" /><Button
android:id="@+id/replay"android:text="replay"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1" /></LinearLayout></LinearLayout>
继续操作之前,先在SD卡根目录放置一个视频文件1.mp4(先使用固定路径,之后再使用动态设置的路径)
下面继续写MainActivity:
public class MainActivity extends Activity implements OnClickListener {private static final String TAG = "MainActivity";VideoView video;Button play;Button pause;Button replay;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);video = (VideoView) findViewById(R.id.videoview);play = (Button) findViewById(R.id.play);pause = (Button) findViewById(R.id.pause);replay = (Button) findViewById(R.id.replay);play.setOnClickListener(this);pause.setOnClickListener(this);replay.setOnClickListener(this);logcat("onCreate");initVediopath();}@Overrideprotected void onDestroy() {super.onDestroy();if (null != video) {video.suspend();}}private void initVediopath() {logcat("initVediopath");File file = new File(Environment.getExternalStorageDirectory(), "1.mp4");logcat("" + Environment.getExternalStorageDirectory());if (file.exists()) {logcat("setPath");video.setVideoPath(file.getPath());} else {Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();logcat("file not exsit");}}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.play:if (!video.isPlaying()) {video.start();}break;case R.id.pause:if (video.isPlaying()) {video.pause();}break;case R.id.replay:if (video.isPlaying()) {video.resume();}break;default:break;}}public void logcat(String log) {Log.i(TAG, log);}
}
MainActivity也很简单,findv的iew,设置listener,设置视频路径,Activity销毁时将VideoView挂起。按钮 的点击事件也就简单的调用VideoView的相关方法。
最后别忘了添加读取SD卡的权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
使用 SurfaceView+MediaPlayer播放视频
MediaPlayer控制视频,SurfaceView负责显示(个人理解,有误请帮忙指出,另外此部分代码大部分参考某篇博客,但是暂时找不到原文了。。。)
布局文件:和上面类似,不过把VideoView换成SurfaceView,另外多了几个button
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/LinearLayout1"android:layout_width="match_parent"android:layout_height="match_parent"android:weightSum="1"android:orientation="vertical" ><SurfaceViewandroid:id="@+id/surfaceVIew"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="0.15"tools:context=".MainActivity" /><LinearLayout android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="0.85"><Button android:id="@+id/btn_play"android:text="开始"android:layout_width="wrap_content"android:layout_height="wrap_content"/><Button android:id="@+id/btn_pause"android:text="暂停"android:layout_width="wrap_content"android:layout_height="wrap_content"/><Button android:id="@+id/btn_stop"android:text="停止"android:layout_width="wrap_content"android:layout_height="wrap_content"/><Button android:id="@+id/btn_low"android:text="调低"android:layout_width="wrap_content"android:layout_height="wrap_content"/><Button android:id="@+id/btn_hight"android:text="调高"android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout>
</LinearLayout>
与上面一样,先使用死路径,在SD卡根目录放置1.mp4。同时先把访问SD卡的权限加上吧。
主Activity:
和上面的步骤类似,不过稍微复杂些。主要是SurfaceView有三个callback
surfaceCreated
surfaceChanged
surfaceDestroyed
在SurfaceView创建时做一些视频的初始化操作。
在SurfaceView销毁时释放资源
横竖屏的地方暂时可以忽略。大体上和上面还是一样的。
public class MainActivity extends Activity implements OnClickListener {/* 功能按钮 */private Button btn_play, btn_pause, btn_stop, btn_low, btn_height;/* SurfaceView */private SurfaceView mSurfaceView;/* 播放视频对象 */private MediaPlayer mediaPlayer;/* 系统声音 */private AudioManager audioManager;/* 记录播放位置 */private int position;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);/* 设置窗口无title */requestWindowFeature(Window.FEATURE_NO_TITLE);/* 全屏显示 */this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);setContentView(R.layout.activity_main);findViews();setListeners();mediaPlayer = new MediaPlayer();setSurfaceView();}// 横竖屏切换时的处理@Overrideprotected void onSaveInstanceState(Bundle outState) {if (mediaPlayer != null && mediaPlayer.isPlaying()) {// 如果在播放的时候切换屏幕则保存当前观看的位置outState.putInt("position", mediaPlayer.getCurrentPosition());}super.onSaveInstanceState(outState);}// 横竖屏切换后的处理@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {if (savedInstanceState.containsKey("position")) {position = savedInstanceState.getInt("position");// 取得切换屏幕时保存的位置}super.onRestoreInstanceState(savedInstanceState);}/* 实例化UI */private void findViews() {btn_play = (Button) findViewById(R.id.btn_play);btn_pause = (Button) findViewById(R.id.btn_pause);btn_stop = (Button) findViewById(R.id.btn_stop);btn_low = (Button) findViewById(R.id.btn_low);btn_height = (Button) findViewById(R.id.btn_hight);mSurfaceView = (SurfaceView) findViewById(R.id.surfaceVIew);audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);}/* 为5个按钮设置监听 */private void setListeners() {btn_play.setOnClickListener(this);btn_pause.setOnClickListener(this);btn_stop.setOnClickListener(this);btn_low.setOnClickListener(this);btn_height.setOnClickListener(this);}/* 播放视频 */private void playMedia() {/* 初始化状态 */mediaPlayer.reset();/* 设置声音流类型 */mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);/* 设置mp3\mp4加载路径 */File file = new File(Environment.getExternalStorageDirectory(), "1.mp4");try {mediaPlayer.setDataSource(file.getAbsolutePath());// 缓冲mediaPlayer.prepare();// 开始播放mediaPlayer.start();// 具体位置Log.i("position", position + "------");mediaPlayer.seekTo(position);// 视频输出到ViewmediaPlayer.setDisplay(mSurfaceView.getHolder());// 重置位置为0position = 0;} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/* 设置surfaceView视图 */private void setSurfaceView() {// creates a "push" surfacemSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 设置事件,回调函数mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {/* SurfaceView创建时 */@Overridepublic void surfaceCreated(SurfaceHolder holder) {if (position > 0) {playMedia();position = 0;}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format,int width, int height) {}/* SurfaceView销毁视图 */@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {if (mediaPlayer.isPlaying()) {mediaPlayer.stop();}/* Activity销毁时停止播放,释放资源。不做这个操作,即使退出,还是能听到视频的声音 */mediaPlayer.release();}});}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_play:// 播放if (mediaPlayer != null && mediaPlayer.isPlaying()) {return;} else {playMedia();}break;case R.id.btn_pause:// 暂停if (mediaPlayer != null && mediaPlayer.isPlaying()) {position = mediaPlayer.getCurrentPosition();mediaPlayer.pause();} else {return;}break;case R.id.btn_stop:// 停止if (mediaPlayer != null && mediaPlayer.isPlaying()) {mediaPlayer.stop();position = 0;} else {return;}break;case R.id.btn_low:// 调小音量// 获取当前的音乐音量int volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);Log.v("Volume", "volume" + volume);// 音量>0if (volume > 0) {audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,AudioManager.ADJUST_LOWER, 0);} else {return;}break;case R.id.btn_hight:// 调大音量volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);// 音量<100if (volume < audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)) {audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,AudioManager.ADJUST_RAISE, 0);} else {return;}break;}}}
下一篇说下如何扫描SD卡的视频文件,并会附上本文中的案例和一个播放MP3的demo
Android 播放SD卡视频 Demo相关推荐
- android 获取sd卡视频文件名,android – 如何获取SD卡上的视频列表
查询MediaStore内容提供商 一个例子可能是 public static void printNamesToLogCat(Context context) { Uri uri = MediaSt ...
- Android 扫描SD卡中的所有视频文件
Android应该是已经把所有的视频文件音频都在开机时,扫描完毕然后存在本地SQLite数据库了,因此,我们"扫描"的最简单方法是读取这个已经存储好的数据库.但是这样做,在程序开启 ...
- android读写sd卡代码,android读写SD卡中的文件 demo
有时,我们需要将更大的文件保存下来,就不能用手机内置的存储空间,毕竟是有限的,所以将文件保存在SD卡中. 要读写SD卡,首先要知道手机上是否有SD卡,且是否可读写 String str = " ...
- Android播放器实现视频窗口实时放大缩小功能
很多开发者希望Android播放端实现视频窗口的放大缩小功能,为此,我们做了个简单的demo,通过播放端回调RGB数据,直接在上层view操作处理即可,Github:https://github.co ...
- Android 判断SD卡是否存在及容量查询
转载:http://blog.csdn.net/xinzheng_wang/article/details/7827775 Android 判断SD卡是否存在及容量查询的简单方法如下: 首先要在And ...
- Android 获取SD卡路径和判断SD卡是否存在.
android获取sd卡路径方法: public String getSDPath(){ File sdDir = null; boolean sdCardExist =Environment.get ...
- videojs播放m3u8后缀视频Demo
videojs播放m3u8后缀视频Demo 转载自:https://segmentfault.com/a/1190000024447688 <!DOCTYPE html><html ...
- 2011 明锐 CD 大众收音机 播放SD 卡顿问题
2011 明锐 CD 大众收音机 播放SD 卡顿问题 TOPPOWER生产型号1ZD 085 186 在手动或自动切换歌曲时会随机出现反复回放上首歌的部分内容,有时会出现报sd err 错误无法播放或 ...
- sd卡视频被删怎么恢复呢?
在移动互联网中,经常是以视频为主记录着我们生活的方方面面.随着视频文件的增多,储存也成为了新的问题.虽然在相机SD卡有一定存储空间,但往往很容易损坏.所以不少小伙伴会选择在电脑上进行备份储存.由于空间 ...
最新文章
- 网格员计算机基本操作,网格交易总结系列(一)基本操作篇
- 剑指offer十:矩形覆盖
- JavaScript: 代码简洁之道
- 1.9 Java 9增强的自动资源管理
- Nginx Mac笔记
- JavaFx实现-渐变效果之一
- 协作通信-af df的matlab仿真,协作通信-AF、DF的MATLAB仿真(解压密码yuema1086)
- LINQ之路 2:C# 3.0的语言功能(上)
- curl有php内存缓存,PHP CURL内存泄露的解决方法
- 张小龙:做 PC 版微信是一种破坏,本来不想做
- 目标检测——neck组件的学习笔记
- C#常见算法题目(面试准备)
- UDP和TCP 简单 区别
- 查询优化器内核剖析第六篇:谈谈Join的顺序问题,纠正江湖偏方
- 微信小程序实现OCR扫描识别
- Stata: 图示交互效应\调节效应
- 文件服务器 excle 变为temp,WPS的excel表格保存之后变成tmp_共享文档无法保存EXCLE 生成TMP...
- Tableau自定义分类调色板
- 银河麒麟V10 SP2 搭建tftp服务
- 苹果隐藏app_iOS14隐藏功能,很实用!附部分BUG解决方案
热门文章
- mysql操作json优点和缺点_mysql之使用json
- Luogu P1197 [JSOI2008]星球大战
- [bzoj 3594] [Scoi2014]方伯伯的玉米田
- ASP.NET关于WebPages的一点总结
- android fragment点击返回键实现内容切换?
- zz 聊聊并发(二)
- leetcode 1160 python
- 深度学习——行数据的分拆及如何“喂”给训练过程
- 资源放送丨《Oracle RAC 集群安装部署》PPT视频
- 详解PostgreSQL数据库中的两阶段锁