当前位置:   article > 正文

在ExoPlayer中使用ffmpeg进行音频解码(编译和使用)_exoplayer ffmpeg

exoplayer ffmpeg

本文目录

1 Ubuntu环境下编译ffmpeg

1.1 环境准备

1.1.1 Ubuntu系统

1.1.2 Exoplayer源码

1.1.3 JAVA

1.1.4 NDK

1.2 编译ffmpeg源码

1.2.1 配置ffmpeg模块路径FFMPEG_MODULE_PATH

1.2.2 配置NDK环境变量NDK_PATH

1.2.3 设置主机平台变量

1.2.4 设置ffmpeg路径FFMPEG_PATH

1.2.5 设置解码器类型

1.2.6 在 FFmpeg 模块 jni 目录中添加指向源代码的链接。

1.2.7 编译

1.3 编译时出现的问题

1.3.1 问题1 make: command not found

1.3.2 问题2

1.4 编译结果

2 交叉编译AAR文件

2.1 编译

2.2 编译中出现的问题

2.2.1 SSLException

2.2.2 Java版本异常

2.3 编译结果

3 在Android工程中引入ffmpeg

3.1 在android studio里面引入aar

3.2 创建FfmpegRenderersFactory.java文件

3.3 创建播放器实例

3.4 播放rtsp代码


Android项目中需要使用Exoplayer接收RTSP流进行解码显示。

在解码过程中出现无法解码AAC音频的问题( aacDecoder_DecodeFrame decoderErr = 0x0005),因此决定在Exoplayer中引入FFMpeg扩展,进行音频解码。

google的官方指导:https://github.com/google/ExoPlayer/tree/release-v2/extensions/ffmpeg

1 Ubuntu环境下编译ffmpeg

1.1 环境准备

1.1.1 Ubuntu系统

系统:ubuntu-20.04.6-desktop-amd64.iso

1.1.2 Exoplayer源码

 Exoplayer源码:ExoPlayer-r2.16.0

1.1.3 JAVA

JAVA版本:JAVA11

因为在windows里面使用的是java1.8,所以一开始linux里面也使用同样的1.8版本。在exoplayer交叉编译的时候,提示需要使用JAVA11。

1.1.4 NDK

NDK:r21e

一开始是用windows的android studio的ndk文件夹,后来发现需要下载Linux版本的。( android-ndk-r21e-linux-x86_64.zip)

下载路径:下载路径 

1.2 编译ffmpeg源码

1.2.1 配置ffmpeg模块路径FFMPEG_MODULE_PATH

  1. cd "Exoplayer工程目录"
  2. FFMPEG_MODULE_PATH="$(pwd)/extensions/ffmpeg/src/main"

1.2.2 配置NDK环境变量NDK_PATH

NDK_PATH="NDK的安装目录"

1.2.3 设置主机平台变量

Linux 使用linux-x86_64,Mac OS X 使用 darwin-x86_64。

HOST_PLATFORM="linux-x86_64"

1.2.4 设置ffmpeg路径FFMPEG_PATH

  1. cd "Ffmpeg工程目录"
  2. FFMPEG_PATH="$(pwd)"

1.2.5 设置解码器类型

FFMPEG支持的解码器类型可以查阅:Supported formats - ExoPlayer

ENABLED_DECODERS=(vorbis opus flac aac ac3 mp3)

1.2.6 在 FFmpeg 模块 jni 目录中添加指向源代码的链接。

  1. cd "${FFMPEG_MODULE_PATH}/jni" && \
  2. ln -s "$FFMPEG_PATH" ffmpeg

1.2.7 编译

执行build_ffmpeg.sh,为 armeabi-v7a、arm64-v8a、x86 和 x86_64 构建 FFmpeg。

如果需要针对不同的体系结构进行构建,可以编辑该脚本。

我图省事,直接全部编译了。

  1. cd "${FFMPEG_MODULE_PATH}/jni" && \
  2. ./build_ffmpeg.sh \
  3. "${FFMPEG_MODULE_PATH}" "${NDK_PATH}" "${HOST_PLATFORM}" "${ENABLED_DECODERS[@]}"

1.3 编译时出现的问题

1.3.1 问题1 make: command not found

出现错误:-bash: make: command not found

原因分析:因为安装系统的时候使用的是最小化mini安装,系统没有安装make、vim等常用命令,直接sudo apt-get install安装下即可。 

解决方案:

  1. sudo apt-get update
  2. sudo apt-get install gcc automake autoconf libtool make

1.3.2 问题2

出现错误:编译中出现的错误,都可以通过查阅“ffbuild/config.log”文件查阅。

  1. If you think configure made a mistake, make sure you are using the latest
  2. version from Git. If the latest version fails, report the problem to the
  3. ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.libera.chat.
  4. Include the log file "ffbuild/config.log" produced by configure as this will help
  5. solve the problem.

