学习bilibili ijkplayer集成,熟悉ffmpeg

整理完vlc后,随手整理了下ijkPlayer;
  • ijkplayer是Bilibili公司开源的播放器实现,整合了FFMpeg, ExoPlayer,MediaPlayer等多种实现,提供了类似于MediaPlayer的API,可以实现软硬解码自由切换,自定义TextureView实现,同时得益于FFMpeg的能力,也能支持多种流媒体协议(RTSP,RTMP,HLS等),多种视频编码格式(h264,
    mpeg4, mjpeg),具有很高的灵活性,可以定制实现自己特色的播放器(比如支持视频缩放,视频翻转等)。
  • IJKPlayer源码地址:

在这里插入图片描述

在这里插入图片描述

一、ubuntu下面编译环境搭建;

例如我阿里云服务端 ubuntu 16.04下载ndk

1、下载Android NDK自解压包:

wget -c http://dl.google.com/android/ndk/android-ndk-r18b-linux-x86_64.bin
android-ndk-r21b-linux-x86_64.bin

2、将Android NDK压缩包解压到你想要的目录下,如
在这里插入图片描述

/opt/android/ndk/
chmod a+x android-ndk-r18b-linux-x86_64.bin
 ./android-ndk-r18b-linux-x86_64.bin

解压后目录结构为:
/opt/android/ndk/android-ndk-r18b

3、配置PATH路径:
命令:
$ sudo vim /etc/profile,在文件末尾加入如下内容:
#set NDK env

export ANDROID_NDK=/opt/android/ndk/android-ndk-r14b
export NDK_HOME=/opt/android/ndk/android-ndk-r14b
export PATH=$NDK_HOME:$PATH

同理SDK也需要安装:

wget https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz?utm_source=androiddevtools&utm_medium=website

mv android-sdk_r24.4.1-linux.tgz\?utm_source\=androiddevtools  android-sdk_r24.4.1-linux.tgz

 tar zxvf android-sdk_r24.4.1-linux.tgz

在这里插入图片描述

export ANDROID_SDK_HOME=/opt/android/sdk/android-sdk-linux
export PATH=$PATH:${ANDROID_SDK_HOME}/tools
export PATH=$PATH:${ANDROID_SDK_HOME}/platform-tools
  • 下载对应gradle版本

https://gradle.org/releases/
在这里插入图片描述

在这里插入图片描述

export GRADLE_HOME=/opt/android/gradle/gradle-2.14.1 
export PATH=$GRADLE_HOME/bin:$PATH   

在这里插入图片描述在这里插入图片描述

source /etc/profile
二、下载源码并且切换到对应稳定版本分支;
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android
cd ijkplayer-android
git checkout -B latest k0.8.8
./init-android.sh
  1. 下载ffmpeg相关code;

在这里插入图片描述

  • 编译ffmpeg
cd android/contrib
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all

在这里插入图片描述

  • 编译ijkPlayer相关库:
cd ..
./compile-ijk.sh all

在这里插入图片描述

  • 编译ijkplayer apk:
./gradlew clean build 

在这里插入图片描述
在这里插入图片描述
成功编译

需要注意的是,如果在ubuntu下面编译建议修改各个项目的build.gradle;

