Vitamio

   Vitamio好多人称之为万能播放器,顾名思义Vitamio最为明显的优势也被体现出来。Vitamio支持的格式很多。Vitamio是一款Android和ios平台的全能多媒体开发框架,它支持大部分的格式,支持流媒体,可以点播和直播音频和视频。经过这几天的学习,总结出来如下:
   我主要总结两大部分:
* 

Vitamio的使用、源码及注意点
*
在hbb项目中播放监控视频那块代码的逻辑问题
*
可能需要改进的地方

一、Vitamio的使用、源码及注意点
Vitamio 内部重写了的Android内部的一个播放视频的控件VideoView,在VideoView中重写了MediaPlayer,我们在使用是要使用Vitamio提供给我们的VideoView而不要去使用Android自带的VideoView。在源码中我们可以看到Vitamio在使用了重写的MediaPlayer, MediaPlayer 中去调用了相应的native方法(即lib中所包含的so里的c/c++方法)。系统自带的播放控件支持的格式少,Vitamio支持的格式多就是因为这些它们提供的so文件。当然,Vitamio重新去实现了播放控件,当然他们的播放流程肯定不会胡来滴。其中流程如这个链接图:https://img-my.csdn.net/uploads/201209/07/1346982074_9123.png
在使用Vitamio,我们只关注去VideoView即可,因为Vitamio给我们封装的挺好的,我们使用它们提供出来的方法就可以了。当然MediaPlayer我们也可以关注下呀,不过像一些错误,MediaPlayer抛出的错误,使用回调给了VideoView,VideoView又使用回调返回给了我们,这个在后面我们在去说。我这么说就是为了说明,我们只是使用的话,VideoView提供出来的方法就差不多。
Vitamio的API及常用的方法可以参考下面的网址:http://www.cnblogs.com/over140/category/409230.html
最简单的使用方法就是直接给VideoView设置你要播放的地址即可(就是这么的简单)。在设置过地址后Vitamio会自动去播放,在源码中可以看到,初始化代码写在try catch中,当初始化失败了,会回调错误给用户。
像最基本的方法如开始播放start()、暂停pause()等在这里就不提了。。。
我们或许对Vitamio给与我们的回调关心,也对,我们会从中得到许多的信息,以便于我们在应用逻辑的开发。经常使用的回调如下所示:
*
setOnPreparedListener

   当Vitamio准备好的时候进行回调,也就是播放了要。在这个时机我们才可以去获得视频等源的信息,比如时长,播放到了哪里,去指定播放的位置等
* 

setOnInfoListener

   当播放时信息会回调在这里,比如开始缓冲、缓冲结束、下载缓冲变化等。 其中回调中三个参数、一个是播放器、类型、额外的值


	* 

MediaPlayer.MEDIA_INFO_BUFFERING_START: 开始缓冲,我们可以在这里去暂停视频,或者去做其他操作(如提示)。
*
MediaPlayer.MEDIA_INFO_BUFFERING_END:缓冲结束,我们可以在这里去开始播放视频,或者去做其他操作(如…)。
*
MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:下载缓冲变化。其中额外的值就是我们的下载网速哦
*
setOnErrorListener

   错误信息都会从这里回调回来,该出的错误信息两个地方回调,第一是在VideoView 初始化的时候,第二是在MediaPlayer里


	* 

在VideoView中初始化失败时会回调,MediaPlayer.MEDIA_ERROR_UNKOWN, 额外值为0
*
MEDIA_ERROR_UNKNOWN:未知错误
*
MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:播放错误(一般视频播放比较慢或视频本身有问题会引发)
*
MEDIA_INFO_VIDEO_TRACK_LAGGING:视频过于复杂,无法解码:不能快速解码帧。此时可能只能正常播放音频
*
MEDIA_INFO_NOT_SEEKABLE: 媒体不支持Seek,例如直播流
*
MEDIA_ERROR_IO:文件不存在或错误,或网络不可访问错误
*
MEDIA_ERROR_MALFORMED:流不符合有关标准或文件的编码规范
*
setOnCompletionListener

   当视频播放结束后回调。
* 

setOnBufferingUpdateListener

   当缓冲buffer更新的时候回调

主要的源码的分析:
*
初始化时

