Android(安卓)使用MediaPlayer播放本地视频
16lz
2021-01-25
MediaPlayer可以播放视频和音频,并且它支持本地和网络文件的播放。本篇文章是使用MediaPlayer播放本地视频,如果觉得使用MediaPlayer比较麻烦,也可以选择VideoView播放视频。
MainActivity.java 代码如下:
package per.juan.playvideodome;import androidx.appcompat.app.AppCompatActivity;import android.content.Context;import android.content.res.AssetFileDescriptor;import android.media.MediaPlayer;import android.os.Build;import android.os.Bundle;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.WindowManager;public class MainActivity extends AppCompatActivity { SurfaceView mSvVideoPlayer; private MediaPlayer mMediaPlayer; private int mPosition = 0; private boolean hasActiveHolder = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSvVideoPlayer = findViewById(R.id.sv_video_player); playVideo(); } /** * 播放视频 */ public void playVideo() { if (mMediaPlayer == null) { //实例化MediaPlayer对象 mMediaPlayer = new MediaPlayer(); mSvVideoPlayer.setVisibility(View.VISIBLE); boolean mHardwareDecoder = false; // 不维持自身缓冲区,直接显示 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB && mHardwareDecoder) { mSvVideoPlayer.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } mSvVideoPlayer.getHolder().setFixedSize(getScreenWidth(), getScreenHeight()); mSvVideoPlayer.getHolder().setKeepScreenOn(true);//保持屏幕常亮 mSvVideoPlayer.getHolder().addCallback(new SurFaceCallback()); } } /** * 向player中设置dispay,也就是SurfaceHolder。但此时有可能SurfaceView还没有创建成功,所以需要监听SurfaceView的创建事件 */ private final class SurFaceCallback implements SurfaceHolder.Callback { @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { if (mMediaPlayer == null) { return; } if (!hasActiveHolder) { play(mPosition); hasActiveHolder = true; } if (mPosition > 0) { play(mPosition); mPosition = 0; } } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mMediaPlayer == null) { return; } if (mMediaPlayer.isPlaying()) { mMediaPlayer.stop(); mPosition = mMediaPlayer.getCurrentPosition(); } } private void play(int position) { try { //添加播放视频的路径与配置MediaPlayer AssetFileDescriptor fileDescriptor = getResources().openRawResourceFd(R.raw.info); mMediaPlayer.reset(); //给mMediaPlayer添加预览的SurfaceHolder,将播放器和SurfaceView关联起来 mMediaPlayer.setDisplay(mSvVideoPlayer.getHolder()); mMediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength()); // 缓冲 mMediaPlayer.prepare(); mMediaPlayer.setOnBufferingUpdateListener(new BufferingUpdateListener()); mMediaPlayer.setOnPreparedListener(new PreparedListener(position)); mMediaPlayer.setOnCompletionListener(new CompletionListener()); } catch (Exception e) { e.printStackTrace(); } } } /** * 缓冲变化时回调 */ private final class BufferingUpdateListener implements MediaPlayer.OnBufferingUpdateListener { @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { } } /** * 准备完成回调 * 只有当播放器准备好了之后才能够播放,所以播放的出发只能在触发了prepare之后 */ private final class PreparedListener implements MediaPlayer.OnPreparedListener { private int position; public PreparedListener(int position) { this.position = position; } @Override public void onPrepared(MediaPlayer mp) { mMediaPlayer.start(); if (position > 0) { mMediaPlayer.seekTo(position); } } } /** * 播放结束时回调 */ private final class CompletionListener implements MediaPlayer.OnCompletionListener { @Override public void onCompletion(MediaPlayer mp) { mMediaPlayer.start(); } } @Override public void onDestroy() { //释放内存,MediaPlayer底层是运行C++的函数方法,不使用后必需释放内存 if (mMediaPlayer != null) { if (mMediaPlayer.isPlaying()) { mMediaPlayer.pause(); mPosition = mMediaPlayer.getCurrentPosition(); } mMediaPlayer.release(); mMediaPlayer = null; } super.onDestroy(); } private int getScreenWidth() { return ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth(); } private int getScreenHeight() { return ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay() .getHeight(); }}
activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?>
由于代码都有写的注释,这里就不一一赘述啦!用到的API主要有:
- void setDataSource(String path) 通过一个具体的路径来设置MediaPlayer的数据源,path可以是本地的一个路径,也可以是一个网络路径
- void setDataSource(Context context, Uri uri) 通过给定的Uri来设置MediaPlayer的数据源,这里的Uri可以是网络路径或是一个ContentProvider的Uri。
- void setDataSource(MediaDataSource dataSource) 通过提供的MediaDataSource来设置数据源
- void setDataSource(FileDescriptor fd) 通过文件描述符FileDescriptor来设置数据源
- int getCurrentPosition() 获取当前播放的位置
- int getAudioSessionId() 返回音频的session ID
- int getDuration() 得到文件的时间
- TrackInfo[] getTrackInfo() 返回一个track信息的数组
- boolean isLooping () 是否循环播放
- boolean isPlaying() 是否正在播放
- void pause () 暂停
- void start () 开始
- void stop () 停止
- void prepare() 同步的方式装载流媒体文件。
- void prepareAsync() 异步的方式装载流媒体文件。
- void reset() 重置MediaPlayer至未初始化状态。
- void release () 回收流媒体资源。
- void seekTo(int msec) 指定播放的位置(以毫秒为单位的时间)
- void setAudioStreamType(int streamtype) 指定流媒体类型
- void setLooping(boolean looping) 设置是否单曲循环
- void setNextMediaPlayer(MediaPlayer next) 当 当前这个MediaPlayer播放完毕后,MediaPlayer next开始播放
- void setWakeMode(Context context, int mode):设置CPU唤醒的状态。
- setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) 网络流媒体的缓冲变化时回调
- setOnCompletionListener(MediaPlayer.OnCompletionListener listener) 网络流媒体播放结束时回调
- setOnErrorListener(MediaPlayer.OnErrorListener listener) 发生错误时回调
- setOnPreparedListener(MediaPlayer.OnPreparedListener listener):当装载流媒体完毕的时候回调。
- setOnInfoListener(OnInfoListener l) 信息监听
好了,本篇文章就这样了,存在总结不到位的地方还望指导,感谢_
源码下载
更多相关文章
- android源码中的c c++库( android中动态和静态版本都有的库)
- Android(安卓)签名之使用命令行给apk签名
- Android(安卓)命令行编译、打包生成apk文件
- Android(安卓)envsetup.sh剖析
- Android(安卓)Studio 配置JNI快速生成头文件
- 搭建windows下的android开发环境
- android中的保存数据方法
- android SDK启动的错误
- 在xml文件的Preference标签中,用给标签加参数