1.4 编译结果

执行完成之后,ffmpeg项目下会多出一个android-libs,里面是各个平台对应的文件。

2 交叉编译AAR文件

2.1 编译

在完成上述步骤以后,此时的文件并不能直接在Android系统上使用,需要进行交叉编译。

在ExoPlayer项目根目录,通过执行gradlew生成AAR文件。

./gradlew extension-ffmpeg:assembleRelease

2.2 编译中出现的问题

2.2.1 SSLException

编译中出现如下的SSLException异常,尝试了几种办法都没有解决,后来灵机一动把将VPN断掉,结果就好了。

  1. Exception in thread "main" javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
  2. at sun.security.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1533)
  3. at sun.security.ssl.AppInputStream.available(AppInputStream.java:60)
  4. at java.io.BufferedInputStream.available(BufferedInputStream.java:410)
  5. at sun.net.www.MeteredStream.available(MeteredStream.java:170)
  6. at sun.net.www.http.KeepAliveStream.close(KeepAliveStream.java:85)
  7. at java.io.FilterInputStream.close(FilterInputStream.java:181)
  8. at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.close(HttpURLConnection.java:3517)
  9. at org.gradle.wrapper.Download.downloadInternal(Download.java:71)
  10. at org.gradle.wrapper.Download.download(Download.java:42)
  11. at org.gradle.wrapper.Install$1.call(Install.java:57)
  12. at org.gradle.wrapper.Install$1.call(Install.java:44)
  13. at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:65)
  14. at org.gradle.wrapper.Install.createDist(Install.java:44)
  15. at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:126)
  16. at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:56)

2.2.2 Java版本异常

Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.

如前所述,交叉编译时需要java11。

 sudo apt-get -y install openjdk-11-jdk

2.3 编译结果

在/ExoPlayer/extensions/ffmpeg/buildout/output/aar下生成需要的aar文件。

3 在Android工程中引入ffmpeg

3.1 在android studio里面引入aar

将编译好的aar文件放在如下路径中。

在build.gradle文件中添加“implementation(fileTree('libs'))”

  1. dependencies {
  2. implementation 'androidx.appcompat:appcompat:1.0.0'
  3. //...
  4. implementation(fileTree('libs'))
  5. }

3.2 创建FfmpegRenderersFactory.java文件

  1. import android.content.Context;
  2. import android.os.Handler;
  3. import com.google.android.exoplayer2.DefaultRenderersFactory;
  4. import com.google.android.exoplayer2.Renderer;
  5. import com.google.android.exoplayer2.audio.AudioRendererEventListener;
  6. import com.google.android.exoplayer2.audio.AudioSink;
  7. import com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer;
  8. import com.google.android.exoplayer2.mediacodec.MediaCodecSelector;
  9. import java.util.ArrayList;
  10. public class FfmpegRenderersFactory extends DefaultRenderersFactory {
  11. public FfmpegRenderersFactory(Context context) {
  12. super(context);
  13. setExtensionRendererMode(EXTENSION_RENDERER_MODE_PREFER);
  14. }
  15. @Override
  16. protected void buildAudioRenderers(Context context, int extensionRendererMode, MediaCodecSelector mediaCodecSelector, boolean enableDecoderFallback, AudioSink audioSink, Handler eventHandler, AudioRendererEventListener eventListener, ArrayList<Renderer> out) {
  17. out.add(new FfmpegAudioRenderer());
  18. super.buildAudioRenderers(context, extensionRendererMode, mediaCodecSelector, enableDecoderFallback, audioSink, eventHandler, eventListener, out);
  19. }
  20. }

3.3 创建播放器实例

ExoPlayer exoPlayer =new ExoPlayer.Builder(getApplicationContext(),new FfmpegRenderersFactory(this)).build();

3.4 播放rtsp代码

java文件

  1. String rtspUri = "rtsp://192.168.1.10:554/live/1_0";
  2. ExoPlayer exoPlayer = null;
  3. PlayerView playerView = null;
  4. playerView = findViewById(R.id.styled_player_view);
  5. exoPlayer =new ExoPlayer.Builder(getApplicationContext(),new FfmpegRenderersFactory(this)).build();
  6. playerView.setPlayer(exoPlayer );
  7. playerView.clearFocus();
  8. MediaSource mediaSource = new RtspMediaSource.Factory().createMediaSource(MediaItem.fromUri(rtspUri));
  9. exoPlayer.setMediaSource(mediaSource);
  10. exoPlayer.prepare();
  11. exoPlayer.setPlayWhenReady(true);

xml布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="horizontal">
  6. <com.google.android.exoplayer2.ui.PlayerView
  7. android:id="@+id/styled_player_view"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"/>
  10. </LinearLayout>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/568919
推荐阅读
  

闽ICP备14008679号