release(false);
try {
mDuration = -1;
mCurrentBufferPercentage = 0;
mMediaPlayer = new MediaPlayer(mContext, mHardwareDecoder);
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mMediaPlayer.setOnInfoListener(mInfoListener);
mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener);
mMediaPlayer.setOnTimedTextListener(mTimedTextListener);
mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.setBufferSize(mBufSize);
mMediaPlayer.setVideoChroma(mVideoChroma == MediaPlayer.VIDEOCHROMA_RGB565 ? MediaPlayer.VIDEOCHROMA_RGB565 : MediaPlayer.VIDEOCHROMA_RGBA);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.prepareAsync();
mCurrentState = STATE_PREPARING;
attachMediaController();
} catch (IOException ex) {
Log.e("Unable to open content: " + mUri, ex);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
} catch (IllegalArgumentException ex) {
Log.e("Unable to open content: " + mUri, ex);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
}

   初始化,重新回到洁净的原点。注意在初始化错误的时候就会去回调一个错误。MEDIA_ERROR_UNKNOWN,未知错误
   其中源码我想讲的是为什么我们在简单使用的时候使用VideoView就可以了。大部分的代码原理都一样,我只拿一个例子说明。还拿错误的回调来说事。
   我们看下面的代码,在VideoView中有一个接口时MediaPlayer的回调接口,也有一个自己的回调接口。

private OnErrorListener mOnErrorListener;

mMediaPlayer.setOnErrorListener(mErrorListener);

private OnErrorListener mErrorListener = new OnErrorListener() {
public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
Log.d(“Error: %d, %d”, framework_err, impl_err);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
if (mMediaController != null)
mMediaController.hide();

if (mOnErrorListener != null) {
  if (mOnErrorListener.onError(mMediaPlayer, framework_err, impl_err))
    return true;
}

if (getWindowToken() != null) {
  int message = framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK ? getResources().getIdentifier("VideoView_error_text_invalid_progressive_playback", "string", mContext.getPackageName()): getResources().getIdentifier("VideoView_error_text_unknown", "string", mContext.getPackageName());

  new AlertDialog.Builder(mContext).setTitle(getResources().getIdentifier("VideoView_error_title", "string", mContext.getPackageName())).setMessage(message).setPositiveButton(getResources().getIdentifier("VideoView_error_button", "string", mContext.getPackageName()), new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
      if (mOnCompletionListener != null)
        mOnCompletionListener.onCompletion(mMediaPlayer);
    }
  }).setCancelable(false).show();
}
return true;

}
};

   看到了吗!VideoView可以说是一个中介哈,去接受MediaPlayer的回调然后再通过自己的回调给使用者。

注意点:
*
在使用Vitamio时记得targetSdkVersion=21, 如果设置的高的话Vitamio会抛异常哦。
*
Vitamio在播放完毕的回调不仅仅是在播放完毕的时候回调,在出错后也会走到播放完毕的那个回调里哦。

二、在hbb项目中播放监控视频那块代码的逻辑问题
*
在正在加载中,如果点击返回,只是让dialog消失,并没有让页面消失,而出现的白屏。

   解决方法:去监听dialog消失的回调,如果视频还没有播放,直接销毁界面即可。
* 

在代码中,设置了一个标识,去标识是否已经播放。在以前的代码中有两个逻辑错误。其一,如果要这个标识的话,我们也应该在OnPreparedListener 准备好的监听里去设置,二不应该在onInfoListener 里去设置,如果是在坏流的情况下也会走到onInfoListener 回调里。这次的视频一直监听不到坏流的原因也在这里。第二我们考虑下,我们完全没有必要去设置这个标识吗?当然在错误的回调里使用,这里我们可以使用VideoView给我们提供好的方法去获取是否已经在播放的。
*
在页面销毁的时候没有去销毁VideoView,这样话有安全隐患,要是内存泄露了呢!

三、可能需要改进地方

   在设置或地址后,Vitamio会去链接播放,如果一直没有加载成功的话,会一直在那里一直在那里。我想这个应该有一个超时时间的,但是在源码里没有找到相应的设置, 至少现在暂为发现。当然这个我们是可以自己去用另一个方法去解决,在加载视频使发一个延迟消息,比如15秒,15秒后判断是否在播放,如果播放了啥都不做,如果还没有播放,认为加载超时,提示用户。当然这个时间和改进需要产品的确认。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值