在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

cd "Exoplayer工程目录"
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

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

1.2.5 设置解码器类型

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

ENABLED_DECODERS=(vorbis opus flac aac ac3 mp3)

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

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

1.2.7 编译

执行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[@]}"

1.3 编译时出现的问题

1.3.1 问题1 make: command not found

出现错误:-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

1.3.2 问题2

出现错误:编译中出现的错误,都可以通过查阅“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.

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断掉,结果就好了。

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)

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'))”

dependencies {
    implementation 'androidx.appcompat:appcompat:1.0.0'
    //...
    implementation(fileTree('libs'))
}

3.2 创建FfmpegRenderersFactory.java文件

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);

    }

}

3.3 创建播放器实例

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

3.4 播放rtsp代码

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>

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值