之前视频播放用的是原生的videoview,但存在加载慢,不支持https协议的问题,所以改用了ijkplayer来播放视频,先开始是ijkplyaer和surfaceview搭配使用,但由于surfaceview是新建了一个新的window,不能受到原本的view的一切属性约束,所以在viewpager中左右滑动很不灵敏,然后又换成了jikplayer和TextureView搭配来播放视频,TextureView具有原生view的一切属性,所以各方面操作都会好很多,建议大家使用TextureView的方案来做视频的播放,下面我贴下代码:
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import java.io.IOException;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
/**
* Created by wjj on 2018/11/12.
*/
public class IjkplayerVideoView_TextureView extends FrameLayout implements TextureView.SurfaceTextureListener {
public IjkplayerVideoView_TextureView(@NonNull Context context) {
super(context);
initVideoView(context);
}
public IjkplayerVideoView_TextureView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initVideoView(context);
}
public IjkplayerVideoView_TextureView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initVideoView(context);
}
@SuppressLint("NewApi")
public IjkplayerVideoView_TextureView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initVideoView(context);
}
/**
* 由ijkplayer提供,用于播放视频,需要给他传入一个surfaceView
*/
private IMediaPlayer mMediaPlayer = null;
/**
* 视频文件地址
*/
private String mPath = "";
private TextureView textureView;
private VideoPlayerListener listener;
private Context mContext;
private Surface surface;
private void initVideoView(Context context) {
mContext = context;
//获取焦点
// setFocusable(true);
}
/**
* 设置视频地址。
* 根据是否第一次播放视频,做不同的操作。
* @param path 视频地址
*/
public void setVideoPath(String path) {
if (TextUtils.equals("", mPath)) {
//如果是第一次播放视频,那就创建一个新的TextureView
mPath = path;
createTextureView();
} else {
//否则就直接load
mPath = path;
load();
}
}
/**
* 新建一个TextureView
*/
private void createTextureView() {
textureView = null;
textureView = new TextureView(getContext());
textureView.setSurfaceTextureListener(this);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
layoutParams.gravity = Gravity.CENTER;
textureView.setLayoutParams(layoutParams);
addView(textureView);
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int i, int i1) {
this.surface = new Surface(surface);
// surfaceTexture数据通道准备就绪,打开播放器
load();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
surface.release();
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
/**
* 加载视频
*/
private void load() {
//每次都要重新创建IMediaPlayer
createPlayer();
try {
mMediaPlayer.setDataSource(mPath);
mMediaPlayer.setLooping(true);
mMediaPlayer.setVolume(0f,0f);
} catch (IOException e) {
e.printStackTrace();
}
//给mediaPlayer设置视图
mMediaPlayer.setSurface(surface);
mMediaPlayer.prepareAsync();
}
/**
* 创建一个新的player
*/
private void createPlayer() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.setDisplay(null);
mMediaPlayer.release();
}
IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();
ijkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);
//开启硬解码
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
mMediaPlayer = ijkMediaPlayer;
if (listener != null) {
mMediaPlayer.setOnPreparedListener(listener);
mMediaPlayer.setOnInfoListener(listener);
mMediaPlayer.setOnSeekCompleteListener(listener);
mMediaPlayer.setOnBufferingUpdateListener(listener);
mMediaPlayer.setOnErrorListener(listener);
}
}
public void setListener(VideoPlayerListener listener) {
this.listener = listener;
if (mMediaPlayer != null) {
mMediaPlayer.setOnPreparedListener(listener);
}
}
/**
* -------======--------- 下面封装了一下控制视频的方法
*/
public void setVolume(float v1,float v2 ){
//关闭声音
if (mMediaPlayer!=null){
mMediaPlayer.setVolume(v1,v2);
}
}
public void start() {
if (mMediaPlayer != null) {
mMediaPlayer.start();
}
}
public void release() {
if (mMediaPlayer != null) {
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
public void pause() {
if (mMediaPlayer != null) {
mMediaPlayer.pause();
}
}
public void stop() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
}
}
public void reset() {
if (mMediaPlayer != null) {
mMediaPlayer.reset();
}
}
public void reCreate(){
if (mMediaPlayer == null) {
mMediaPlayer.reset();
}
}
public long getDuration() {
if (mMediaPlayer != null) {
return mMediaPlayer.getDuration();
} else {
return 0;
}
}
public long getCurrentPosition() {
if (mMediaPlayer != null) {
return mMediaPlayer.getCurrentPosition();
} else {
return 0;
}
}
public void seekTo(long l) {
if (mMediaPlayer != null) {
mMediaPlayer.seekTo(l);
}
}
}
布局中引入
<com.wj.widget.ijkplayerVideo.IjkplayerVideoView_TextureView
android:id="@+id/video_wallpaper_img2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
</com.wj.widget.ijkplayerVideo.IjkplayerVideoView_TextureView>
代码设置调用播放视频,我这里是在fragment里面调用的:
view.video_wallpaper_img2.setListener(object : VideoPlayerListener() {
override fun onSeekComplete(p0: IMediaPlayer?) {
}
override fun onInfo(p0: IMediaPlayer?, p1: Int, p2: Int): Boolean {
return false
}
override fun onVideoSizeChanged(p0: IMediaPlayer?, p1: Int, p2: Int, p3: Int, p4: Int) {
}
override fun onBufferingUpdate(p0: IMediaPlayer?, p1: Int) {
}
override fun onPrepared(mp: IMediaPlayer?) {
// 视频准备好播放了,但是他不会自动播放,需要手动让他开始。
mp?.start()
view.iv_wallpaper_video_preview.visibility = View.GONE
}
override fun onCompletion(p0: IMediaPlayer?) {
}
override fun onError(p0: IMediaPlayer?, p1: Int, p2: Int): Boolean {
return false
}
} )
// 缓存
var proxy: HttpProxyCacheServer = MyAPP.getProxy(acty!!)
//注意不能传入本地路径,本地的你还传进来干嘛。
var proxyUrl = proxy.getProxyUrl(url)
view.video_wallpaper_img2.setVideoPath(proxyUrl)
//关闭声音,这个看你的需求了
// view.video_wallpaper_img2.setVolume(0f, 0f)
这样就可以播放了,HttpProxyCacheServer视频缓存是用了一个库,需要在glide中引入这个库的依赖:
dependencies {
compile 'com.danikula:videocache:2.6.4'
}
关于HttpProxyCacheServer详细使用教程可以看这篇博客https://blog.csdn.net/wjj1996825/article/details/84562496