Android开发 MediaPlayer入门_播放本地视频

前言

  MediaPlayer,可以播放视频/音频,并且它支持本地和网络文件的播放.本片博客作为入门教程,先以最通俗的方式解释播放文件本地视频.(如果你嫌MediaPlayer还是太麻烦可以试试选择VideoView)

实现流程

  •   获取权限
  •   保持屏幕常亮
  •   初始化SurfaceView的状态监听
  •   初始化MediaPlayer
  •   给MediaPlayer添加预览SurfaceView的SurfaceHolder
  •   添加需要播放的视频并且配置MediaPlayer
  •   播放视频
  •   暂停视频
  •   停止视频
  •   释放内存

获取权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

播放本地视频,那就需要读写存储权限,注意别忘记了动态授权.另外MediaPlayer是支持网络视频播放的如果你需要播放网络视频则还需要添加网络权限

保持屏幕常亮

音视频开发的基本操作,在xml的根布局上添加下面这个属性,也可以在SurfaceView上添加

android:keepScreenOn="true"

初始化SurfaceView

作为显示播放视频的曲面View,如果你还不了解它.那么建议你先学习一些SurfaceView的知识.

我们需要监听SurfaceView状态,确定它启动完毕之后我们在开始加载播放视频.在onCreate执行下面的初始化initSurfaceviewStateListener

private void initSurfaceviewStateListener() {mSurfaceHolder = mVideoPlaySurfaceview.getHolder();mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(SurfaceHolder holder) {mMediaPlayer.setDisplay(holder);//给mMediaPlayer添加预览的SurfaceHoldersetPlayVideo(mPath);//添加播放视频的路径
            }@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {Log.e(TAG, "surfaceChanged触发: width=" + width + "height" + height);}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {}});}

在surfaceCreated方法里执行了2个方法:(当然可以先不关注,下面依然会重新提到它们)

  1. 给MediaPlayer添加预览的SurfaceHolder.
  2. 添加播放视频的路径与配置MediaPlayer

初始化MediaPlayer

private void initMediaPalyer() {mMediaPlayer = new MediaPlayer();}

直接new,没说明好说的,也是可以先在onCreate执行initMediaPalyer

给MediaPlayer添加预览SurfaceView的SurfaceHolder

SurfaceView初始化完成后直接给MediaPlayer设置SurfaceHolder >>>>> mMediaPlayer.setDisplay(holder);

mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(SurfaceHolder holder) {mMediaPlayer.setDisplay(holder);//给mMediaPlayer添加预览的SurfaceHoldersetPlayVideo(mPath);//添加播放视频的路径}

添加需要播放的视频并且配置MediaPlayer

    private void setPlayVideo(String path) {try {mMediaPlayer.setDataSource(path);//设置播放视频文件mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);//缩放模式mMediaPlayer.setLooping(true);//设置循环播放mMediaPlayer.prepareAsync();//异步准备
//            mMediaPlayer.prepare();//同步准备,因为是同步在一些性能较差的设备上会导致UI卡顿mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { //准备完成回调
                @Overridepublic void onPrepared(MediaPlayer mp) {mp.start();//启动播放视频}});} catch (IOException e) {e.printStackTrace();}}

setPlayVideo方法,在surfaceCreated接口回调方法里执行即可.上面已经有写就不在重复交代了

播放视频

private void startPlay(){if (!mMediaPlayer.isPlaying()){ //判断视频是否在播放mMediaPlayer.start();}}

暂停视频

 private void pausePlay(){if (mMediaPlayer.isPlaying()){mMediaPlayer.pause();}}

停止视频

private void stopPlay(){if (mMediaPlayer.isPlaying()){mMediaPlayer.stop();}}

释放内存

这是必要的,因为MediaPlayer底层是运行C++的函数方法.不要使用后,必需释放内存

@Overrideprotected void onDestroy() {super.onDestroy();if (mMediaPlayer != null){if (mMediaPlayer.isPlaying()){mMediaPlayer.stop();}mMediaPlayer.release();mMediaPlayer = null;}}

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) 信息监听
       mMediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {@Overridepublic boolean onInfo(MediaPlayer mp, int what, int extra) {//what 对应返回的值如下
//                public static final int MEDIA_INFO_UNKNOWN = 1;  媒体信息未知
//                public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; 媒体信息视频跟踪滞后
//                public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; 媒体信息\视频渲染\开始
//                public static final int MEDIA_INFO_BUFFERING_START = 701; 媒体信息缓冲启动
//                public static final int MEDIA_INFO_BUFFERING_END = 702; 媒体信息缓冲结束
//                public static final int MEDIA_INFO_NETWORK_BANDWIDTH = 703; 媒体信息网络带宽(703)
//                public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; 媒体-信息-坏-交错
//                public static final int MEDIA_INFO_NOT_SEEKABLE = 801; 媒体信息找不到
//                public static final int MEDIA_INFO_METADATA_UPDATE = 802; 媒体信息元数据更新
//                public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; 媒体信息不支持字幕
//                public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; 媒体信息字幕超时return false;}});

贴心周到,贴全demo代码,给你查缺补漏

xml文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"android:keepScreenOn="true"android:background="@color/colorBlack1"tools:context=".work.share.VideoPlayActivity"><SurfaceViewandroid:id="@+id/video_play_surfaceview"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintVertical_bias="0.5"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"/><ImageViewandroid:id="@+id/start_and_stop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/ic_start"android:layout_marginBottom="50dp"android:layout_marginLeft="20dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintBottom_toBottomOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

activity

import androidx.constraintlayout.widget.ConstraintLayout;
import android.content.pm.ActivityInfo;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import com.yt.kangaroo.R;
import com.yt.kangaroo.app.BaseActivity;
import java.io.File;
import java.io.IOException;
/***@content:视频播放activity*@time:2019-6-13*@build:*/public class VideoPlayActivity extends BaseActivity implements View.OnClickListener {private static final String TAG = VideoPlayActivity.class.getSimpleName();private SurfaceView mVideoPlaySurfaceview;private ImageView mStartAndStop;private MediaPlayer mMediaPlayer;private String mPath;private boolean isInitFinish = false;private SurfaceHolder mSurfaceHolder;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);File file = new File(getExternalCacheDir(), "demo.mp4");mPath = file.getAbsolutePath();initMediaPalyer();initSurfaceviewStateListener();}@Overrideprotected void onPause() {super.onPause();pausePlay();}@Overridepublic int getLayout() {return R.layout.activity_video_play;}@Overridepublic void initView() {mVideoPlaySurfaceview = findViewById(R.id.video_play_surfaceview);mStartAndStop = findViewById(R.id.start_and_stop);mStartAndStop.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.start_and_stop:if (mMediaPlayer.isPlaying()) {pausePlay();mStartAndStop.setImageResource(R.mipmap.ic_start);} else {startPlay();mStartAndStop.setImageResource(R.mipmap.ic_stop);}break;default:break;}}private void initSurfaceviewStateListener() {mSurfaceHolder = mVideoPlaySurfaceview.getHolder();mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(SurfaceHolder holder) {mMediaPlayer.setDisplay(holder);//给mMediaPlayer添加预览的SurfaceHoldersetPlayVideo(mPath);//添加播放视频的路径
            }@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {Log.e(TAG, "surfaceChanged触发: width=" + width + "height" + height);}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {}});}private void initMediaPalyer() {mMediaPlayer = new MediaPlayer();}private void setPlayVideo(String path) {try {mMediaPlayer.setDataSource(path);//
            mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);//缩放模式mMediaPlayer.setLooping(true);//设置循环播放mMediaPlayer.prepareAsync();//异步准备
//            mMediaPlayer.prepare();//同步准备,因为是同步在一些性能较差的设备上会导致UI卡顿mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { //准备完成回调
                @Overridepublic void onPrepared(MediaPlayer mp) {isInitFinish = true;mp.start();}});} catch (IOException e) {e.printStackTrace();}}private void startPlay(){if (!mMediaPlayer.isPlaying()){mMediaPlayer.start();}}private void stopPlay(){if (mMediaPlayer.isPlaying()){mMediaPlayer.stop();}}private void pausePlay(){if (mMediaPlayer.isPlaying()){mMediaPlayer.pause();}}private void seekTo(int time){mMediaPlayer.seekTo(time);}@Overrideprotected void onDestroy() {super.onDestroy();if (mMediaPlayer != null){if (mMediaPlayer.isPlaying()){mMediaPlayer.stop();}mMediaPlayer.release();mMediaPlayer = null;}}}

end

posted on 2019-06-13 21:35 观心静 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/guanxinjing/p/11019662.html

