最近在做一款视频剪辑的app时,基本每个功能都会有视频播放的功能,所以利用MediaPlayer自下定义了一个播放器。下面简单分享下心得:
目录
1.明确需求
1)可以播放、暂停、快进、快退
2)快进、快退有2种方式,一种按钮点击,一种拖动条拖动。
3)播放音频时显示音频动画
4)播放完毕可选择是否显示重播按钮
5)播放时,视频不会有变形或者模糊。
6)当加载网络视频时
播放器有2种形式:
1.工具栏始终固定于显示区下面
上面的图例就是这种情况,这种情况一般用在裁剪视频时,为了防止工具栏遮挡显示区域。
2.工具栏浮于显示区上面
2.代码设计
模型构建
由上面的效果图,可以将自定义View划分成3个部分:播放显示区、工具栏、状态区。
上代码
下面我只说一下关键代码,其余的可以看源码。
1)定义自定义属性
<declare-styleable name="CZVideoView">
<attr name="sfvWidth" format="dimension" >
<enum name="fill_parent" value="-1" />
<!-- The view should be as big as its parent (minus padding).
Introduced in API Level 8. -->
<enum name="match_parent" value="-1" />
<!-- The view should be only big enough to enclose its content (plus padding). -->
<enum name="wrap_content" value="-2" />
</attr>
<attr name="sfvHeight" format="dimension" >
<enum name="fill_parent" value="-1" />
<!-- The view should be as big as its parent (minus padding).
Introduced in API Level 8. -->
<enum name="match_parent" value="-1" />
<!-- The view should be only big enough to enclose its content (plus padding). -->
<enum name="wrap_content" value="-2" />
</attr>
<attr name="toolMenuPosition">
<enum name="on" value="1" /> <!--表示ToolMenu在SufaceView的Z轴上方。-->
<enum name="below" value="2" /> <!--表示ToolMenu在SufaceView的下方。-->
</attr>
</declare-styleable>
2)初始化布局
根据自定义属性toolMenuPosition来加载不同形式的布局
if(PlayMenuController.TOOL_MENU_POSITION_ON == toolMenuPosition){
/**
* 注意{@link R.layout.cz_video_view_position_on}中的{@link surfaceView}的layout_width属性,在xml里,要定义为wrap_content,
* 如果定义成match_parent,会导致后面的resize失败。我也不知道原理是什么。TODO
*/
LayoutInflater.from(context).inflate(R.layout.cz_video_view_position_on, this, true);
}else if(PlayMenuController.TOOL_MENU_POSITION_BELOW == toolMenuPosition){
/**
* 注意{@link R.layout.cz_video_view_position_below}中的{@link surfaceView}的layout_width属性,在xml里,要定义为wrap_content,
* 如果定义成match_parent,会导致后面的resize失败。我也不知道原理是什么。TODO
*/
LayoutInflater.from(context).inflate(R.layout.cz_video_view_position_below, this, true);
playMenuController.setAutoHidePlayMenu(false);
}
动态创建状态区内部类StateView,和视频播放叠加。
3)视频大小适配
为防止视频变形,需要对surfaceView的大小进行适配。适配方案如下:
<1>获取当前surfaceView的宽高
<2>指定surfaceView新的宽高就是当前的宽高
<3>比较视频的宽度与高度
比较surfaceView的高度与视频的高度
如果surfaceView的高度 > 视频的高度,使surfaceView的高度等于视频的高度。(这样就保证视频虽然很小,但是不会被拉伸导致模糊。)
int sfvMeasuredHeight = surfaceView.getMeasuredHeight();
int sfvMeasuredWidth = surfaceView.getMeasuredWidth();
int sfvNewWidth = sfvMeasuredWidth,sfvNewHeight = sfvMeasuredHeight;
if(localSrc.getMediaType() == MediaDetailBean.MEDIA_TYPE_VIDEO){ //视频就要适配变形
//sfv比视频还高,sfv与视频同高
if(sfvMeasuredHeight > localSrc.getHeight()){
sfvNewHeight = localSrc.getHeight();
}
if(localSrc.getWidth() <= localSrc.getHeight()){
sfvNewWidth = (int) (1.0 * sfvNewHeight * localSrc.getWidth() / localSrc.getHeight());
}else{
sfvNewWidth = mWidth;
sfvNewHeight = (int) (1.0 * sfvNewWidth * localSrc.getHeight() / localSrc.getWidth());
}
}
resizeSurfaceView(sfvNewWidth, sfvNewHeight);
# 源码:
如有疑惑或者好的建议,或者想纠正作者的博文,请联系如下
公众号:微信公众号搜索“修符道人”或者扫描下方二维码
微信号:XinYi1349308479
QQ邮箱:1349308479@qq.com
0 条评论