diff --git a/android/ijkplayer/gradle/wrapper/gradle-wrapper.properties b/android/ijkplayer/gradle/wrapper/gradle-wrapper.properties
index f47ae66..da11b25 100644
--- a/android/ijkplayer/gradle/wrapper/gradle-wrapper.properties
+++ b/android/ijkplayer/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
+distributionUrl=gradle-2.14.1-all.zip
diff --git a/android/ijkplayer/ijkplayer-arm64/build.gradle b/android/ijkplayer/ijkplayer-arm64/build.gradle
index a8cbe0c..17f01cf 100644
--- a/android/ijkplayer/ijkplayer-arm64/build.gradle
+++ b/android/ijkplayer/ijkplayer-arm64/build.gradle
@@ -6,7 +6,9 @@ android {
     compileSdkVersion rootProject.ext.compileSdkVersion
     //noinspection GroovyAssignabilityCheck
     buildToolsVersion rootProject.ext.buildToolsVersion
-
+       lintOptions {
+        abortOnError false
+    }
     defaultConfig {
         minSdkVersion 21
         targetSdkVersion rootProject.ext.targetSdkVersion
diff --git a/android/ijkplayer/ijkplayer-armv5/build.gradle b/android/ijkplayer/ijkplayer-armv5/build.gradle
index b3b7b3a..8c1c8ce 100644
--- a/android/ijkplayer/ijkplayer-armv5/build.gradle
+++ b/android/ijkplayer/ijkplayer-armv5/build.gradle
@@ -6,6 +6,9 @@ android {
     compileSdkVersion rootProject.ext.compileSdkVersion
     //noinspection GroovyAssignabilityCheck
     buildToolsVersion rootProject.ext.buildToolsVersion
+    lintOptions {
+        abortOnError false
+    }
 
     defaultConfig {
         minSdkVersion 9
diff --git a/android/ijkplayer/ijkplayer-armv7a/build.gradle b/android/ijkplayer/ijkplayer-armv7a/build.gradle
index b3b7b3a..8c1c8ce 100644
--- a/android/ijkplayer/ijkplayer-armv7a/build.gradle
+++ b/android/ijkplayer/ijkplayer-armv7a/build.gradle
@@ -6,6 +6,9 @@ android {
     compileSdkVersion rootProject.ext.compileSdkVersion
     //noinspection GroovyAssignabilityCheck
     buildToolsVersion rootProject.ext.buildToolsVersion
+    lintOptions {
+        abortOnError false
+    }
 
     defaultConfig {
         minSdkVersion 9
diff --git a/android/ijkplayer/ijkplayer-java/build.gradle b/android/ijkplayer/ijkplayer-java/build.gradle
index 30d3ad2..9797cdd 100644
--- a/android/ijkplayer/ijkplayer-java/build.gradle
+++ b/android/ijkplayer/ijkplayer-java/build.gradle
@@ -20,6 +20,8 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
         }
     }
+
+
 }
 
 dependencies {
diff --git a/android/ijkplayer/ijkplayer-x86/build.gradle b/android/ijkplayer/ijkplayer-x86/build.gradle
index b3b7b3a..3abae56 100644
--- a/android/ijkplayer/ijkplayer-x86/build.gradle
+++ b/android/ijkplayer/ijkplayer-x86/build.gradle
@@ -6,6 +6,11 @@ android {
     compileSdkVersion rootProject.ext.compileSdkVersion
     //noinspection GroovyAssignabilityCheck
     buildToolsVersion rootProject.ext.buildToolsVersion
+    android {
+    lintOptions {
+        abortOnError false
+    }
+}
 
     defaultConfig {
         minSdkVersion 9
diff --git a/android/ijkplayer/ijkplayer-x86_64/build.gradle b/android/ijkplayer/ijkplayer-x86_64/build.gradle
index a8cbe0c..eb6d58a 100644
--- a/android/ijkplayer/ijkplayer-x86_64/build.gradle
+++ b/android/ijkplayer/ijkplayer-x86_64/build.gradle
@@ -6,6 +6,11 @@ android {
     compileSdkVersion rootProject.ext.compileSdkVersion
     //noinspection GroovyAssignabilityCheck
     buildToolsVersion rootProject.ext.buildToolsVersion
+   android {
+    lintOptions {
+        abortOnError false
+    }
+}
 
     defaultConfig {
         minSdkVersion 21

全项目编译容易引起

在这里插入图片描述

  • 修改后编译成功

在这里插入图片描述

三、集成ffmpeg 相关库以及ijk jni aar到android studio个人项目;

在这里插入图片描述
copy生成的aar以及对应的平台so到android Studio工程

在这里插入图片描述
在这里插入图片描述
修改APP下的build.gradle, 主要设置.so及.aar的位置

在这里插入图片描述

模块简要介绍
ijkplayer-javaijkplayer的一些操作封装及定义。这里面是通用的API接口,里面最主要的是IMediaPlayer,它是用来渲染显示多媒体的
ijkplayer-exogoogle开源的一个新的播放器ExoPlayer,在Demo中和ijkplayer对比用的。通过安装ijkplayer可以发现setting里面可以选择不同player来渲染多媒体显示,该模块下面就是一个MediaPlayer
ijkplayer-example测试程序
ijkplayer-{arch}编译出来的各个版本的.so文件

主要实现类:

  1. 封装PlayerView
package com.example.ijkplayer.view;

import android.content.Context;
import android.graphics.Color;
import android.media.AudioManager;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;


import com.example.ijkplayer.VideoListener;

import java.io.IOException;
import java.util.Map;

import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;

public class PlayerView extends FrameLayout {

    private IMediaPlayer mMediaPlayer = null;
    private String mPath;
    private Map<String, String> mHeader;
    private SurfaceView mSurfaceView;
    private Context mContext;
    private boolean mEnableMediaCodec;
    private AudioManager mAudioManager;
    private AudioFocusHelper mAudioFocusHelper;
    private VideoListener mListener;

    public PlayerView(@NonNull Context context) {
        this(context, null);
    }

    public PlayerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PlayerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    /**
     * 初始化
     */
    private void init(Context context) {
        mContext = context;
        setBackgroundColor(Color.BLACK);
        createSurfaceView();
        mAudioManager = (AudioManager) mContext.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
        mAudioFocusHelper = new AudioFocusHelper();
    }

    /**
     * 创建surfaceView
     */
    private void createSurfaceView() {
        mSurfaceView = new SurfaceView(mContext);
        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(0.8f, 0.8f);
        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;
    }

    private void setListener(IMediaPlayer player) {
        player.setOnPreparedListener(mPreparedListener);
        player.setOnVideoSizeChangedListener(mVideoSizeChangedListener);
    }


    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.pause();
            mMediaPlayer.stop();
            mMediaPlayer.release();
        }
        mMediaPlayer = createPlayer();
        setListener(mMediaPlayer);
        mMediaPlayer.setDisplay(mSurfaceView.getHolder());
        mMediaPlayer.setDataSource(mContext, Uri.parse(mPath), mHeader);
        mMediaPlayer.prepareAsync();
    }

    /**
     * 设置自己的player回调
     */
    public void setVideoListener(VideoListener listener) {
        mListener = listener;
    }

    private IMediaPlayer.OnPreparedListener mPreparedListener = new IMediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(IMediaPlayer iMediaPlayer) {
            if (mListener != null) {
                mListener.onPrepared(iMediaPlayer);
            }
        }
    };

    public void start() {
        if (mMediaPlayer != null) {
            mMediaPlayer.start();
            Log.d("Mr.xw==", "start_player");
            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;
    }

    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()) {
                        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;
        }
    }

}
  1. VideoListener监听类
package com.example.ijkplayer;

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 {
}
  1. 播放页面IJKPlayerActivity
package com.example.ijkplayer.activity;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

import com.example.ijkplayer.VideoListener;
import com.example.ijkplayer.view.PlayerView;
import com.mgtv.exodemo.R;

import java.io.IOException;

import tv.danmaku.ijk.media.player.IMediaPlayer;

public class IJKPlayerActivity extends Activity implements VideoListener {
    private PlayerView mMediaPlayer = null;
    private String videoUrlRtp = "rtp://239.76.245.115:1234";
    private String videoUrlHls = "http://10.255.30.137:8082/EDS/RedirectPlay/000000000000/vod/f95e41c67ca2410c89b335ee5f5eecb8/3cc6fae6d07740aa8d57934e26cc2632?UserToken=123456789&UserName=6830018";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ijkplayer);
        mMediaPlayer = findViewById(R.id.ijk_player);
    }

    @Override
    protected void onResume() {
        super.onResume();
        initIJKPlayer();
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseData();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseData();
    }

    private void releaseData() {
        if (isFinishing()) {
            if (mMediaPlayer != null) {
                mMediaPlayer.stop();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
        }
    }

    /**
     * 初始化播放器
     */
    private void initIJKPlayer() {
        mMediaPlayer.setVideoListener(this);
        mMediaPlayer.setPath(videoUrlRtp);
        /**false 软解,true:硬解 默认使用硬解码*/
        mMediaPlayer.setEnableMediaCodec(true);
        try {
            mMediaPlayer.load();
        } catch (IOException e) {
            Toast.makeText(this, "播放失败", Toast.LENGTH_SHORT);
            e.printStackTrace();
        }
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {

    }

    @Override
    public void onBufferingUpdate(IMediaPlayer iMediaPlayer, int i) {

    }

    @Override
    public void onCompletion(IMediaPlayer iMediaPlayer) {

    }

    @Override
    public boolean onError(IMediaPlayer iMediaPlayer, int i, int i1) {
        return false;
    }

    @Override
    public boolean onInfo(IMediaPlayer iMediaPlayer, int i, int i1) {
        return false;
    }

    @Override
    public void onPrepared(IMediaPlayer iMediaPlayer) {
        mMediaPlayer.start();
    }

    @Override
    public void onSeekComplete(IMediaPlayer iMediaPlayer) {

    }

    @Override
    public void onVideoSizeChanged(IMediaPlayer iMediaPlayer, int i, int i1, int i2, int i3) {

    }

}
 /**false 软解,true:硬解*/
  mMediaPlayer.setEnableMediaCodec(false);

硬解的时候可以看到cpu占用率
在这里插入图片描述
软解的时候可以看到cpu占用率:
在这里插入图片描述

如果需要播放直播rtp的话,需要使能rtp:

export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocol=rtp"
修改为以下,就可以打开rtsp协议了
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtp"

在这里插入图片描述

执行以下命令,连接配置文件,开始编译

cd config
rm module.sh
ln -s module-lite.sh module.sh
cd android
cd contrib
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh al

在这里插入图片描述
重新编译ffmpeg:
在这里插入图片描述

在这里插入图片描述
update ffmpge库
在这里插入图片描述
更新库后可以支持组播rtp(直播流)的播放;
在这里插入图片描述

四、IjkPlayer的常用Option设置
参数设置功能说明
1.设置是否开启变调mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,“soundtouch”,isModifyTone?0:1)
2.设置是否开启环路过滤: 0开启,画面质量高,解码开销大,48关闭,画面质量差点,解码开销小mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC,“skip_loop_filter”,isSkipLoopFilter?0:48L)
3.设置播放前的最大探测时间mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,“analyzemaxduration”,100L)
4.设置播放前的探测时间 1,达到首屏秒开效果mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,“soundtouch”,isModifyTone?0:1)
5.播放前的探测Size,默认是1M, 改小一点会出画面更快mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,“probesize”,1024*10)
6.每处理一个packet之后刷新io上下文mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,“flush_packets”,1L)
7. 是否开启预缓冲,一般直播项目会开启,达到秒开的效果,不过带来了播放丢帧卡顿的体验mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,“packet-buffering”,isBufferCache?1:0)
8.播放重连次数mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,“reconnect”,5)
9.最大缓冲大小,单位kbmediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,“max-buffer-size”,maxCacheSize))
10.跳帧处理,放CPU处理较慢时,进行跳帧处理,保证播放流程,画面和声音同步mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,“framedrop”,5)
11.最大fpsmediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,“max-fps”,30);
12.设置硬解码方式mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, “mediacodec”, 1) mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, “mediacodec-auto-rotate”, 1) mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, “mediacodec-handle-resolution-change”, 1)
13.SeekTo设置优化mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, “enable-accurate-seek”, 1);

附上个人编译的支持rtp的相关库以及官方demo
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
https://download.csdn.net/download/xiaweilihai/12634232

个人测试demo需要在IPTV专网环境才能播放rtp,gitHub demo上修改播放Uri即可:

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值