Android开发 MediaPlayer入门_播放本地视频
<h1><span style="color: rgba(0, 128, 128, 1)">版权声明</span></h1><p>本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/11019662.html</p>
<div>本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。</div>
<h1><span style="color: rgba(0, 128, 128, 1)">前言</span></h1>
<p> MediaPlayer,可以播放视频/音频,并且它支持本地和网络文件的播放.本片博客作为入门教程,先以最通俗的方式解释播放文件本地视频.(如果你嫌MediaPlayer还是太麻烦可以试试选择VideoView)</p>
<h1><span style="color: rgba(0, 128, 128, 1)">实现流程</span></h1>
<ul>
<li> 获取权限</li>
<li> 保持屏幕常亮</li>
<li> 初始化SurfaceView的状态监听</li>
<li> 初始化MediaPlayer</li>
<li> 给<span style="color: rgba(0, 0, 0, 1)">MediaPlayer</span>添加预览SurfaceView的<span style="color: rgba(0, 0, 0, 1)">SurfaceHolder</span></li>
<li> 添加需要播放的视频并且配置MediaPlayer</li>
<li> 播放视频</li>
<li> 暂停视频</li>
<li> 停止视频</li>
<li> 释放内存</li>
</ul>
<p> </p>
<h1><span style="color: rgba(0, 128, 128, 1)">获取权限</span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">uses-permission </span><span style="color: rgba(255, 0, 0, 1)">android:name</span><span style="color: rgba(0, 0, 255, 1)">="android.permission.WRITE_EXTERNAL_STORAGE"</span> <span style="color: rgba(0, 0, 255, 1)">/></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">uses-permission </span><span style="color: rgba(255, 0, 0, 1)">android:name</span><span style="color: rgba(0, 0, 255, 1)">="android.permission.READ_EXTERNAL_STORAGE"</span> <span style="color: rgba(0, 0, 255, 1)">/></span></pre>
</div>
<p>播放本地视频,那就需要读写存储权限,注意别忘记了动态授权.另外MediaPlayer是支持网络视频播放的如果你需要播放网络视频则还需要添加网络权限</p>
<h1><span style="color: rgba(0, 128, 128, 1)">保持屏幕常亮</span></h1>
<p>音视频开发的基本操作,在xml的根布局上添加下面这个属性,也可以在<span style="color: rgba(0, 0, 128, 1); font-weight: bold">SurfaceView</span>上添加</p>
<div class="cnblogs_code">
<pre>android:keepScreenOn="true"</pre>
</div>
<h1><span style="color: rgba(0, 128, 128, 1)">初始化SurfaceView</span></h1>
<p>作为显示播放视频的曲面View,如果你还不了解它.那么建议你先学习一些SurfaceView的知识.</p>
<p>我们需要监听SurfaceView状态,确定它启动完毕之后我们在开始加载播放视频.在onCreate执行下面的初始化<span style="color: rgba(0, 0, 0, 1)">initSurfaceviewStateListener</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> initSurfaceviewStateListener() {
mSurfaceHolder </span>=<span style="color: rgba(0, 0, 0, 1)"> mVideoPlaySurfaceview.getHolder();
mSurfaceHolder.addCallback(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SurfaceHolder.Callback() {
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> surfaceCreated(SurfaceHolder holder) {
mMediaPlayer.setDisplay(holder);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">给mMediaPlayer添加预览的SurfaceHolder</span>
setPlayVideo(mPath);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加播放视频的路径</span>
<span style="color: rgba(0, 0, 0, 1)"> }
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> surfaceChanged(SurfaceHolder holder, <span style="color: rgba(0, 0, 255, 1)">int</span> format, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> height) {
Log.e(TAG, </span>"surfaceChanged触发: width=" + width + "height" +<span style="color: rgba(0, 0, 0, 1)"> height);
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> surfaceDestroyed(SurfaceHolder holder) {
}
});
}</span></pre>
</div>
<p>在<span style="color: rgba(0, 0, 0, 1)">surfaceCreated</span>方法里执行了2个方法:(当然可以先不关注,下面依然会重新提到它们)</p>
<ol>
<li><span style="color: rgba(0, 0, 0, 1)">给MediaPlayer添加预览的SurfaceHolder.</span></li>
<li><span style="color: rgba(0, 0, 0, 1)">添加播放视频的路径与配置<span style="color: rgba(0, 0, 0, 1)">MediaPlayer</span></span></li>
</ol>
<h1><span style="color: rgba(0, 128, 128, 1)">初始化MediaPlayer</span></h1>
<p><strong><span style="color: rgba(255, 0, 0, 1)">请注意</span></strong><span style="color: rgba(0, 0, 0, 1)"><strong><span style="color: rgba(255, 0, 0, 1)">,MediaPlayer最好是全局变量</span></strong>让某个class一直持有直到你不需要为止,如果是局部变量会有概率出现播放时突然中断的问题</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> initMediaPalyer() {
mMediaPlayer </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> MediaPlayer();
}</span></pre>
</div>
<p>直接new,没说明好说的,也是可以先在onCreate执行<span style="color: rgba(0, 0, 0, 1)">initMediaPalyer</span></p>
<h1><span style="color: rgba(0, 128, 128, 1)">给MediaPlayer添加预览SurfaceView的SurfaceHolder</span></h1>
<p><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">SurfaceView</span></span></span>初始化完成后直接给<span style="color: rgba(0, 0, 0, 1)">MediaPlayer</span>设置<span style="color: rgba(0, 0, 0, 1)">SurfaceHolder >>>>> <strong><span style="color: rgba(0, 0, 0, 1)">mMediaPlayer.setDisplay(holder);</span></strong></span></p>
<div class="cnblogs_code">
<pre>mSurfaceHolder.addCallback(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SurfaceHolder.Callback() {
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> surfaceCreated(SurfaceHolder holder) {
mMediaPlayer.setDisplay(holder);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">给mMediaPlayer添加预览的SurfaceHolder</span>
setPlayVideo(mPath);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加播放视频的路径</span>
}</pre>
</div>
<h1><span style="color: rgba(0, 128, 128, 1)">添加需要播放的视频并且配置MediaPlayer</span></h1>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setPlayVideo(String path) {
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
mMediaPlayer.setDataSource(path);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置播放视频文件</span>
mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">缩放模式</span>
mMediaPlayer.setLooping(<span style="color: rgba(0, 0, 255, 1)">true</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置循环播放</span>
mMediaPlayer.prepareAsync();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">异步准备
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> mMediaPlayer.prepare();</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">同步准备,因为是同步在一些性能较差的设备上会导致UI卡顿</span>
mMediaPlayer.setOnPreparedListener(<span style="color: rgba(0, 0, 255, 1)">new</span> MediaPlayer.OnPreparedListener() { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">准备完成回调</span>
<span style="color: rgba(0, 0, 0, 1)"> @Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onPrepared(MediaPlayer mp) {</span><span style="color: rgba(0, 0, 0, 1)">
mp.start();<span style="color: rgba(0, 128, 0, 1)">//启动<span style="color: rgba(0, 128, 0, 1)">播放视频</span></span>
}
});
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (IOException e) {
e.printStackTrace();
}
}</span></pre>
</div>
<pre class="highlighter-hljs" data-dark-theme="true"><code>setPlayVideo方法,在surfaceCreated接口回调方法里执行即可.上面已经有写就不在重复交代了</code></pre>
<h1><span style="color: rgba(0, 128, 128, 1)">播放视频</span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> startPlay(){
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">mMediaPlayer.isPlaying()){ <span style="color: rgba(0, 128, 0, 1)">//<span style="color: rgba(0, 128, 0, 1)">判断视频是否在播放</span></span>
mMediaPlayer.start();
}
}</span></pre>
</div>
<h1><span style="color: rgba(0, 128, 128, 1)">暂停视频</span></h1>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> pausePlay(){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
}
}</span></pre>
</div>
<h1><span style="color: rgba(0, 128, 128, 1)">停止视频</span></h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> stopPlay(){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
}
}</span></pre>
</div>
<h1><span style="color: rgba(0, 128, 128, 1)">释放内存</span></h1>
<p>这是必要的,因为MediaPlayer底层是运行C++的函数方法.不要使用后,必需释放内存</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">@Override
</span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onDestroy() {
</span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onDestroy();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (mMediaPlayer != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
}
mMediaPlayer.release();
mMediaPlayer </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
}</span></pre>
</div>
<p> </p>
<div>
<div>
<h1><span style="color: rgba(0, 128, 128, 1)">API总汇</span></h1>
<ul>
<li><strong>void setDataSource(String path) 通过一个具体的路径来设置MediaPlayer的数据源,path可以是本地的一个路径,也可以是一个网络路径</strong></li>
<li><strong>void setDataSource(Context context, Uri uri) 通过给定的Uri来设置MediaPlayer的数据源,这里的Uri可以是网络路径或是一个ContentProvider的Uri。</strong></li>
<li><strong>void setDataSource(MediaDataSource dataSource) 通过提供的MediaDataSource来设置数据源</strong></li>
<li><strong>void setDataSource(FileDescriptor fd) 通过文件描述符FileDescriptor来设置数据源</strong></li>
<li><strong>int getCurrentPosition() 获取当前播放的位置</strong></li>
<li><strong>int getAudioSessionId() 返回音频的session ID</strong></li>
<li><strong>int getDuration() 得到文件的时间</strong></li>
<li><strong>TrackInfo[] getTrackInfo() 返回一个track信息的数组</strong></li>
<li><strong>boolean isLooping () 是否循环播放</strong></li>
<li><strong>boolean isPlaying() 是否正在播放</strong></li>
<li><strong>void pause () 暂停</strong></li>
<li><strong>void start () 开始</strong></li>
<li><strong>void stop () 停止</strong></li>
<li><strong>void prepare() 同步的方式装载流媒体文件。</strong></li>
<li><strong>void prepareAsync() 异步的方式装载流媒体文件。</strong></li>
<li><strong>void reset() 重置MediaPlayer至未初始化状态。</strong></li>
<li><strong>void release () 回收流媒体资源。</strong></li>
<li><strong>void seekTo(int msec) 指定播放的位置(以毫秒为单位的时间)</strong></li>
<li><strong>void setAudioStreamType(int streamtype) 指定流媒体类型</strong></li>
<li><strong>void setLooping(boolean looping) 设置是否单曲循环</strong></li>
<li><strong>void setNextMediaPlayer(MediaPlayer next) 当 当前这个MediaPlayer播放完毕后,MediaPlayer next开始播放</strong></li>
<li><strong>void setWakeMode(Context context, int mode):设置CPU唤醒的状态。</strong></li>
<li><strong>setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) 网络流媒体的缓冲变化时回调</strong></li>
<li><strong>setOnCompletionListener(MediaPlayer.OnCompletionListener listener) 网络流媒体播放结束时回调</strong></li>
<li><strong>setOnErrorListener(MediaPlayer.OnErrorListener listener) 发生错误时回调 </strong></li>
<li><strong>setOnPreparedListener(MediaPlayer.OnPreparedListener listener):当装载流媒体完毕的时候回调。</strong></li>
<li><strong>setOnInfoListener(OnInfoListener l)</strong> <strong>信息监听</strong></li>
</ul>
</div>
</div>
<p> </p>
<div class="cnblogs_code">
<pre> mMediaPlayer.setOnInfoListener(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> MediaPlayer.OnInfoListener() {
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">boolean</span> onInfo(MediaPlayer mp, <span style="color: rgba(0, 0, 255, 1)">int</span> what, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> extra) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">what 对应返回的值如下
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_UNKNOWN = 1;媒体信息未知
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; 媒体信息视频跟踪滞后
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; 媒体信息\视频渲染\开始
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_BUFFERING_START = 701; 媒体信息缓冲启动
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_BUFFERING_END = 702; 媒体信息缓冲结束
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_NETWORK_BANDWIDTH = 703; 媒体信息网络带宽(703)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; 媒体-信息-坏-交错
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_NOT_SEEKABLE = 801; 媒体信息找不到
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_METADATA_UPDATE = 802; 媒体信息元数据更新
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; 媒体信息不支持字幕
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; 媒体信息字幕超时</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
}
});</span></pre>
</div>
<p> </p>
<p> </p>
<h1> </h1>
<h1><span style="color: rgba(0, 128, 128, 1)">贴心周到,贴全demo代码,给你查缺补漏</span></h1>
<p><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">xml文件</span></span></p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)"><?</span><span style="color: rgba(255, 0, 255, 1)">xml version="1.0" encoding="utf-8"</span><span style="color: rgba(0, 0, 255, 1)">?></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">androidx.constraintlayout.widget.ConstraintLayout </span><span style="color: rgba(255, 0, 0, 1)">xmlns:android</span><span style="color: rgba(0, 0, 255, 1)">="http://schemas.android.com/apk/res/android"</span><span style="color: rgba(255, 0, 0, 1)">
xmlns:app</span><span style="color: rgba(0, 0, 255, 1)">="http://schemas.android.com/apk/res-auto"</span><span style="color: rgba(255, 0, 0, 1)">
xmlns:tools</span><span style="color: rgba(0, 0, 255, 1)">="http://schemas.android.com/tools"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="match_parent"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="match_parent"</span><span style="color: rgba(255, 0, 0, 1)">
android:fitsSystemWindows</span><span style="color: rgba(0, 0, 255, 1)">="true"</span><span style="color: rgba(255, 0, 0, 1)">
android:keepScreenOn</span><span style="color: rgba(0, 0, 255, 1)">="true"</span><span style="color: rgba(255, 0, 0, 1)">
android:background</span><span style="color: rgba(0, 0, 255, 1)">="@color/colorBlack1"</span><span style="color: rgba(255, 0, 0, 1)">
tools:context</span><span style="color: rgba(0, 0, 255, 1)">=".work.share.VideoPlayActivity"</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">SurfaceView
</span><span style="color: rgba(255, 0, 0, 1)">android:id</span><span style="color: rgba(0, 0, 255, 1)">="@+id/video_play_surfaceview"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="wrap_content"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="wrap_content"</span><span style="color: rgba(255, 0, 0, 1)">
app:layout_constraintHorizontal_bias</span><span style="color: rgba(0, 0, 255, 1)">="0.5"</span><span style="color: rgba(255, 0, 0, 1)">
app:layout_constraintVertical_bias</span><span style="color: rgba(0, 0, 255, 1)">="0.5"</span><span style="color: rgba(255, 0, 0, 1)">
app:layout_constraintTop_toTopOf</span><span style="color: rgba(0, 0, 255, 1)">="parent"</span><span style="color: rgba(255, 0, 0, 1)">
app:layout_constraintBottom_toBottomOf</span><span style="color: rgba(0, 0, 255, 1)">="parent"</span><span style="color: rgba(255, 0, 0, 1)">
app:layout_constraintLeft_toLeftOf</span><span style="color: rgba(0, 0, 255, 1)">="parent"</span><span style="color: rgba(255, 0, 0, 1)">
app:layout_constraintRight_toRightOf</span><span style="color: rgba(0, 0, 255, 1)">="parent"</span><span style="color: rgba(0, 0, 255, 1)">/></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">ImageView
</span><span style="color: rgba(255, 0, 0, 1)">android:id</span><span style="color: rgba(0, 0, 255, 1)">="@+id/start_and_stop"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="wrap_content"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="wrap_content"</span><span style="color: rgba(255, 0, 0, 1)">
android:src</span><span style="color: rgba(0, 0, 255, 1)">="@mipmap/ic_start"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_marginBottom</span><span style="color: rgba(0, 0, 255, 1)">="50dp"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_marginLeft</span><span style="color: rgba(0, 0, 255, 1)">="20dp"</span><span style="color: rgba(255, 0, 0, 1)">
app:layout_constraintLeft_toLeftOf</span><span style="color: rgba(0, 0, 255, 1)">="parent"</span><span style="color: rgba(255, 0, 0, 1)">
app:layout_constraintBottom_toBottomOf</span><span style="color: rgba(0, 0, 255, 1)">="parent"</span> <span style="color: rgba(0, 0, 255, 1)">/></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">androidx.constraintlayout.widget.ConstraintLayout</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
</div>
<p> </p>
<p>activity</p>
<p> </p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> androidx.constraintlayout.widget.ConstraintLayout;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.content.pm.ActivityInfo;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.media.MediaPlayer;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.os.Bundle;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.util.Log;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.view.SurfaceHolder;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.view.SurfaceView;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.view.View;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.widget.ImageView;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> com.yt.kangaroo.R;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> com.yt.kangaroo.app.BaseActivity;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.io.File;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.io.IOException;
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
*@content:视频播放activity
*@time:2019-6-13
*@build:
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> VideoPlayActivity <span style="color: rgba(0, 0, 255, 1)">extends</span> BaseActivity <span style="color: rgba(0, 0, 255, 1)">implements</span><span style="color: rgba(0, 0, 0, 1)"> View.OnClickListener {
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String TAG = VideoPlayActivity.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">.getSimpleName();
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> SurfaceView mVideoPlaySurfaceview;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> ImageView mStartAndStop;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> MediaPlayer mMediaPlayer;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String mPath;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">boolean</span> isInitFinish = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> SurfaceHolder mSurfaceHolder;
@Override
</span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onCreate(Bundle savedInstanceState) {
</span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onCreate(savedInstanceState);
setOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
File file </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> File(getExternalCacheDir(), "demo.mp4"<span style="color: rgba(0, 0, 0, 1)">);
mPath </span>=<span style="color: rgba(0, 0, 0, 1)"> file.getAbsolutePath();
initMediaPalyer();
initSurfaceviewStateListener();
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onPause() {
</span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onPause();
pausePlay();
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getLayout() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> R.layout.activity_video_play;
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> initView() {
mVideoPlaySurfaceview </span>=<span style="color: rgba(0, 0, 0, 1)"> findViewById(R.id.video_play_surfaceview);
mStartAndStop </span>=<span style="color: rgba(0, 0, 0, 1)"> findViewById(R.id.start_and_stop);
mStartAndStop.setOnClickListener(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">);
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onClick(View v) {
</span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (v.getId()) {
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> R.id.start_and_stop:
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (mMediaPlayer.isPlaying()) {
pausePlay();
mStartAndStop.setImageResource(R.mipmap.ic_start);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
startPlay();
mStartAndStop.setImageResource(R.mipmap.ic_stop);
}
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> initSurfaceviewStateListener() {
mSurfaceHolder </span>=<span style="color: rgba(0, 0, 0, 1)"> mVideoPlaySurfaceview.getHolder();
mSurfaceHolder.addCallback(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SurfaceHolder.Callback() {
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> surfaceCreated(SurfaceHolder holder) {
mMediaPlayer.setDisplay(holder);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">给mMediaPlayer添加预览的SurfaceHolder</span>
setPlayVideo(mPath);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加播放视频的路径</span>
<span style="color: rgba(0, 0, 0, 1)"> }
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> surfaceChanged(SurfaceHolder holder, <span style="color: rgba(0, 0, 255, 1)">int</span> format, <span style="color: rgba(0, 0, 255, 1)">int</span> width, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> height) {
Log.e(TAG, </span>"surfaceChanged触发: width=" + width + "height" +<span style="color: rgba(0, 0, 0, 1)"> height);
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> surfaceDestroyed(SurfaceHolder holder) {
}
});
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> initMediaPalyer() {
mMediaPlayer </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> MediaPlayer();
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setPlayVideo(String path) {
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
mMediaPlayer.setDataSource(path);</span><span style="color: rgba(0, 128, 0, 1)">//
</span> mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">缩放模式</span>
mMediaPlayer.setLooping(<span style="color: rgba(0, 0, 255, 1)">true</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置循环播放</span>
mMediaPlayer.prepareAsync();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">异步准备
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> mMediaPlayer.prepare();</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">同步准备,因为是同步在一些性能较差的设备上会导致UI卡顿</span>
mMediaPlayer.setOnPreparedListener(<span style="color: rgba(0, 0, 255, 1)">new</span> MediaPlayer.OnPreparedListener() { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">准备完成回调</span>
<span style="color: rgba(0, 0, 0, 1)"> @Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onPrepared(MediaPlayer mp) {
isInitFinish </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
mp.start();
}
});
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (IOException e) {
e.printStackTrace();
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> startPlay(){
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">mMediaPlayer.isPlaying()){
mMediaPlayer.start();
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> stopPlay(){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> pausePlay(){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> seekTo(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> time){
mMediaPlayer.seekTo(time);
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onDestroy() {
</span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onDestroy();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (mMediaPlayer != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
}
mMediaPlayer.release();
mMediaPlayer </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
}</span></pre>
</div>
<p> </p>
<p><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">end</span></span></p>
</div>
<div id="MySignature" role="contentinfo">
<div style="text-align: center">
<p style="color:orange;font-size:16px;" >本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/11019662.html </p>
<div style="color:orange;font-size:16px;">本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。 </div>
</div><br><br>
来源:https://www.cnblogs.com/guanxinjing/p/11019662.html
頁:
[1]