Android开发 MediaPlayer入门_播放本地视频相关推荐

  1. android实现本地视频播放功能,Android开发 MediaPlayer入门_播放本地视频

    前言 MediaPlayer,可以播放视频/音频,并且它支持本地和网络文件的播放.本片博客作为入门教程,先以最通俗的方式解释播放文件本地视频. 实现流程 获取权限 保持屏幕常亮 初始化SurfaceV ...

  2. android局域网视频传输,[Android]如何通过局域网从计算机播放本地视频

    与移动电话相比,计算机具有功能强大和存储容量大的优势,但是我们越来越依赖于移动电话等移动设备. 很少打开计算机. 我可以使用计算机为手机等移动设备服务吗?通过在同一网络中设置计算机文件夹共享,移动设备 ...

  3. Android 使用MediaPlayer播放本地视频

    MediaPlayer可以播放视频和音频,并且它支持本地和网络文件的播放.本篇文章是使用MediaPlayer播放本地视频,如果觉得使用MediaPlayer比较麻烦,也可以选择VideoView播放 ...

  4. Android无法播放本地视频

    最近初学安卓,在Android Studio里面做播放本地视频功能时遇到了,路径正确却弹出了"无法播放此视频"的情况(网络视频可以正常播放). 解决办法: 由于安卓10更新了一些东 ...

  5. android java教程_[Java教程]Android开发快速入门

    [Java教程]Android开发快速入门 0 2020-12-22 18:01:40 Xamarin.Android 应用程序剖析 以下屏幕截图列出了解决方案的内容. 下面是一个解决方案资源管理器, ...

  6. 安卓开发VideoView播放本地视频失败解决办法

    先上代码MainActivity.java 一个简单的videoview播放视频的功能 public class MainActivity extends AppCompatActivity {pri ...

  7. view_video.php,Android_Android使用VideoView播放本地视频和网络视频的方法,1、效果展示2、布局文件- phpStudy...

    Android使用VideoView播放本地视频和网络视频的方法 1.效果展示 2.布局文件 xmlns:tools="http://schemas.android.com/tools&qu ...

  8. 如视VR显示连不上服务器,HTC Vive播放本地视频图文教程(附常见问题解决办法)...

    由于需要连接电脑设备,因而部分新手用户不懂如何使用HTC Vive播放本地视频.实际上整个操作并不复杂,只需要用到Vive Cinema播放器即可.Vive Cinema是HTC VR New Tec ...

  9. Android开发从入门到精通

    Android开发从入门到精通 --Android经典教程 目 录 目 录 1 第一章 什么是Android 1 什么是Android - 嵌入式设备编程的历史-第一章(1) 1 开放手机联盟和And ...

  10. Win10系统,用C++调用OpenCV接口,播放本地视频文件,播放本地和网络摄像头

    1 前言 前边2篇文章介绍了在WIN10系统上,分别用C++和Python调用OpenCV接口,加载和显示一张静态图片.本篇我们来看一下,用C++如何调用OpenCV接口,打开和播放本地视频文件,打开 ...

最新文章

  1. 在Andoird studio 中用代码实现setId报错,而在ecplise中可以,的处理方法
  2. 攻读计算机视觉和机器学习硕士给我带来了什么?
  3. 用 Flask 来写个轻博客 (28) — 使用 Flask-Assets 压缩 CSS/JS 提升网页加载速度
  4. html a标签去掉下划线_让HTML元素动起来
  5. 储留香:一个智能运维系统就是一个中枢神经系统,我说的!
  6. js_!和!!的使用
  7. .net mysql数据库_.net连接MySQL数据库
  8. 自然语言处理 —— 2.7负采样
  9. 对android中ActionBar中setDisplayHomeAsUpEnabled和setHomeButtonEnabled和setDisplayShowHomeEnabled方法的理解...
  10. lhgcoreDialogPlugin v3.5.2 使用点滴
  11. MySQL 常用的查询命令
  12. mysql 系统序列号_mysql 序列号
  13. 计算机室 多媒体教室制度,多媒体教室计算机室规章制度.doc
  14. 惠普打印机故障代码_HP激光打印机常见故障代码
  15. N81新手入门全攻略——N81常规设置问答篇
  16. Github上的1000多本免费电子书重磅来袭!
  17. 摄像头防水性能测试软件,手机摄像头防水测试/气密性检测方法分享
  18. 史上最全最准的支付行业常用名词解释精选
  19. 应用泛函分析—距离空间
  20. python selenium 点击加载更多_Python Selenium 疑难杂症解方(三): 点击

热门文章

  1. 求求你们了,别再写满屏的 if/ else 了!
  2. 分布式服务的幂等性设计,值得学习!
  3. 5亿次Web攻击 怎么防住的?
  4. 100 个网络基础知识 看完成半个网络高手
  5. “技术天才”李一男已出狱:曾被视为华为接班人!华中科大少年班,27岁华为副总裁,曾任百度CTO...
  6. Google 投资了京东
  7. LICEcap 录制Gif动画
  8. BZOJ4998 星球联盟(LCT+双连通分量+并查集)
  9. 'telent' 不是内部或外部命令,也不是可运行的程序或批处理文件。
  10. LinkedList 注意事项