diff --git a/app/src/main/java/com/example/gsyvideoplayer/DetailPlayer.java b/app/src/main/java/com/example/gsyvideoplayer/DetailPlayer.java index 84b2a8546e1519943025efe0407084e2b74ec568..08a11961f5bd8903cc53e55e18cb07cc78b25523 100644 --- a/app/src/main/java/com/example/gsyvideoplayer/DetailPlayer.java +++ b/app/src/main/java/com/example/gsyvideoplayer/DetailPlayer.java @@ -10,6 +10,7 @@ import android.widget.ImageView; import android.widget.RelativeLayout; import com.example.gsyvideoplayer.listener.SampleListener; +import com.shuyu.gsyvideoplayer.GSYPreViewManager; import com.shuyu.gsyvideoplayer.GSYVideoPlayer; import com.shuyu.gsyvideoplayer.utils.OrientationUtils; @@ -42,7 +43,7 @@ public class DetailPlayer extends AppCompatActivity { ButterKnife.bind(this); String url = "http://baobab.wdjcdn.com/14564977406580.mp4"; - detailPlayer.setUp(url, true, null, "测试视频"); + detailPlayer.setUp(url, false, null, "测试视频"); //增加封面 ImageView imageView = new ImageView(this); @@ -136,6 +137,7 @@ public class DetailPlayer extends AppCompatActivity { protected void onDestroy() { super.onDestroy(); GSYVideoPlayer.releaseAllVideos(); + GSYPreViewManager.instance().releaseMediaPlayer(); if (orientationUtils != null) orientationUtils.releaseListener(); } diff --git a/gsyVideoPlayer/src/main/java/com/shuyu/gsyvideoplayer/GSYPreViewManager.java b/gsyVideoPlayer/src/main/java/com/shuyu/gsyvideoplayer/GSYPreViewManager.java new file mode 100644 index 0000000000000000000000000000000000000000..9d2599a96a63b6b91a837e38b9cce140add03953 --- /dev/null +++ b/gsyVideoPlayer/src/main/java/com/shuyu/gsyvideoplayer/GSYPreViewManager.java @@ -0,0 +1,146 @@ +package com.shuyu.gsyvideoplayer; + +import android.media.AudioManager; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; +import android.text.TextUtils; +import android.view.Surface; + +import com.shuyu.gsyvideoplayer.model.GSYModel; + +import java.io.IOException; +import java.util.Map; + +import tv.danmaku.ijk.media.player.AbstractMediaPlayer; +import tv.danmaku.ijk.media.player.IMediaPlayer; +import tv.danmaku.ijk.media.player.IjkMediaPlayer; + +/** + * Created by shuyu on 2016/12/11. + */ + +public class GSYPreViewManager implements IMediaPlayer.OnPreparedListener { + + public static String TAG = "GSYPreViewManager"; + + private static GSYPreViewManager videoManager; + + public static final int HANDLER_PREPARE = 0; + public static final int HANDLER_SETDISPLAY = 1; + public static final int HANDLER_RELEASE = 2; + + private IjkMediaPlayer mediaPlayer; + private HandlerThread mMediaHandlerThread; + private GSYPreViewManager.MediaHandler mMediaHandler; + + public static synchronized GSYPreViewManager instance() { + if (videoManager == null) { + videoManager = new GSYPreViewManager(); + } + return videoManager; + } + + public GSYPreViewManager() { + mediaPlayer = new IjkMediaPlayer(); + mMediaHandlerThread = new HandlerThread(TAG); + mMediaHandlerThread.start(); + mMediaHandler = new GSYPreViewManager.MediaHandler((mMediaHandlerThread.getLooper())); + } + + public class MediaHandler extends Handler { + public MediaHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what) { + case HANDLER_PREPARE: + initVideo(msg); + break; + case HANDLER_SETDISPLAY: + showDisplay(msg); + break; + case HANDLER_RELEASE: + if (mediaPlayer != null) { + mediaPlayer.release(); + } + break; + } + } + + } + + private void initVideo(Message msg) { + try { + mediaPlayer.release(); + + initIJKPlayer(msg); + + mediaPlayer.setOnPreparedListener(GSYPreViewManager.this); + mediaPlayer.setVolume(0, 0); + mediaPlayer.prepareAsync(); + + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void initIJKPlayer(Message msg) { + mediaPlayer = new IjkMediaPlayer(); + mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + try { + mediaPlayer.setDataSource(((GSYModel) msg.obj).getUrl(), ((GSYModel) msg.obj).getMapHeadData()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void showDisplay(Message msg) { + if (msg.obj == null && mediaPlayer != null) { + mediaPlayer.setSurface(null); + } else { + Surface holder = (Surface) msg.obj; + if (mediaPlayer != null && holder.isValid()) { + mediaPlayer.setSurface(holder); + } + } + } + + + @Override + public void onPrepared(IMediaPlayer mp) { + mp.pause(); + } + + public void prepare(final String url, final Map mapHeadData, boolean loop, float speed) { + if (TextUtils.isEmpty(url)) return; + Message msg = new Message(); + msg.what = HANDLER_PREPARE; + GSYModel fb = new GSYModel(url, mapHeadData, loop, speed); + msg.obj = fb; + mMediaHandler.sendMessage(msg); + } + + public void releaseMediaPlayer() { + Message msg = new Message(); + msg.what = HANDLER_RELEASE; + mMediaHandler.sendMessage(msg); + } + + public void setDisplay(Surface holder) { + Message msg = new Message(); + msg.what = HANDLER_SETDISPLAY; + msg.obj = holder; + mMediaHandler.sendMessage(msg); + } + + public IjkMediaPlayer getMediaPlayer() { + return mediaPlayer; + } + +} \ No newline at end of file diff --git a/gsyVideoPlayer/src/main/java/com/shuyu/gsyvideoplayer/video/CustomGSYVideoPlayer.java b/gsyVideoPlayer/src/main/java/com/shuyu/gsyvideoplayer/video/CustomGSYVideoPlayer.java index 9d34d88adfcc1e8b7eefb93f0847d335e58447d4..9d4232811a2e350283d9dd1f06ec4712014684d4 100644 --- a/gsyVideoPlayer/src/main/java/com/shuyu/gsyvideoplayer/video/CustomGSYVideoPlayer.java +++ b/gsyVideoPlayer/src/main/java/com/shuyu/gsyvideoplayer/video/CustomGSYVideoPlayer.java @@ -1,42 +1,29 @@ package com.shuyu.gsyvideoplayer.video; -import android.app.Activity; import android.content.Context; -import android.graphics.Bitmap; -import android.media.MediaMetadataRetriever; -import android.text.TextUtils; +import android.graphics.SurfaceTexture; +import android.os.Handler; import android.util.AttributeSet; -import android.widget.ImageView; +import android.view.Surface; +import android.view.TextureView; +import android.view.ViewGroup; import android.widget.RelativeLayout; import android.widget.SeekBar; -import com.shuyu.gsyvideoplayer.GSYVideoManager; -import com.shuyu.gsyvideoplayer.GSYVideoPlayer; +import com.shuyu.gsyvideoplayer.GSYPreViewManager; +import com.shuyu.gsyvideoplayer.GSYTextureView; import com.shuyu.gsyvideoplayer.R; import com.shuyu.gsyvideoplayer.utils.Debuger; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; - /** * Created by shuyu on 2016/12/10. */ public class CustomGSYVideoPlayer extends StandardGSYVideoPlayer { + private RelativeLayout mPreviewLayout; - private ImageView mSeekBarImage; - - private ShowSeekBarImageTimerTask mShowSeekBarImageTimerTask; - - private Timer mSeekBarImageTimer; - - //记录上一个进度图的位置,用于判断是否取数据 - private int mPreSeekPosition = -1; - - //记录进度图变化的帧图片图的偏移时间,避免太频繁进入 - private long mOffsetTime; + private GSYTextureView mPreviewTexture; //是否因为用户点击 private boolean mIsFromUser; @@ -53,7 +40,7 @@ public class CustomGSYVideoPlayer extends StandardGSYVideoPlayer { private void initView() { - mSeekBarImage = (ImageView) findViewById(R.id.seek_bar_image); + mPreviewLayout = (RelativeLayout) findViewById(R.id.preview_layout); } @Override @@ -61,30 +48,67 @@ public class CustomGSYVideoPlayer extends StandardGSYVideoPlayer { return R.layout.video_layout_custom; } + @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - super.onProgressChanged(seekBar, progress, fromUser); - if ((mCurrentState == GSYVideoPlayer.CURRENT_STATE_PLAYING - || mCurrentState == GSYVideoPlayer.CURRENT_STATE_PAUSE) - && GSYVideoManager.instance().getMediaPlayer() != null) { + protected void addTextureView() { + super.addTextureView(); + + if (mPreviewLayout.getChildCount() > 0) { + mPreviewLayout.removeAllViews(); + } + mPreviewTexture = null; + mPreviewTexture = new GSYTextureView(getContext()); + mPreviewTexture.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { + @Override + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + GSYPreViewManager.instance().setDisplay(new Surface(surface)); + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + + } + + @Override + public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { + GSYPreViewManager.instance().setDisplay(null); + return true; + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + + } + }); + mPreviewTexture.setRotation(mRotate); + + RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); + mPreviewLayout.addView(mPreviewTexture, layoutParams); + } + + @Override + protected void prepareVideo() { + GSYPreViewManager.instance().prepare(mUrl, mMapHeadData, mLooping, mSpeed); + super.prepareVideo(); + } + @Override + public void onProgressChanged(SeekBar seekBar, final int progress, boolean fromUser) { + super.onProgressChanged(seekBar, progress, fromUser); + if (fromUser) { int width = seekBar.getWidth(); int offset = (int) (width - (getResources().getDimension(R.dimen.seek_bar_image) / 2)) / 100 * progress; - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mSeekBarImage.getLayoutParams(); + RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mPreviewLayout.getLayoutParams(); layoutParams.leftMargin = offset; //设置帧预览图的显示位置 - mSeekBarImage.setLayoutParams(layoutParams); - - long currentTime = System.currentTimeMillis(); - - if (fromUser && (mPreSeekPosition == -1 || Math.abs(progress - mPreSeekPosition) > 2)) { - //开始预览帧小图 - startSeekBarImageTimer(seekBar.getProgress()); - mPreSeekPosition = progress; - mOffsetTime = currentTime; + mPreviewLayout.setLayoutParams(layoutParams); + if (GSYPreViewManager.instance().getMediaPlayer() != null && mHadPlay) { + int time = progress * getDuration() / 100; + Debuger.printfLog("SEEK TO " + time); + GSYPreViewManager.instance().getMediaPlayer().seekTo(time); } - } } @@ -92,18 +116,14 @@ public class CustomGSYVideoPlayer extends StandardGSYVideoPlayer { public void onStartTrackingTouch(SeekBar seekBar) { super.onStartTrackingTouch(seekBar); mIsFromUser = true; - mSeekBarImage.setVisibility(VISIBLE); + mPreviewLayout.setVisibility(VISIBLE); } @Override public void onStopTrackingTouch(SeekBar seekBar) { - seekBar.setProgress(mPreSeekPosition); super.onStopTrackingTouch(seekBar); mIsFromUser = false; - cancelSeekBarImageTimer(); - mSeekBarImage.setVisibility(GONE); - mOffsetTime = 0; - mPreSeekPosition = -1; + mPreviewLayout.setVisibility(GONE); } @Override @@ -113,60 +133,4 @@ public class CustomGSYVideoPlayer extends StandardGSYVideoPlayer { } super.setTextAndProgress(secProgress); } - - private void startSeekBarImageTimer(int progress) { - cancelSeekBarImageTimer(); - mSeekBarImageTimer = new Timer(); - mShowSeekBarImageTimerTask = new ShowSeekBarImageTimerTask(progress); - mSeekBarImageTimer.schedule(mShowSeekBarImageTimerTask, 0); - } - - private void cancelSeekBarImageTimer() { - if (mShowSeekBarImageTimerTask != null) { - mShowSeekBarImageTimerTask.cancel(); - } - if (mSeekBarImageTimer != null) { - mSeekBarImageTimer.cancel(); - } - - } - - /** - * 获取帧预览图任务 - **/ - protected class ShowSeekBarImageTimerTask extends TimerTask { - - int mProgress; - - ShowSeekBarImageTimerTask(int progress) { - this.mProgress = progress; - } - - @Override - public void run() { - if (!TextUtils.isEmpty(mUrl)) { - try { - int time = mProgress * getDuration() / 100 * 1000; - //获取帧图片 - if (GSYVideoManager.instance().getMediaMetadataRetriever() != null) { - final Bitmap bitmap = GSYVideoManager.instance().getMediaMetadataRetriever() - .getFrameAtTime(time, MediaMetadataRetriever.OPTION_CLOSEST); - ((Activity) getContext()).runOnUiThread(new Runnable() { - @Override - public void run() { - if (bitmap != null) { - Debuger.printfLog("time " + System.currentTimeMillis()); - //显示 - mSeekBarImage.setImageBitmap(bitmap); - } - } - }); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - } diff --git a/gsyVideoPlayer/src/main/res/layout/video_layout_custom.xml b/gsyVideoPlayer/src/main/res/layout/video_layout_custom.xml index 84f861d6129ed69801e0838dcd29b22979d9d152..775f116631a0a04b4a57fd3568bf7be3f2a466c3 100644 --- a/gsyVideoPlayer/src/main/res/layout/video_layout_custom.xml +++ b/gsyVideoPlayer/src/main/res/layout/video_layout_custom.xml @@ -166,8 +166,8 @@ -