android视频播放实现
1. 安卓视频播放(阿里云视频点播播放器SDK+SurfaceView)
本篇文章讲述使用阿里云视频视频播放sdk中的高级播放器加上SurfaceView实现,采用id+STS方法进行视频播放。
流程:用户App获取STS凭证 -> 服务端下发STS凭证 -> 用户上传视频并获取vid -> 服务端获取STS凭证 -> 将STS凭证下发给客户端 -> 完成视频播放。
请看阿里云文档=========》》》》》》 阿里云-高级播放器Android使用说明
接下来我们来看一下安卓给我们提供的手势控制类
接口
setOnTouchListener(this);
其中定义了四种状态 NONE = 0, VOLUME = 1, BRIGHTNESS = 2, FF_REW = 3;
接下来我们来看一下我们自定义的SurfaceViewOnGestureListener继承 GestureDetector.SimpleOnGestureListener主要用到了
onDown(MotionEvent e)
onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)两个方法
a.在onDown的时候把状态设置NONE
b.判断横向滑动的距离大于纵向滑动的距离,就把模式赋值为快进和后退
c.在onScroll中进行状态赋值,根据滑动的距离,如果按下的点在屏幕的左半部分就吧状态设置为调节亮度BRIGHTNESS,如果在右半部分就是调节音量
d.各种情况调用各自的接口方法
快进和后退,我们需要知道的就是我们滑动的距离如何与视频的长度关联起来。
那么咱们就可以把视频的总长度与屏幕的总长度相比,这样就能知道你手指滑动的距离占视频的多少了。
我们可以通过 l = ration / mySurfaceView.getWidth();来获得这个比例,然后用当前的进度加上指滑动的距离占视频的长度就是要播放的视频位置
抬起点的x坐标与按下点的X坐标所得的距离,大于0是快进,小于零是后退。
系统的音量有很多,包括通话音量值,系统铃声值,音乐音量值,闹铃音量值,等等吧。
做一下笔记以备以后用到
视频播放我们用的是音乐音量值,同样的道理,我们需要把音量和高度进行关联,我们可以控件的高度闭上最大音量得出比例后就可以知道你滑动的距离占音量的多少了。
这里有个注意点就是activity是当前的这个界面,设置的是当前的界面,离开这个界面后就不管用了。
相同的道理和滑动调节音量一样也是获得屏幕的高度比上最大的亮度,然后计算滑动的距离转换成亮度是多少。(这里不多讲了)
为什么会出现黑屏,就是按Home键再点App回来后,只有声音没有图片的问题,因为我们用的是SurfaceView,每次点击Home键时会销毁这个SurfaceView,再回来时又会重新创建,这样我们的阿里云播放器与SurfaceView就没有绑定了,画面就没有了。
这样我们需要 给surfaceView添加mySurfaceView.getHolder().addCallback(this);
我们在按home键的时候会走surfaceDestroyed。这样,我们就可以在这里做一个标识,让他暂停,然后再回来的时候就会走surfaceCreated,判断标识,然后进行处理就可以了。切记一定要重新让aliyunVodPlayer与SurfaceView进行关联,这样才能有画面也有声音。
由于我们的视频在阿里云的服务器上存着,访问阿里云的服务器需要临时凭证,我们通过STS来获取Token,但是这个Token是有时间限制,正好阿里云的播放器给我们提供了播放视频出错时候的回调接口,我们只需要在这里面进行重新请求Token就可以了
2. js android端实现视频自动播放
在安卓手机上,使用video播放视频有个问题,video控件层级会永远在顶层,不利于视频互动H5开发,而IOS手机上不会有此问题。
<video src="http://xxx.mp4" x5-video-player-type="h5"/>
x5-video-player-type="h5" 只适用于微信浏览器
注意:
1.jsmpeg 需要将视频转为.ts的文件
先安装ffmpeg,然后执行以下命令,将mp4格式的文件转成 .ts(用命令行转的才能正常播放)
ffmpeg -i video.mp4 -f mpegts -codec:v mpeg1video -codec:a mp2 out.ts(文件的路径不太好找,建议全局搜索一下)
2.安卓上使用jsmpeg插件渲染canvas,ios上正常使用video并加入隐藏控制条等设置
3. http://hf-app.oss-cn-hangzhou.aliyuncs.com/public/html/jsmpeg.js 请使用此js,原作者的js没有回调设置
4. https://github.com/phoboslab/jsmpeg 原作者github地址
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSMpegPlayer</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0">
<style>
html,body{
padding: 0;
margin: 0;
}
.msg-wrap{
position: fixed;
top: 0;
left: 0;
background: #fff;
border: 1px solid #000;
}
.video-wrap{
width: 100%;
display: none;
}
</style>
</head>
<body>
<video class="video-wrap" id="video-ios" x5-playsinline webkit-playsinline playsinline src="1_BG_4s_2.mp4"></video>
<canvas class="video-wrap" id="video-android"></canvas>
<div class="msg-wrap" id="msgTxt">loading...</div>
<script src="http://hf-app.oss-cn-hangzhou.aliyuncs.com/public/html/jsmpeg.js"></script>
<script>
var msgTxt = document.getElementById('msgTxt');
var video = document.getElementById('video-ios');
var canvas = document.getElementById('video-android');
//检测是否为非安卓浏览器并作处理
var check = !! navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
if(check){
msgTxt.innerHTML = "not Android mode"
video.style.display="block"
video.play()
//监听video加载完成
video.addEventListener("loadedmetadata",function(){
msgTxt.innerHTML = "not Android mode:videoPlaying"
})
//监听video播放结束
video.addEventListener("ended",function(){
msgTxt.innerHTML = "not Android mode:videoEnd"
})
}else{
// jsmpegPlay(canvas,'1_BG_4s_5.ts',startCallBack,playingCallBack,endCallBack)
jsmpegPlay(canvas,'out.ts',startCallBack,playingCallBack,endCallBack)
}
function jsmpegPlay(Vcanvas,vVideo,startFun,playingFun,endFun) {
var player = new JSMpeg.Player(
vVideo ,{
canvas: Vcanvas,
loop: false,
autoplay: true,
startSign: true,
startCallBack: startFun,
playingCallBack: playingFun,
endCallBack: endFun
});
}
//视频开始播放(即解码完成)执行
function startCallBack() {
msgTxt.innerHTML = "Android mode:videoPlaying"
canvas.style.display="block"
}
//视频播放进度
function playingCallBack(currentTime) {
// console.log(currentTime)
}
//视频播放完成执行
function endCallBack() {
msgTxt.innerHTML = "Android mode:videoEnd"
}
</script>
</body>
</html>
项目中遇到的坑,把使用方法记录一下
在线演示DOMO
JSMpegPlayer
https://github.com/xxfxx/android-video-autuplay github地址,欢迎小星星~~~
3. android如何实现视频的在线播放
vitamio
能播放绝大部分格式的视频,但是这个有点大,里面的so文件比较多,官方文档上说有瘦身的方法,我试过但是没成功,就一个用了vitamio
的小demo,打完包都10m了。在线视频的话如果在电脑浏览器上能直接播放的话,用这个都可以播的,也有缓冲。我们项目也有在线视频播放,原本也是准备用vitamio
的,但是太大了,打完包apk增加了10m,然后我就换成了universalvideoview
了,这个也可以在线播放,有缓冲效果,主要是打包后apk不大。如果你播放在线视频功能要求高,而且不在乎apk大小的话可以使用vitamio
,如果仅想实现在线播放的话建议universalvideoview
就够了!
4. Android实现视频播放的几种方式
Android提供了常见的视频编码,解码机制,使用Android自带的MediaPlayer,MediaController等类可以很方便的实现视频播放的功能。支持的视频格式有MP4和3GP等。这些多媒体数据可以来自于Android应用的资源文件,也可以来自于外部存储器上的文件,甚至可以是来自于网络上的文件流。
1、MediaController+VideoView实现方式
这种方式是最简单的实现方式。VideoView继承了SurfaceView同时实现了MediaPlayerControl接口,MediaController则是安卓封装的辅助控制器,带有暂停,播放,停止,进度条等控件。通过VideoView+MediaController可以很轻松的实现视频播放、停止、快进、快退等功能。
布局文件如下:
使用此实现方式的步骤:
1.加载指定的视频文件
2.建立VideoView和MediaController之间的关联,这样就不需要自己去控制视频的播放、暂停等。让MediaController控制即可。
3.VideoView获取焦点。
2、MediaPlayer+SurfaceView+自定义控制器
虽然VideoView的实现方式很简单,但是由于是自带的封装好的类,所以无论是播放器的大小、位置以及控制都不受我们控制。
这种实现方式步骤如下:
1.创建MediaPlayer对象,并让它加载指定的视频文件。可以是应用的资源文件、本地文件路径、或者URL。
2.在界面布局文件中定义SurfaceView组件,并为SurfaceView的SurfaceHolder添加Callback监听器。
3.调用MediaPlayer对象的setDisplay(SurfaceHolder sh)将所播放的视频图像输出到指定的SurfaceView组件。
4.调用MediaPlayer对象的prepareAsync()或prepare()方法装载流媒体文件
5.调用MediaPlayer对象的start()、stop()和pause()方法来控制视频的播放。
在实现第二步之前需要先给surfaceHolder设置一个callback,callback的3个回调函数如下:
3、MediaPlayer+SurfaceView+MediaController
第二种实现方式使用的是自定义控件,MediaPlayer+SurfaceView也可以使用系统自带的MediaController控制器。
使用这个方式实现,布局文件只需一个SurfaceView即可,其他的控件都交给MediaController控制器,布局文件如下:
实际过程中推荐大家使用B站的播放器ijkplayer非常好用!
5. Android短视频滑动播放(一)
本文主要介绍采用RecyclerView配合PagerSnapHelper实现短视频滑动播放内容。
主页布局文件定义RecyclerView,为RecyclerView建立对应适配器。
适配器条目中添加视频播放容器FrameLayout及封面ImageVIew.
PagerSnapHelper 结合 LinearLayoutManager 实现滑动管理,实现监听任务。
PagerSnapHelper can help achieve a similar behavior to
ViewPager. Set both RecyclerView and the items of the RecyclerView.Adapter to have android.view.ViewGroup.LayoutParams#MATCH_PARENT height and width and then attach PagerSnapHelper to the RecyclerView using #attachToRecyclerView(RecyclerView)}.
RecyclerView管理器为LinearLayoutManager 时,默认为纵向滑动,如果想采用横向滑动,就设置其滑动方向为RecyclerView.HORIZONTAL。同理,我们也可以这样采用setOrientation(RecyclerView.HORIZONTAL) 方法去改变滑动方向。
为RecyclerView 设置管理器PagerLayoutManager,设置其Adapter数据内容,进行封面展示,且此时会回调onPageInitComplete()方法,进行首个视频播放。对RecyclerView进行滑动,当页面滑动结束后,会先回调管理器中onPageRelease()方法,此时可对进行中播放器进行停止释放;然后,回调onPageSelected()方法,对选中页面内容进行展示播放。
当滑动后取消时,要进行判断当前位置,避免当前页视频停止或重复播放。
初始化播放器内容
开始播放视频内容,进行播放器视图加载
停止播放,移除视图
例子中采用了自定义空布局的播放器继承自GSY开源播放器,单纯进行视频播放,当然也可以采用其它的播放器饺子或者IjkPlayer等。
布局文件
简单的滑动播放这些就完成了,例子也只是仅仅提供了实现的方法和思路,供大家进行学习参考,实际使用中可以对其进一步地进行封装及处理,接下来也会补充一些滑动播放适配器的数据加载处理以及多布局内容展示等内容。
6. android手机如何播放mp4
android手机播放MP4视频文件步骤如下:
工具/材料:以小米6手机为例。
1、首先打开小米6手机,点击“小米视频”图标,如下图所示;
7. Android 使用MediaCodec实现视频的无缝切换
网络上面很多视频播放都是利用MediaPlayer+显示视图(SurfaceView、TextureView)进行本地或者网络视频的播放。那么利用MediaCodec对视频流进行硬解码的小伙伴该如何在不同的控件之间无缝切换呢?是不是TextureView的生命周期很难控制?
TextureView与SurfaceTexture构成了组合关系,可见SurfaceTexture的确是由TextureView给‘包办’了。在程序世界中,一个对象被‘包办’无非是指:
(1)这个对象什么时候被创建?
(2)这个对象如何被创建?
(3)这个对象的产生带来了哪些变化,或者说程序自从有了它有哪些不同?
(4)这个对象什么时候被销毁?
之所以对SurfaceTexture这个盯碰态对象要大动笔墨,因为它是整个显示框架的‘连接者’。
是不凯源是遇到过在播放视频返回后台再回来,发现TextureView显示视图是一片黑色?监听TextureView的生命周期你会发现,返回后台是调用了销毁方法的。那你就会问销毁之后岂不是有需要重新创建?重新创建会引来更多的问题,解码去也需要重新初始化。所以我们只能另寻他法,下面方法就是无缝切换的核心部吵腊分。
在销毁方法中我们注意,有一个返回参数。官方的解释如下
现在恍然大悟了吧,我们在销毁的时候返回false,并保存SurfaceTexture对象,然后从后台返回界面的时候在onSurfaceTextureAvailable()方法中,调用setSurfaceTexture(mSurfaceTexture)方法,这样就会恢复之前的画面了。
使用ItemTouchHelper轻松实现RecyclerView拖拽排序和滑动删除
源码地址: https://github.com/chezi008/VideoSurveillance