According to bilibili official documentation run code encountered problems

1. Several system plug-ins installed before build

# install homebrew, git, yasm
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install git
brew install yasm

# add these lines to your ~/.bash_profile or ~/.profile
# export ANDROID_SDK=<your sdk path>
# export ANDROID_NDK=<your ndk path>

# on Cygwin (unmaintained)
# install git, make, yasm
Copy the code

2. Solve the clone IJKPlayer library is slow or even disconnected.

As we all know, gitHub’s domestic access is very slow, so terminal agent needs to be set here to carry out clone project, remember that your computer needs to have agent here.

Export https_proxy http_proxy = = http://127.0.0.1:7890 http://127.0.0.1:7890 all_proxy = socks5: / / 127.0.0.1:7890Copy the code

3. Clone project and checkout latest version

Git clone https://github.com/Bilibili/ijkplayer.git ijkplayer - android CD ijkplayer - android git checkout - B latest k0.8.8Copy the code

4. Perform preprocessing (depending on how lean the package to compile is)

  • 1. Simple
cd config
rm module.sh
ln -s module-lite.sh module.sh
cd android/contrib
# cd ios
sh compile-ffmpeg.sh clean
Copy the code
  • 2. Simply wear HEVC
cd config
rm module.sh
ln -s module-lite-hevc.sh module.sh
cd android/contrib
# cd ios
sh compile-ffmpeg.sh clean
Copy the code
  • 3. Complex that supports multiple formats
cd config
rm module.sh
ln -s module-default.sh module.sh
cd android/contrib
# cd ios
sh compile-ffmpeg.sh clean
Copy the code

5. Perform. / init – android. Sh

This step will take you to Github to download FFmpeg resources

./init-android.sh


Copy the code

6. Build ffmpeg

cd android/contrib
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
Copy the code
  • (1) You need the NDKr10e or later question

Since it needs this version of the NDK, we can download one and set it to the environment variable. The download address is as follows:

https://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip?hl=zh_cn
Copy the code

Download, unzip, and configure environment variables. All in one go. Then we continue to run

  • (2)fatal error: linux/perf_event.h: No such file or directory
Export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-linux-perf" $COMMON_FF_CFG_FLAGS --disable-linux-perfCopy the code

Compile ijk

cd ..
./compile-ijk.sh all
Copy the code

OK, compile complete!

RUN IJKPlayerDemo

  • Unable to build problem Here is my configuration.

1. Modify BuildScript and AllProjects as follows.

