Android SurfaceView+MediaPlayer制作播放暂停停止

本文详细讨论了Android中使用SurfaceView+MediaPlayer实现播放、暂停和停止操作时遇到的问题及解决方案,特别是针对Activity生命周期的处理。分析了MediaPlayer在不同状态下的行为,包括错误状态的恢复、播放状态的控制以及生命周期的管理。文中还提到了如何处理暂停后返回应用导致的播放异常问题,并提供了相应的代码示例。
摘要由CSDN通过智能技术生成

这个播放的坑实在是多
其实网上也有很多这种demo,但是我运行之后,点击home,在回到应用发现播放异常,针对此现象,才决定写这篇文章,并重写了一个demo。
得自己控制好视频播放的声明周期
先上一张官网的生命周期图片
这里写图片描述
1、带单箭头的表示同步方法,双箭头的代表异步方法。
2、当一个MediaPlayer对象刚刚使用new创建,或者reset()被调用后,它处于Idle状态; 在release()被调用后,它处于End状态。
3、reset()方法调用后,新构造的MediaPlayer对象和MediaPlayer对象之间存在细微但重要的区别。

getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioAttributes(AudioAttributes), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(long, int), prepare() or prepareAsync()

在空闲状态下(Idle),对于一个新的MediaPlayer构造对象,如果您监听了OnErrorListener.onError()方法,那么将不会回调。但是对于一个调用了reset方法后的MediaPlayer对象(此时也属于Idle状态),当调用了上面的方法,就会在OnErrorListener.onError()方法回调。
4、一旦MediaPlayer对象不再被使用,立即调用release(),一旦MediaPlayer对象处于End状态,就不能再使用它,并且无法将其返回到任何其他状态。
每当应用程序的Activity暂停(onPause()或停止它的onStop()方法被调用)时,应该调用此方法来释放MediaPlayer对象。
5、使用new MediaPlayer时,处于Idle状态,而使用create这个重载方法创建对象时,直接处于Prepared状态。
6、可以创建setOnErrorListener监听观察播放期间的一切错误。
7、当进入错误状态可以调用reset,重新回复Idle状态。
8、调用

setDataSource(FileDescriptor)或setDataSource(String)或setDataSource(Context,Uri)或setDataSource(FileDescriptor,long,long)setDataSource(MediaDataSource)

将处于空闲状态的MediaPlayer对象转换为Initialized状态。
如果在任何其他状态下调用setDataSource(),则会引发IllegalStateException。
9、可以调用prepare()方法,该方法返回就进入Prepared状态。或者调用prepareAsync,当设置了setOnPreparedListener监听时,在onPrepared方法中,会将MediaPlayer置为Prepared状态。
10、要开始播放,必须调用start()。在start()成功返回后,MediaPlayer对象处于Started状态。可以调用isPlaying()来测试MediaPlayer对象是否处于Started状态。
调用start()对已处于Started状态的MediaPlayer对象没有影响。
调用start()以恢复已暂停的MediaPlayer对象的播放,并且恢复的播放位置与暂停的位置相同。当对start()的调用返回时,暂停的MediaPlayer对象将返回到Started状态。
11、可以调用pause()方法对处于paused状态
调用pause()对已处于暂停状态的MediaPlayer对象没有影响。
12、调用stop()将停止播放,并使MediaPlayer处于Started,Paused,Prepared或PlaybackCompleted状态进入停止状态。
一旦处于停止状态,直到调用prepare()或prepareAsync()以再次将MediaPlayer对象设置为Prepared状态,才能开始播放。
13、seekTo(long,int)可以在其他状态下调用,例如Prepared,Paused和PlaybackCompleted状态。当在这些状态下调用seekTo(long,int)时,如果流有视频并且请求的位置有效,则将显示一个视频帧。
此外,可以通过调用getCurrentPosition()来获取当前的实际播放位置,这对于需要跟踪播放进度的音乐播放器等应用程序很有帮助。
14、当播放到达流尾时,播放完成。
如果使用setLooping(boolean)将循环模式设置为true,则MediaPlayer对象应保持在Started状态。
如果循环模式设置为false,则如果通过setOnCompletionListener(OnCompletionListener)事先注册了OnCompletionListener,则播放器引擎将调用用户提供的回调方法OnCompletion.onCompletion()。调用回调信号表明对象现在处于PlaybackCompleted状态。
在PlaybackCompleted状态下,调用start()可以从音频/视频源的开头重新开始播放。

这里写图片描述

其实网上也有很多这种demo,但是我运行之后,点击home,在回到应用发现播放异常,针对此现象,才决定写这篇文章。

Demo:

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

import java.io.IOException;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, MediaPlayer.OnInfoListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener, MediaPlayer.OnSeekCompleteListener, View.OnClickListener<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值