完成《Android实现录像功能》和《Android实现选择视频功能》后,已经实现了神马笔记插入视频的功能,接下来完成视频笔记的最后一个功能——播放。
播放视频笔记中的视频。
播放本地视频可以使用VideoView
和MediaPlayer + SurfaceView
两种方式。
目前VideoView
已经足够满足要求,因此采用VideoView
方式。
设置视频路径setVideoURI()
后,调用start()
方法即可播放视频。
VideoItem item = this.getItem();
if (item == null) {
return;
}
if (!isReady) {
videoView.setVideoURI(item.getUri());
isReady = true;
}
{
videoView.start();
actionBtn.setVisibility(View.INVISIBLE);
// photoView.setVisibility(View.INVISIBLE); // when rendering start, make it invisible
videoView.setVisibility(View.VISIBLE);
}
{
item.setPlaying(true);
}
调用pause()
接口,暂停播放。
VideoItem item = this.getItem();
if (item == null) {
return;
}
if (videoView.isPlaying()) {
videoView.pause();
actionBtn.setVisibility(View.VISIBLE);
}
释放资源并调整界面。
VideoItem item = this.getItem();
if (item != null) {
item.setPlaying(false);
}
{
actionBtn.setVisibility(View.VISIBLE);
photoView.setVisibility(View.VISIBLE);
// videoView.setVisibility(View.INVISIBLE); // keep it visible to avoid black slash
}
{
videoView.stopPlayback();
this.isReady = false;
}
VideoView
在detach时,会释放MediaPlayer
,不进行处理的话会显示黑屏。
因此需要调整界面。
public void surfaceDestroyed(SurfaceHolder holder)
{
// after we return from this we can't use the surface any more
mSurfaceHolder = null;
if (mMediaController != null) mMediaController.hide();
release(true);
}
super.onViewDetachedFromWindow();
VideoItem item = this.getItem();
if (item != null) {
item.setPlaying(false);
}
{
actionBtn.setVisibility(View.VISIBLE);
photoView.setVisibility(View.VISIBLE);
videoView.setVisibility(View.INVISIBLE);
}
{
videoView.stopPlayback();
this.isReady = false;
}
Activity切换到后台时,同样会释放MediaPlayer
,因此需要调整界面。
播放单个视屏时,需要处理用户播放及暂停视频,以及视频播放结束、Detach事件、onStop事件等事件。
Android支持同时播放多个视频,使用多个VideoView
可以同时播放多个视频。
神马笔记对视频播放进行了显示,同一个时间只能播放一个视频。
因此,播放新视频的同时,停止上一个视频的播放。
public void setPlayingItem(ChatItem item, boolean stopPrevious) {
if (playingItem == item) {
return;
}
ChatItem previous = playingItem;
this.playingItem = item;
if (previous != null && stopPrevious) {
int position = previous.getParent().indexOf(previous);
recyclerView.getAdapter().notifyItemChanged(position);
ChatViewHolder holder = ChatViewHolderUtils.find(recyclerView, previous);
if (holder != null) {
holder.stop();
}
}
}
Android使用多个MediaPlayer
可以同时播放视频和音频。
同样的,神马笔记对此进行了限制,或者播放视频,或者播放音频,二选一。
public void setPlaying(boolean value) {
VideoHelper videoHelper = getVideoHelper();
if (value) {
// stop audio
{
parent.getTapeHelper().stop();
parent.getTapeHelper().resetSpeaker();
}
{
videoHelper.setPlayingItem(this, true);
}
} else {
if (isPlaying()) {
// reset speaker
{
parent.getTapeHelper().setSpeakerOn(parent.getTapeHelper().isSpeakerOn(), true);
}
{
videoHelper.setPlayingItem(null, false);
}
}
}
}
public void start() {
{
TapeHelper tapeHelper = getTapeHelper();
tapeHelper.setSpeakerOn(tapeHelper.isSpeakerOn(), true);
tapeHelper.setWakeLock(true);
tapeHelper.setScreenOn(true);
}
{
parent.getVideoHelper().stop();
}
{
AudioPlayer player = this.getAudioPlayer();
player.setTarget(this.getFile());
player.start();
}
}
播放音频时,神马笔记允许选择听筒或者扬声器进行输出。
但播放视频只使用扬声器。
Android允许录音和播放视频同时进行。
同样的,神马笔记对此进行了限制。
同样的,二选一。
void requestTape() {
this.tapeHelper.stop();
this.videoHelper.stop();
this.tapeHelper.resetSpeaker();
PermissionHelper helper = new PermissionHelper(getActivity());
helper.setPermission(Manifest.permission.RECORD_AUDIO);
final boolean isGranted = helper.isGranted();
PermissionHelper.OnPermissionListener consumer = (h) -> {
bottomBar.chatBar.setVisibility(View.INVISIBLE);
popupTape.show(isGranted);
};
String requestMsg = "请允许录制音频,以发送语音。";
String deniedMsg = "请在「权限管理」,设置允许「麦克风」,以发送语音。";
helper.setRequestMessage(requestMsg);
helper.setDeniedMessage(deniedMsg);
helper.setOnPermissionListener(consumer);
helper.request();
}
首先,我们处理了单个视频的播放,允许用户播放及暂停,然后处理视频播放结束后,用户可以重新开始播放,并且处理了detach和onStop两个事件。
接下来,处理多个视频播放,对此进行了限制,同一时间只能播放一个视频。
然后,处理视屏和音频播放问题,同一时间只能播放一种。
再来,处理扬声器问题,播放视频时,只会将音频输出到扬声器。
最后,处理视频和录音的问题,同样是二选一。
分类 | 关系 | 说明 |
---|---|---|
视频 | 单个 | 处理用户播放及暂停,并且处理结束事件、detach事件和onStop事件。 |
多个 | 一次只允许播放一个视频。 | |
相关 | 音频 | 视频和音频,二选一。 |
扬声器 | 只输出到扬声器,不能使用听筒。 | |
录音 | 视频和录音,二选一。 |
提交视频笔记版本测试,顺利的话,明天就能发布。
须菩提。
菩萨应如是布施。不住于相。
何以故。
若菩萨不住相布施。
其福德不可思量。