【Android】ijkplayer集成使用
https://www.jianshu.com/p/9e60cbd4db15
Ijkplayer rtsp 封装
package xxxxximport android.content.Context; import android.graphics.Color; import android.media.AudioManager; import android.net.Uri; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.Gravity; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.FrameLayout;import java.util.Map;import tv.danmaku.ijk.media.player.IMediaPlayer; import tv.danmaku.ijk.media.player.IjkMediaPlayer;public class VideoPlayer extends FrameLayout {/*** 由ijkplayer提供,用于播放视频,需要给他传入一个surfaceView*/private IMediaPlayer mMediaPlayer = null;/*** 视频文件地址*/private String mPath ;/*** 视频请求header*/private Map<String,String> mHeader;private SurfaceView mSurfaceView;private Context mContext;private boolean mEnableMediaCodec=true;IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();private VideoListener mListener;private AudioManager mAudioManager;private AudioFocusHelper mAudioFocusHelper;public VideoPlayer(@NonNull Context context) {this(context, null);}public VideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public VideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}//初始化private void init(Context context) {mContext = context;mSurfaceView = new SurfaceView(mContext);setBackgroundColor(Color.BLACK);createSurfaceView();mAudioManager = (AudioManager)mContext.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);mAudioFocusHelper = new AudioFocusHelper();}//创建surfaceViewprivate void createSurfaceView() {mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(SurfaceHolder surfaceHolder) {}@Overridepublic void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {if (mMediaPlayer != null) {mMediaPlayer.setDisplay(surfaceHolder);}}@Overridepublic void surfaceDestroyed(SurfaceHolder surfaceHolder) {}});LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Gravity.CENTER);// mSurfaceView.setLayoutParams(layoutParams);addView(mSurfaceView,0,layoutParams);}//创建一个新的playerprivate IMediaPlayer createPlayer() { // IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer(); // ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 1); // // ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32); // ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1); // ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0); // // ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "http-detect-range-support", 1); // // ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48); // ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "min-frames", 100); // ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1); // // ijkMediaPlayer.setVolume(1.0f, 1.0f);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 60);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-fps", 0);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "fps", 30);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_YV12);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec_mpeg4", 1);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer");ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "max-buffer-size", 1024);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 10);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probsize", "4096");ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", "2000000");ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec_mpeg4", 1);// 最大缓冲cache是3s, 有时候网络波动,会突然在短时间内收到好几秒的数据// 因此需要播放器丢包,才不会累积延时// 这个和第三个参数packet-buffering无关。ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 3000);// 无限制收流ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 1);// 设置无缓冲,这是播放器的缓冲区,有数据就播放ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0);// 可选,有时候tcp模式出画面更快,因为rtsp是先udp,不成功再切到tcp的//ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1);// 设置在解析的 url 之前 (这里设置超时为5秒)// 如果没有设置stimeout,在解析时(也就是avformat_open_input)把网线拔掉,av_read_frame会阻塞(时间单位是微妙)ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "stimeout", "5000000");setEnableMediaCodec(ijkMediaPlayer,mEnableMediaCodec);return ijkMediaPlayer;}//设置是否开启硬解码private void setEnableMediaCodec(IjkMediaPlayer ijkMediaPlayer, boolean isEnable) {int value = isEnable ? 1 : 0;ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", value);//开启硬解码ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", value);ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", value);}public void setEnableMediaCodec(boolean isEnable){mEnableMediaCodec = isEnable;}//设置ijkplayer的监听private void setListener(IMediaPlayer player){player.setOnPreparedListener(mPreparedListener);player.setOnVideoSizeChangedListener(mVideoSizeChangedListener);}/*** 设置自己的player回调*/public void setVideoListener(VideoListener listener){mListener = listener;}//设置播放地址public void setPath(String path) {setPath(path,null);}public void setPath(String path,Map<String,String> header){mPath = path;mHeader = header;}// //开始加载视频 // public void load() throws IOException { // if(mMediaPlayer != null){ // mMediaPlayer.stop(); // mMediaPlayer.release(); // } // mMediaPlayer = createPlayer(); // setListener(mMediaPlayer); // mMediaPlayer.setDisplay(mSurfaceView.getHolder()); // mMediaPlayer.setDataSource(mContext, Uri.parse(mPath),mHeader); // // mMediaPlayer.prepareAsync(); // }//开始加载视频public void load(String path) {if(mMediaPlayer != null){mMediaPlayer.stop();mMediaPlayer.release();}mHeader=null;mMediaPlayer = createPlayer();setListener(mMediaPlayer);mMediaPlayer.setDisplay(mSurfaceView.getHolder());try { // mMediaPlayer.setDataSource(mContext, Uri.parse(path),mHeader);mMediaPlayer.setDataSource(mContext, Uri.parse(path));} catch (Exception e) {e.printStackTrace();}mMediaPlayer.prepareAsync();mMediaPlayer.start();mAudioFocusHelper.requestFocus();}public void start() {if (mMediaPlayer != null) {mMediaPlayer.start();mAudioFocusHelper.requestFocus();}}public void release() {if (mMediaPlayer != null) {mMediaPlayer.reset();mMediaPlayer.release();mMediaPlayer = null;mAudioFocusHelper.abandonFocus();}}public void pause() {if (mMediaPlayer != null) {mMediaPlayer.pause();mAudioFocusHelper.abandonFocus();}}public void stop() {if (mMediaPlayer != null) {mMediaPlayer.stop();mAudioFocusHelper.abandonFocus();}}public void reset() {if (mMediaPlayer != null) {mMediaPlayer.reset();mAudioFocusHelper.abandonFocus();}}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);}}public boolean isPlaying(){if(mMediaPlayer != null) {return mMediaPlayer.isPlaying();}return false;}//------------------ 各种listener 赋值 ---------------------//private IMediaPlayer.OnPreparedListener mPreparedListener = new IMediaPlayer.OnPreparedListener(){@Overridepublic void onPrepared(IMediaPlayer iMediaPlayer) {if(mListener != null){mListener.onPrepared(iMediaPlayer);}}};private IMediaPlayer.OnVideoSizeChangedListener mVideoSizeChangedListener = new IMediaPlayer.OnVideoSizeChangedListener() {@Overridepublic void onVideoSizeChanged(IMediaPlayer iMediaPlayer, int i, int i1, int i2, int i3) {int videoWidth = iMediaPlayer.getVideoWidth();int videoHeight = iMediaPlayer.getVideoHeight();if (videoWidth != 0 && videoHeight != 0) {mSurfaceView.getHolder().setFixedSize(videoWidth, videoHeight);}}};//------------------ 音频监听 ---------------------///*** 音频焦点改变监听*/private class AudioFocusHelper implements AudioManager.OnAudioFocusChangeListener {boolean startRequested = false;boolean pausedForLoss = false;int currentFocus = 0;@Overridepublic void onAudioFocusChange(int focusChange) {if (currentFocus == focusChange) {return;}currentFocus = focusChange;switch (focusChange) {case AudioManager.AUDIOFOCUS_GAIN://获得焦点case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT://暂时获得焦点if (startRequested || pausedForLoss) {start();startRequested = false;pausedForLoss = false;}if (mMediaPlayer != null)//恢复音量mMediaPlayer.setVolume(1.0f, 1.0f);break;case AudioManager.AUDIOFOCUS_LOSS://焦点丢失case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT://焦点暂时丢失 // if (isPlaying()) {pausedForLoss = true;pause(); // }break;case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK://此时需降低音量 // if (mMediaPlayer != null && isPlaying()) {if (mMediaPlayer != null){mMediaPlayer.setVolume(0.1f, 0.1f);}break;}}boolean requestFocus() {if (currentFocus == AudioManager.AUDIOFOCUS_GAIN) {return true;}if (mAudioManager == null) {return false;}int status = mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);if (AudioManager.AUDIOFOCUS_REQUEST_GRANTED == status) {currentFocus = AudioManager.AUDIOFOCUS_GAIN;return true;}startRequested = true;return false;}boolean abandonFocus() {if (mAudioManager == null) {return false;}startRequested = false;int status = mAudioManager.abandonAudioFocus(this);return AudioManager.AUDIOFOCUS_REQUEST_GRANTED == status;}}}
package xxxxx
import tv.danmaku.ijk.media.player.IMediaPlayer;public interface VideoListener extends IMediaPlayer.OnBufferingUpdateListener, IMediaPlayer.OnCompletionListener, IMediaPlayer.OnPreparedListener, IMediaPlayer.OnInfoListener, IMediaPlayer.OnVideoSizeChangedListener, IMediaPlayer.OnErrorListener, IMediaPlayer.OnSeekCompleteListener{ }
/IJKMEDIA: rtsp://10.0.127.111:554/1: Protocol not found
1597133197.424 4720-4861/cn.jzvd.demo E/tv.danmaku.ijk.media.player.IjkMediaPlayer: Error (-10000,0)