赞
踩
1.2.1 配置ffmpeg模块路径FFMPEG_MODULE_PATH
1.2.6 在 FFmpeg 模块 jni 目录中添加指向源代码的链接。
1.3.1 问题1 make: command not found
3.2 创建FfmpegRenderersFactory.java文件
Android项目中需要使用Exoplayer接收RTSP流进行解码显示。
在解码过程中出现无法解码AAC音频的问题( aacDecoder_DecodeFrame decoderErr = 0x0005),因此决定在Exoplayer中引入FFMpeg扩展,进行音频解码。
google的官方指导:https://github.com/google/ExoPlayer/tree/release-v2/extensions/ffmpeg
系统:ubuntu-20.04.6-desktop-amd64.iso
Exoplayer源码:ExoPlayer-r2.16.0
JAVA版本:JAVA11
因为在windows里面使用的是java1.8,所以一开始linux里面也使用同样的1.8版本。在exoplayer交叉编译的时候,提示需要使用JAVA11。
NDK:r21e
一开始是用windows的android studio的ndk文件夹,后来发现需要下载Linux版本的。( android-ndk-r21e-linux-x86_64.zip)
下载路径:下载路径
- cd "Exoplayer工程目录"
- FFMPEG_MODULE_PATH="$(pwd)/extensions/ffmpeg/src/main"
NDK_PATH="NDK的安装目录"
Linux 使用linux-x86_64,Mac OS X 使用 darwin-x86_64。
HOST_PLATFORM="linux-x86_64"
- cd "Ffmpeg工程目录"
- FFMPEG_PATH="$(pwd)"
FFMPEG支持的解码器类型可以查阅:Supported formats - ExoPlayer
ENABLED_DECODERS=(vorbis opus flac aac ac3 mp3)
- cd "${FFMPEG_MODULE_PATH}/jni" && \
- ln -s "$FFMPEG_PATH" ffmpeg
执行build_ffmpeg.sh,为 armeabi-v7a、arm64-v8a、x86 和 x86_64 构建 FFmpeg。
如果需要针对不同的体系结构进行构建,可以编辑该脚本。
我图省事,直接全部编译了。
- cd "${FFMPEG_MODULE_PATH}/jni" && \
- ./build_ffmpeg.sh \
- "${FFMPEG_MODULE_PATH}" "${NDK_PATH}" "${HOST_PLATFORM}" "${ENABLED_DECODERS[@]}"
出现错误:-bash: make: command not found
原因分析:因为安装系统的时候使用的是最小化mini安装,系统没有安装make、vim等常用命令,直接sudo apt-get install安装下即可。
解决方案:
- sudo apt-get update
- sudo apt-get install gcc automake autoconf libtool make
出现错误:编译中出现的错误,都可以通过查阅“ffbuild/config.log”文件查阅。
- If you think configure made a mistake, make sure you are using the latest
- version from Git. If the latest version fails, report the problem to the
- ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.libera.chat.
- Include the log file "ffbuild/config.log" produced by configure as this will help
- solve the problem.
执行完成之后,ffmpeg项目下会多出一个android-libs,里面是各个平台对应的文件。
在完成上述步骤以后,此时的文件并不能直接在Android系统上使用,需要进行交叉编译。
在ExoPlayer项目根目录,通过执行gradlew生成AAR文件。
./gradlew extension-ffmpeg:assembleRelease
编译中出现如下的SSLException异常,尝试了几种办法都没有解决,后来灵机一动把将VPN断掉,结果就好了。
- Exception in thread "main" javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
- at sun.security.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1533)
- at sun.security.ssl.AppInputStream.available(AppInputStream.java:60)
- at java.io.BufferedInputStream.available(BufferedInputStream.java:410)
- at sun.net.www.MeteredStream.available(MeteredStream.java:170)
- at sun.net.www.http.KeepAliveStream.close(KeepAliveStream.java:85)
- at java.io.FilterInputStream.close(FilterInputStream.java:181)
- at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.close(HttpURLConnection.java:3517)
- at org.gradle.wrapper.Download.downloadInternal(Download.java:71)
- at org.gradle.wrapper.Download.download(Download.java:42)
- at org.gradle.wrapper.Install$1.call(Install.java:57)
- at org.gradle.wrapper.Install$1.call(Install.java:44)
- at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:65)
- at org.gradle.wrapper.Install.createDist(Install.java:44)
- at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:126)
- at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:56)
Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.
如前所述,交叉编译时需要java11。
sudo apt-get -y install openjdk-11-jdk
在/ExoPlayer/extensions/ffmpeg/buildout/output/aar下生成需要的aar文件。
将编译好的aar文件放在如下路径中。
在build.gradle文件中添加“implementation(fileTree('libs'))”
- dependencies {
- implementation 'androidx.appcompat:appcompat:1.0.0'
- //...
- implementation(fileTree('libs'))
- }
- import android.content.Context;
- import android.os.Handler;
- import com.google.android.exoplayer2.DefaultRenderersFactory;
- import com.google.android.exoplayer2.Renderer;
- import com.google.android.exoplayer2.audio.AudioRendererEventListener;
- import com.google.android.exoplayer2.audio.AudioSink;
- import com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer;
- import com.google.android.exoplayer2.mediacodec.MediaCodecSelector;
- import java.util.ArrayList;
-
- public class FfmpegRenderersFactory extends DefaultRenderersFactory {
- public FfmpegRenderersFactory(Context context) {
- super(context);
- setExtensionRendererMode(EXTENSION_RENDERER_MODE_PREFER);
- }
-
- @Override
- protected void buildAudioRenderers(Context context, int extensionRendererMode, MediaCodecSelector mediaCodecSelector, boolean enableDecoderFallback, AudioSink audioSink, Handler eventHandler, AudioRendererEventListener eventListener, ArrayList<Renderer> out) {
-
- out.add(new FfmpegAudioRenderer());
- super.buildAudioRenderers(context, extensionRendererMode, mediaCodecSelector, enableDecoderFallback, audioSink, eventHandler, eventListener, out);
-
- }
-
- }
ExoPlayer exoPlayer =new ExoPlayer.Builder(getApplicationContext(),new FfmpegRenderersFactory(this)).build();
java文件
- String rtspUri = "rtsp://192.168.1.10:554/live/1_0";
- ExoPlayer exoPlayer = null;
- PlayerView playerView = null;
-
- playerView = findViewById(R.id.styled_player_view);
- exoPlayer =new ExoPlayer.Builder(getApplicationContext(),new FfmpegRenderersFactory(this)).build();
-
- playerView.setPlayer(exoPlayer );
- playerView.clearFocus();
-
- MediaSource mediaSource = new RtspMediaSource.Factory().createMediaSource(MediaItem.fromUri(rtspUri));
- exoPlayer.setMediaSource(mediaSource);
- exoPlayer.prepare();
- exoPlayer.setPlayWhenReady(true);
xml布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <com.google.android.exoplayer2.ui.PlayerView
- android:id="@+id/styled_player_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
- </LinearLayout>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。