赞
踩
ijkplayer: Android/iOS video player based on FFmpeg n3.4, with MediaCodec, VideoToolbox support.
官方的描述就这么简单的一句话,但丝毫都不影响它的强大。
截止到2023.7.20
LibVLC-Android 最大的问题在与OOM,测试了多个版本后最终选择放弃:
3.1.0/3.2.5/3.3.5/3.5.0/3.6.0/4.0.0-eap1到4.0.0-eap11, 内存随着播放次数增加而递增,到最终出现OOM
4.0.0-eap12: OOM 解决了,setVolume不工作了…
PS
4.0.0-eap12: OOM还和绑定的播放窗口有关, 传入SurfaceView/TextureView是内存泄露问题依然存在;
直到使用了org.videolan.libvlc.util.VLCVideoLayout才得以解决。
另外一个问题是,org.videolan.libvlc.util.VLCVideoLayout在画面切换、覆盖时会出现残留、画面比例失调等问题。
下载了源码编译
vlc-android
export ANDROID_NDK=/home/anson/Android/Sdk/ndk/android-ndk-r14b
export ANDROID_SDK=/home/anson/Android/Sdk
buildsystem/compile.sh -l -a arm
生成AAR只需要加上 -r 参数即可
OOM问题依旧~ 跟4.0.0-eap12还是有区别
当然也考虑过其他的播放插件如
ExoPlayer, 没有H265,android exoplayer rtsp example
迁移到了 AndroidX Media3 1.1.0 release.
This is the last planned release of the com.google.android.exoplayer2 artifacts.
This project is now deprecated. All users should migrate to androidx.media3 (which contains the same ExoPlayer code).
See the migration guide for more details, including a script to help with the migration
PS: 视沃科技-大牛直播移动端
之前没试过,然后下载下来试了下,DEMO APK都跑不了,呵呵,非免费
GSYVideoPlayer
Android–GSYVideoPlayer框架实现播放视频
怎么说好呢,这是个大合集,EXO, IJK…一样解决不了 RTSP + H265
rtsp-client-android
一些兼容性问题,不出图。
implementation "tv.danmaku.ijk.media:ijkplayer-java:0.8.8"
implementation "tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8"
export ANDROID_NDK=/home/anson/Android/Sdk/ndk/android-ndk-r14b export ANDROID_SDK=/home/anson/Android/Sdk ARCH=armv7a echo ">> INIT " git checkout -B latest k0.8.8 ./init-android.sh ./init-android-openssl.sh cd android/contrib echo ">> BUILD OPENSSL" ./compile-openssl.sh clean ./compile-openssl.sh ${ARCH} echo ">> BUILD FFMPEG" ./compile-ffmpeg.sh clean ./compile-ffmpeg.sh ${ARCH} echo ">> BUILD IJKPLAYER" cd .. ./compile-ijk.sh clean ./compile-ijk.sh ${ARCH}
源码的一些修改:
git diff config/module-lite.sh android/contrib/tools/do-compile-ffmpeg.sh diff --git a/android/contrib/tools/do-compile-ffmpeg.sh b/android/contrib/tools/do-compile-ffmpeg.sh index d6b3ba63..633b89f6 100755 --- a/android/contrib/tools/do-compile-ffmpeg.sh +++ b/android/contrib/tools/do-compile-ffmpeg.sh @@ -267,7 +267,7 @@ FF_CFG_FLAGS="$FF_CFG_FLAGS --prefix=$FF_PREFIX" # Advanced options (experts only): FF_CFG_FLAGS="$FF_CFG_FLAGS --cross-prefix=${FF_CROSS_PREFIX}-" FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-cross-compile" -FF_CFG_FLAGS="$FF_CFG_FLAGS --target-os=linux" +FF_CFG_FLAGS="$FF_CFG_FLAGS --target-os=android" FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-pic" # FF_CFG_FLAGS="$FF_CFG_FLAGS --disable-symver" @@ -292,6 +292,8 @@ case "$FF_BUILD_OPT" in ;; esac + + #-------------------- echo "" echo "--------------------" diff --git a/config/module-lite.sh b/config/module-lite.sh index d5ba3d0f..64c4b05a 100755 --- a/config/module-lite.sh +++ b/config/module-lite.sh @@ -42,7 +42,10 @@ export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-swscale" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-postproc" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-avfilter" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-avresample" -# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-pthreads" +export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-pthreads" +export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-mediacodec" +export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-jni" + # export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-w32threads" # export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-os2threads" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-network" @@ -146,7 +149,8 @@ export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocol=mmst" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocol=rtmp*" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtmp" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtmpt" -export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocol=rtp" +export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtp" +export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=rtsp" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocol=sctp" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocol=srtp" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocol=subfile"
编译完成后:
JAVA
android/ijkplayer/ijkplayer-java/src/main/java/tv/danmaku/ijk/media/player/ ├── AbstractMediaPlayer.java ├── AndroidMediaPlayer.java ├── annotations │ ├── AccessedByNative.java │ └── CalledByNative.java ├── exceptions │ └── IjkMediaException.java ├── ffmpeg │ └── FFmpegApi.java ├── IjkLibLoader.java ├── IjkMediaCodecInfo.java ├── IjkMediaMeta.java ├── IjkMediaPlayer.java ├── IjkTimedText.java ├── IMediaPlayer.java ├── ISurfaceTextureHolder.java ├── ISurfaceTextureHost.java ├── MediaInfo.java ├── MediaPlayerProxy.java ├── misc │ ├── AndroidMediaFormat.java │ ├── AndroidTrackInfo.java │ ├── IAndroidIO.java │ ├── IjkMediaFormat.java │ ├── IjkTrackInfo.java │ ├── IMediaDataSource.java │ ├── IMediaFormat.java │ └── ITrackInfo.java ├── pragma │ ├── DebugLog.java │ └── Pragma.java └── TextureMediaPlayer.java
SO 库
android/ijkplayer/ijkplayer-armv7a/src/main/libs/armeabi-v7a/
├── libijkffmpeg.so
├── libijkplayer.so
└── libijksdl.so
这里偷个懒,使用so库即可,build.gradle:
implementation "tv.danmaku.ijk.media:ijkplayer-java:0.8.8"
//这个不要,直接使用编译出来的so库
//implementation "tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8"
编译完成后,可以尝试在AndroidStudio中打开ijkplayer的示例项目。AndroidStudio和gradle已经物是人非,使用一些需要修改成一些兼容的版本等配置信息。
android/ijkplayer/build.gradle
--- a/android/ijkplayer/build.gradle +++ b/android/ijkplayer/build.gradle @@ -3,9 +3,11 @@ buildscript { repositories { jcenter() + maven { url 'https://maven.google.com/'} + maven { url 'https://maven.aliyun.com/repository/jcenter' } } dependencies { - classpath 'com.android.tools.build:gradle:2.1.3' + classpath 'com.android.tools.build:gradle:4.0.1' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7' @@ -17,6 +19,8 @@ buildscript { allprojects { repositories { jcenter() + maven { url 'https://maven.google.com/'} + maven { url 'https://maven.aliyun.com/repository/jcenter' } } }
android/ijkplayer/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Aug 24 16:26:25 CST 2016
+#Wed Jul 19 10:32:59 CST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
android/ijkplayer/ijkplayer-example/build.gradle
--- a/android/ijkplayer/ijkplayer-example/build.gradle +++ b/android/ijkplayer/ijkplayer-example/build.gradle @@ -16,6 +16,12 @@ android { targetSdkVersion rootProject.ext.targetSdkVersion versionCode rootProject.ext.versionCode versionName rootProject.ext.versionName + + externalNativeBuild{ + ndk{ + abiFilters 'armeabi-v7a' + } + } } buildTypes { release { @@ -23,36 +29,35 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - productFlavors { + /*productFlavors { all32 { minSdkVersion 9 } all64 { minSdkVersion 21 } // armv5 {} // armv7a {} // arm64 { minSdkVersion 21 } // x86 {} - } + }*/ } dependencies { - compile fileTree(include: ['*.jar'], dir: 'libs') - compile 'com.android.support:appcompat-v7:23.0.1' - compile 'com.android.support:preference-v7:23.0.1' - compile 'com.android.support:support-annotations:23.0.1' - + } + } } buildTypes { release { @@ -23,36 +29,35 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - productFlavors { + /*productFlavors { all32 { minSdkVersion 9 } all64 { minSdkVersion 21 } // armv5 {} // armv7a {} // arm64 { minSdkVersion 21 } // x86 {} - } + }*/ } dependencies { - compile fileTree(include: ['*.jar'], dir: 'libs') - compile 'com.android.support:appcompat-v7:23.0.1' - compile 'com.android.support:preference-v7:23.0.1' - compile 'com.android.support:support-annotations:23.0.1' - - compile 'com.squareup:otto:1.3.8' + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'com.android.support:appcompat-v7:23.0.1' + implementation 'com.android.support:preference-v7:23.0.1' + implementation 'com.android.support:support-annotations:23.0.1' - compile project(':ijkplayer-java') - compile project(':ijkplayer-exo') + implementation 'com.squareup:otto:1.3.8' - all32Compile project(':ijkplayer-armv5') - all32Compile project(':ijkplayer-armv7a') - all32Compile project(':ijkplayer-x86') + implementation project(':ijkplayer-java') + implementation project(':ijkplayer-exo') - all64Compile project(':ijkplayer-armv5') - all64Compile project(':ijkplayer-armv7a') - all64Compile project(':ijkplayer-arm64') - all64Compile project(':ijkplayer-x86') - all64Compile project(':ijkplayer-x86_64') + //all32Compile project(':ijkplayer-armv5') + implementation project(':ijkplayer-armv7a') + //all32Compile project(':ijkplayer-x86') + //all64Compile project(':ijkplayer-armv5') + //all64Implementation project(':ijkplayer-armv7a') + //all64Compile project(':ijkplayer-arm64') + //all64Compile project(':ijkplayer-x86') + //all64Compile project(':ijkplayer-x86_64') // compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8' // compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'
android/ijkplayer/settings.gradle
--- a/android/ijkplayer/settings.gradle
+++ b/android/ijkplayer/settings.gradle
@@ -1,7 +1,7 @@
-include ':ijkplayer-armv5', ':ijkplayer-x86_64'
+//include ':ijkplayer-armv5', ':ijkplayer-x86_64'
include ':ijkplayer-armv7a'
-include ':ijkplayer-arm64'
-include ':ijkplayer-x86'
+//include ':ijkplayer-arm64'
+//include ':ijkplayer-x86'
include ':ijkplayer-java'
include ':ijkplayer-exo'
解决No version of NDK matched the requested version编译报错的问题
设置NDK路径即可
找不到库:
defaultConfig {
applicationId "tv.danmaku.ijk.media.example"
minSdkVersion 9
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName
externalNativeBuild{
ndk{
abiFilters 'armeabi-v7a'
}
}
}
|–/home/anson/work/importProjs/ijkplayer/android/contrib/build/ffmpeg-armv7a/toolchain/bin//arm-linux-androideabi-gcc
ERROR: jni not found
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-all-videos", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-hevc", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");
总的来说,ijkplayer 的使用与系统的MediaPlayer很相近。一些优化和延迟可以参考文末的链接。
PS: 若需要频繁切换播放源,特别是一些在线视频,不要吝啬多创建几个ijkplayer的实例,实例的复用不见得可以省多少资源,反而会带来许多意料之外的问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。