Repositories {/ / * * * * * * * * domestic configuration start * * * * * * * * * * * * / / maven maven {{url 'https://maven.aliyun.com/repository/google'} url 'https://maven.aliyun.com/repository/jcenter' } maven { url 'https://maven.aliyun.com/nexus/content/groups/public' } //======== end =============//}Copy the code

2. Modify the classpath

The classpath 'com. Android. Tools. Build: gradle: 3.3.0'Copy the code

3. Modify gradle Wrapper

distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-bin.zip
Copy the code

4. Flavors configuration questions

// Make sure that you can change your minSdkVersion to 21 ^^!Copy the code

5. The directory cannot be loaded correctly

The program in the default "/" to the Environment. External.getexternalstoragedirectory (). The toString ()Copy the code

In addition, there is something wrong with the original code of the program, and it always identifies the “/” directory. At this time, we can change the program to the following.

String path = Environment.getExternalStorageDirectory().toString();
doOpenDirectory(path, false);
Copy the code

OK, done! We now have the iJkPlayer compiled and the player demo running correctly.

Build a new player project using compiled resources

    1. Copy files from ijkplayer-armv7a/ SRC /main/libs to libs of the new project.

    1. Then put ijkplayer – Java/build/outputs/aar/ijkplayer – Java – the aar libs is copied to the new project

Note: older versions of androidStudio do not actively generate aars at demo runtime, so you need to run the gradlew assembleRelease in the project root directory (MacOs).

  • 3. Finally, modify build.gradle to add so and AAR dependencies
Dependencies -> implementation fileTree(implementation fileTree) [' *. Jar ', '*. Aar']) / / android - > increase the NDK defaultConfig - > {abiFilters "armeabi", "armeabi - v7a", "arm64 - v8a", "x86, x86_64" "} // Android -> Add sourceSets {main {jnilibs. srcDirs = ['libs']}} // Outermost -> Add Repositories {flatDir { dir 'libs' } }Copy the code

The AAR and SO libraries are now ready to be configured

Homemade player simple Demo

  1. Player’s custom view

IjkVideoView.kt

package com.example.ijkplayerdemo import android.content.Context import android.text.TextUtils import android.util.AttributeSet import android.view.Gravity import android.view.SurfaceHolder import android.view.SurfaceView import android.widget.FrameLayout import androidx.annotation.Nullable import tv.danmaku.ijk.media.player.IMediaPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer import java.io.IOException class IjkVideoView : FrameLayout { private var mContext: Context? = null private var mMediaPlayer: IMediaPlayer? = null // Private var mVideoPlayerListener: VideoPlayerListener? Private var mSurfaceView: SurfaceView? Private var constructor = "constructor(context: context) : super(context) { initVideoView(context) } constructor(context: Context, @Nullable attrs: AttributeSet?) : super(context, attrs) { initVideoView(context) } constructor( context: Context, @Nullable attrs: AttributeSet? , defStyleAttr: Int ) : super(context, attrs, defStyleAttr) { initVideoView(context) } constructor( context: Context, @Nullable attrs: AttributeSet? , defStyleAttr: Int, defStyleRes: Int ) : super(context, attrs, defStyleAttr, defStyleRes) { } abstract class VideoPlayerListener : IMediaPlayer.OnPreparedListener, IMediaPlayer.OnCompletionListener, IMediaPlayer.OnErrorListener private fun initVideoView(context: Context) { mContext = context isFocusable = true } fun setPath(path: String) { if (TextUtils.equals("", mPath)) { mPath = path initSurfaceView() } else { mPath = path loadVideo() } } private fun initSurfaceView() { mSurfaceView = SurfaceView(mContext) mSurfaceView? .holder? .addCallback(LmnSurfaceCallback()) val layoutParams =LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Gravity.CENTER) mSurfaceView? .layoutParams = layoutParams this.addView(mSurfaceView)} private inner class lmnEcallBack: SurfaceHolder.Callback { override fun surfaceCreated(holder: SurfaceHolder) {} override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { loadVideo() } override fun surfaceDestroyed(holder: SurfaceHolder) {}} private Fun loadVideo() {if (mMediaPlayer! = null) { mMediaPlayer? .stop() mMediaPlayer? .release() } val ijkMediaPlayer = IjkMediaPlayer() mMediaPlayer = ijkMediaPlayer if (mVideoPlayerListener ! = null) { mMediaPlayer? .setOnPreparedListener(mVideoPlayerListener) mMediaPlayer? .setOnErrorListener(mVideoPlayerListener) } try { mMediaPlayer? .dataSource = mPath } catch (e: IOException) { e.printStackTrace() } mMediaPlayer? .setDisplay(mSurfaceView? .holder) mMediaPlayer? .prepareAsync() } fun setListener(listener: VideoPlayerListener?) { mVideoPlayerListener = listener if (mMediaPlayer ! = null) { mMediaPlayer? .setOnPreparedListener(listener) } } val isPlaying: Boolean get() = if (mMediaPlayer ! = null) { mMediaPlayer? .isPlaying? :false } else false fun start() { if (mMediaPlayer ! = null) { mMediaPlayer? .start() } } fun pause() { if (mMediaPlayer ! = null) { mMediaPlayer? .pause() } } fun stop() { if (mMediaPlayer ! = null) { mMediaPlayer? .stop() } } fun reset() { if (mMediaPlayer ! = null) { mMediaPlayer? .reset() } } fun release() { if (mMediaPlayer ! = null) { mMediaPlayer? .reset() mMediaPlayer? .release() mMediaPlayer = null } } }Copy the code
  1. The Activity call

MainActivity.kt

package com.example.ijkplayerdemo import android.os.Bundle import android.os.Environment import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import tv.danmaku.ijk.media.player.IMediaPlayer import tv.danmaku.ijk.media.player.IjkMediaPlayer import java.io.File class MainActivity : AppCompatActivity() { var ijkVideoView:IjkVideoView? =null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Environment.getStorageDirectory().absolutePath // init player IjkMediaPlayer.loadLibrariesOnce(null) IjkMediaPlayer.native_profileBegin("libijkplayer.so") ijkVideoView = findViewById(R.id.player) ijkVideoView? .setListener(object: IjkVideoView.VideoPlayerListener() { override fun onPrepared(p: IMediaPlayer?) {// Play successfully processed p? .start() } override fun onCompletion(p0: IMediaPlayer?) {toast.maketext (this@MainActivity," toast.length_long ", toast.length_long).show()} Override fun onError(p0: IMediaPlayer? , p1: Int, p2: Int): Boolean {toast.maketext (this@MainActivity," toast.length_long ", toast.length_long).show() return false}}) // path ijkVideoView? .setPath("http://tanzi27niu.cdsb.mobi/wps/wp-content/uploads/2017/05/2017-05-17_17-33-30.mp4"); ijkVideoView? .start(); }}Copy the code
  1. Layout file

activity_main.xml

<? The XML version = "1.0" encoding = "utf-8"? > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.example.ijkplayerdemo.IjkVideoView android:id="@+id/player" android:layout_width="match_parent" android:layout_height="250dp"/> </RelativeLayout>Copy the code
  1. Add network and storage permissions (don’t forget to apply for storage permissions yourself!)
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Copy the code