【Android】ijkplayer集成使用
https://www.jianshu.com/p/9e60cbd4db15
Ijkplayer rtsp 封装
package xxxxx import 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(); } //创建surfaceView private void createSurfaceView() { mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { if (mMediaPlayer != null) { mMediaPlayer.setDisplay(surfaceHolder); } } @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { } }); LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT , LayoutParams.MATCH_PARENT, Gravity.CENTER); // mSurfaceView.setLayoutParams(layoutParams); addView(mSurfaceView,0,layoutParams); } //创建一个新的player private 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(){ @Override public void onPrepared(IMediaPlayer iMediaPlayer) { if(mListener != null){ mListener.onPrepared(iMediaPlayer); } } }; private IMediaPlayer.OnVideoSizeChangedListener mVideoSizeChangedListener = new IMediaPlayer.OnVideoSizeChangedListener() { @Override public 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; @Override public 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)