第一节 安装Android Studio 3.5.3

Android Studio 3.5.3下载地址:

Android Studio 3.5.3 December 5, 2019
Windows (32-bit): android-studio-ide-191.6010548-windows32.zip (756.1 MB)
https://redirector.gvt1.com/edgedl/android/studio/ide-zips/3.5.3.0/android-studio-ide-191.6010548-windows32.zip
解压后运行bin/studio.exe。Windows (64-bit): android-studio-ide-191.6010548-windows.zip (756.6 MB)
https://redirector.gvt1.com/edgedl/android/studio/ide-zips/3.5.3.0/android-studio-ide-191.6010548-windows.zip
解压后运行bin/studio64.exe。

Android Studio自带JRE,不需要事先安装Java。

Android Studio 3.5.3可以在Win7 SP1系统下直接解压使用。
如果是XP SP3或者64位XP SP2系统的话就必须要先安装one core api 4.0.1,否则运行不了studio.exe或者studio64.exe。
one core api 4.0.1下载地址:https://github.com/shorthorn-project/One-Core-API-Binaries/releases/download/4.0.1/One-Core-API-Binaries-4.0.1.zip
安装完成后重启电脑。

本人用的是64位Windows XP SP2系统,one core api 4.0.1安装完成后就可以成功运行studio64.exe了。

出现下面的窗口时点Cancel就行。

默认的Android SDK下载路径C:\Documents and Settings\Administrator\AppData\Local\Android\Sdk是有空格的,必须要改。
例如改成D:\Android\Sdk,路径中一定不能有空格。

下载过程中如果失败就多Retry几次。本人就遇到过几次域名解析失败,但过几分钟又能下载了。

下载完点击Finish按钮,就可以安装成功了。

第二节 建立普通Java安卓工程并运行

点击Start a new Android Studio project。

选择Empty Activity。

Save location要改成一个没有空格的路径,默认的路径C:\Documents and Settings\Administrator\AndroidStudioProjects\MyApplication是有空格的,是不能使用的。
Language要改成Java。
改完后点击Finish按钮。

进入工程后会下载gradle-5.4.1-all.zip,但是下载要很长时间。为了避免每次创建新工程都要下载一遍,可以在浏览器中下载https://services.gradle.org/distributions/gradle-5.4.1-all.zip,保存到D:\Android文件夹中。
修改工程里面的gradle-wrapper.properties文件(如F:\Projects\AndroidStudioProjects\MyApplication\gradle\wrapper\gradle-wrapper.properties)
把里面的distributionUrl改成file:///D:/Android/gradle-5.4.1-all.zip。
重启Android Studio,点击菜单栏里面的File->Sync Project with Gradle Files,就可以立即下载完成了。

点击解除阻止:

完了之后报了一个错误:ERROR: Cause: unable to find valid certification path to requested target
解决办法是打开Gradle Scripts下面的build.gradle (Project: My Application)文件,将里面的两处google()修改成maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' },两处jcenter()修改成maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'},改完后点击一下上面的Try Again。

adb解除一下阻止:

sync成功:

sync成功后,就可以打开app/res/layout/activity_main.xml,看到可视化设计界面了。

现在我们尝试生成一下apk安装包。点击菜单栏的Build -> Make Project命令。
build失败,报错:
AAPT: aapt2.exe E 08-22 19:42:48  2296  2152 LoadedArsc.cpp:112] RES_TABLE_TYPE_TYPE entry offsets overlap actual entry data.
aapt2.exe E 08-22 19:42:48  2296  2152 ApkAssets.cpp:157] Failed to load 'resources.arsc' in APK 'D:\Android\Sdk\platforms\android-36\android.jar'.
error: failed to load include path D:\Android\Sdk\platforms\android-36\android.jar.

解决办法是打开Gradle Scripts下面的build.gradle (Module: app)文件。
compileSdkVersion改成28
buildToolsVersion改成"28.0.3"
targetSdkVersion改成28

改完后点击右上角的Sync Now,等一会后报错:
ERROR: Failed to install the following Android SDK packages as some licences have not been accepted.
build-tools;28.0.3 Android SDK Build-Tools 28.0.3
platforms;android-28 Android SDK Platform 28
To build this project, accept the SDK license agreements and install the missing components using the Android Studio SDK Manager.
Alternatively, to transfer the license agreements from one workstation to another, see http://d.android.com/r/studio-ui/export-licenses.html

Using Android SDK: D:\Android\Sdk
Install missing SDK package(s)

点击Install missing SDK package(s),接受一下协议。

点击Finish后,再点击一下Build->Make Project菜单,就成功了。
可以在F:\Projects\AndroidStudioProjects\MyApplication\app\build\outputs\apk\debug下成功生成app-debug.apk。

现在我们尝试一下在命令行中安装这个apk到手机上运行。

安卓手机USB驱动下载地址:https://www.onlinedown.net/soft/1116709.htm
ADB Interface驱动所在文件夹:1510571328_36999_ysy\adb_interface_usb_driver
这个驱动适用于32位和64位的XP和Win7系统。

首先用USB数据线连接手机和电脑,电脑提示发现新硬件。

开始->运行->cmd打开命令行窗口,运行命令:
D:\Android\Sdk\platform-tools\adb.exe install -t F:\Projects\AndroidStudioProjects\MyApplication\app\build\outputs\apk\debug\app-debug.apk
手机上要允许一下USB Debugging。

进度一直卡住不动,什么都不输出。这是因为,最新版本的Android SDK Platform-Tools 36.0.0已经不支持XP和Win7系统了,无法正常运行。
去网上下载旧版本的platform-tools:https://dl.google.com/android/repository/platform-tools_r23.1.0-windows.zip。
下载完后先关闭Android Studio,重启一下电脑。
重启电脑后先不要打开Android Studio,先把D:\Android\Sdk\platform-tools文件夹删除掉,把刚刚下载的platform-tools_r23.1.0-windows.zip里面的platform-tools文件夹解压到D:\Android\Sdk。

再在命令行中运行一下D:\Android\Sdk\platform-tools\adb.exe install -t F:\Projects\AndroidStudioProjects\MyApplication\app\build\outputs\apk\debug\app-debug.apk命令,就成功了。

这个时候再打开Android Studio,点击Run -> Run 'app'菜单,也能成功安装apk到手机上运行。

可以看到手机上的logcat:

因为XP系统没有Powershell,所以Terminal窗格无法使用,要Win7下才能使用。

在SDK Manager里面可以看到,Android SDK Platform-Tools的版本号是23.1。

第三节 建立Native C++安卓工程并运行

先把上一节的工程关了:

然后新建一个Native C++工程:

进去之后还是一样的先把distributionUrl改成file:///D:/Android/gradle-5.4.1-all.zip,因为从网上下载会失败。改完后一定要重启Android Studio,点击菜单栏里面的File->Sync Project with Gradle Files。

ERROR: Cause: unable to find valid certification path to requested target
一样的解决方法,打开Gradle Scripts下面的build.gradle (Project: My Application)文件,将里面的两处google()修改成maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' },两处jcenter()修改成maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'},改完后点击一下上面的Try Again。

完了之后会要求我们安装NDK。
ERROR: Failed to install the following Android SDK packages as some licences have not been accepted.
ndk;29.0.13846066 NDK (Side by side) 29.0.13846066
To build this project, accept the SDK license agreements and install the missing components using the Android Studio SDK Manager.
Alternatively, to transfer the license agreements from one workstation to another, see http://d.android.com/r/studio-ui/export-licenses.html

Using Android SDK: D:\Android\Sdk

NDK 29.0.13846066版本太高,与Android Studio 3.5.3不匹配,一定要安装低版本的NDK。
在当前工程Sync失败的情况下,Tools菜单下是没有SDK Manager命令的,只能从File -> Settings菜单打开。
从File -> Settings菜单打开Settings窗口后,左边展开Apperance & Behavior -> System Settings -> Android SDK。
右边打开SDK Tools选项卡,勾选下面的Show Package Details,然后勾选安装NDK (Side by side) 21.0.6113669版本。

装完NDK后,点击File -> Project Structure菜单。

左边选择SDK Location,右边Android NDK location选择NDK的路径D:\Android\Sdk\ndk\21.0.6113669。

ERROR: CMake '3.10.2' was not found in PATH or by cmake.dir property.
Install CMake 3.10.2
点击Install CMake 3.10.2链接安装cmake。

ERROR: CMake '3.10.2' was not found in PATH or by cmake.dir property.
Set cmake.dir in local.properties to D:\Android\Sdk\cmake\3.10.2.4988404
点击Set cmake.dir in local.properties to D:\Android\Sdk\cmake\3.10.2.4988404链接,就可以成功了。
上面的Unable to execute Clang-Tidy: Cannot create property=Diagnostics for JavaBean=com.jetbrains.cidr.lang.daemon.clang.tidy.ClangTidyYamlLoader$YamlData@9aedf45 in 'string', line 2, column 1:    MainSourceFile:   'F:\Projects\An不用管,不影响工程的编译和运行。

Build -> Make Project生成apk安装包。

AAPT: aapt2.exe E 08-22 20:53:53  2724  1520 LoadedArsc.cpp:112] RES_TABLE_TYPE_TYPE entry offsets overlap actual entry data.
aapt2.exe E 08-22 20:53:53  2724  1520 ApkAssets.cpp:157] Failed to load 'resources.arsc' in APK 'D:\Android\Sdk\platforms\android-36\android.jar'.
error: failed to load include path D:\Android\Sdk\platforms\android-36\android.jar.

修改build.gradle (Module: app)文件。
compileSdkVersion改成28
buildToolsVersion改成"28.0.3"
targetSdkVersion改成28
Sync一下,然后再次Make Project,成功。

Run -> Run 'app',成功。

第四节 下载并使用C++ Oboe音频库

Android Studio 3.5.3可以成功导入oboe-1.9.0,但无法成功导入最新版的oboe-1.9.3。
https://github.com/google/oboe/archive/refs/tags/1.9.0.zip(Jun 26, 2024)
https://github.com/google/oboe/archive/refs/tags/1.9.3.zip(Dec 18, 2024)
把oboe-1.9.0.zip下载下来,然后解压到一个没有空格的文件夹里面,如D:\Android。

打开app/src/main/cpp/CMakeLists.txt文件,找到末尾的target_link_libraries,在括号里面添加oboe。
然后在下面添加:
set(OBOE_DIR D:\\Android\\oboe-1.9.0)
add_subdirectory(${OBOE_DIR} ./oboe)
include_directories(${OBOE_DIR}/include)

修改完成后,点击菜单栏里面的Build -> Refresh Linked C++ Projects,然后再Build -> Make Project。

修改代码。
【com/example/myapplication/MainActivity.java】

package com.example.myapplication;import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// Example of a call to a native methodtextView = findViewById(R.id.sample_text);}@Overrideprotected void onPause() {super.onPause();stringFromJNI("stop");textView.setText(stringFromJNI("log"));}@Overrideprotected void onResume() {super.onResume();stringFromJNI("start");}/*** A native method that is implemented by the 'native-lib' native library,* which is packaged with this application.*/public native String stringFromJNI(String message);// Used to load the 'native-lib' library on application startup.static {System.loadLibrary("native-lib");}
}

【native-lib.cpp】

#include <jni.h>
#include <string>
#include <oboe/Oboe.h>class OboeSinePlayer: public oboe::AudioStreamDataCallback {
public:OboeSinePlayer() : logCount(0) {}virtual ~OboeSinePlayer() = default;// Call this from Activity onResume()int32_t startAudio() {std::lock_guard<std::mutex> lock(mLock);oboe::AudioStreamBuilder builder;// The builder set methods can be chained for convenience.oboe::Result result = builder.setSharingMode(oboe::SharingMode::Exclusive)->setPerformanceMode(oboe::PerformanceMode::LowLatency)->setChannelCount(kChannelCount)->setSampleRate(kSampleRate)->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::Medium)->setFormat(oboe::AudioFormat::Float)->setDataCallback(this)->openStream(mStream);if (result != oboe::Result::OK) return (int32_t) result;// Typically, start the stream after querying some stream information, as well as some input from the userresult = mStream->requestStart();return (int32_t) result;}// Call this from Activity onPause()void stopAudio() {// Stop, close and delete in case not already closed.std::lock_guard<std::mutex> lock(mLock);if (mStream) {mStream->stop();mStream->close();mStream.reset();}}oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override {println("onAudioReady: numFrames=%d", numFrames);float *floatData = (float *) audioData;for (int i = 0; i < numFrames; ++i) {float sampleValue = kAmplitude * sinf(mPhase);for (int j = 0; j < kChannelCount; j++) {floatData[i * kChannelCount + j] = sampleValue;}mPhase += mPhaseIncrement;if (mPhase >= kTwoPi) mPhase -= kTwoPi;}return oboe::DataCallbackResult::Continue;}std::string getLog() {std::string log = this->log;this->log.clear();return log;}private:std::mutex         mLock;std::shared_ptr<oboe::AudioStream> mStream;// Stream paramsstatic int constexpr kChannelCount = 2;static int constexpr kSampleRate = 48000;// Wave params, these could be instance variables in order to modify at runtimestatic float constexpr kAmplitude = 0.5f;static float constexpr kFrequency = 440;static float constexpr kPI = M_PI;static float constexpr kTwoPi = kPI * 2;static double constexpr mPhaseIncrement = kFrequency * kTwoPi / (double) kSampleRate;// Keeps track of where the wave isfloat mPhase = 0.0;std::string log;int logCount;void println(const char *fmt, ...) {char header[30];char buffer[256];va_list list;va_start(list, fmt);vsnprintf(buffer, sizeof(buffer), fmt, list);va_end(list);if (log.empty() || logCount % 100 != 0) {if (!log.empty()) {log += "\n";}snprintf(header, sizeof(header), "[%d] ", logCount);log += header;log += buffer;logCount++;}}
};OboeSinePlayer player;extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(JNIEnv* env,jobject that , jstring message) {std::string hello = "Hello from C++";const char *messageCstr = env->GetStringUTFChars(message, nullptr);if (messageCstr != nullptr) {if (strcmp(messageCstr, "start") == 0) {player.startAudio();} else if (strcmp(messageCstr, "stop") == 0) {player.stopAudio();} else if (strcmp(messageCstr, "log") == 0) {hello = player.getLog();}env->ReleaseStringUTFChars(message, messageCstr);}return env->NewStringUTF(hello.c_str());
}

【layout/activity_main.xml】

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/sample_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Hello World!" /></ScrollView></androidx.constraintlayout.widget.ConstraintLayout>

改完代码,Build -> Make Project,然后Run -> Run 'app',在手机上运行。

APP运行后,在手机上能听到Oboe发出的声音,是一段蜂鸣声。
按HOME键(不是返回键)关闭APP,停止播放声音。再重新打开APP,又开始播放声音了,而且APP上会有日志显示,每次显示100条。这个日志是C++代码里面的println("onAudioReady: numFrames=%d", numFrames);语句打印的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/94188.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/94188.shtml
英文地址,请注明出处:http://en.pswp.cn/web/94188.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

calchash.exe和chckhash.exe计算pe文件hash值的两个实用小工具

第一部分&#xff1a; C:\WINDOWS\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\NT5.CAT t部分内容B B D 0 2 2 2 1 A A 6 5 5 6 2 8 F 4 9 5 F 6 C D 3 0 3 9 0 8 B B E 0 0 F 9 5 9 5 第二部分&#xff1a; D:\>calchash.exe pidgen.dll BB D0 22 21 AA 65 …

lanczso算法中的额外正交化代码解释

额外正交化 定义&#xff1a;在Lanczos算法中&#xff0c;由于浮点误差&#xff0c;生成的向量可能不完全正交&#xff0c;需要额外正交化步骤。代码实现&#xff1a;def extra_orthogonalization(v, basis):for u in basis:v - u * (v.dot(u) / u.dot(u))

Rabbit 实战指南-学习笔记

第 4 章 RabbitMQ 进阶 mandatory 参数 Returning | RabbitMQ 当 mandatory 参数设为 true 时&#xff0c;交换器无法根据自身的类型和路由键找到一个符合条件的队列&#xff0c;那么RabbitMQ 会调用 Basic.Return 命令将消息返回给生产者,通过调用channel.addReturnListener …

BEVDet4D

1. BEVDet4D算法动机及开创性思路 1&#xff09;BEVDet算法概述输入输出&#xff1a;输入为6视角图像&#xff08;NuScenes数据集&#xff09;&#xff0c;输出为3D检测结果核心模块&#xff1a; 图像编码器&#xff1a;由Backbone网络和多尺度特征融合网络组成&#xff0c;处理…

当 AI 学会 “理解” 人类:自然语言处理的进化与伦理边界

大家可以去我的资源看看&#xff0c;有很多关于AI的免费资源可以下载&#xff0c;不下载也可以看看&#xff0c;真的对你有用引言&#xff1a;从 “对话” 到 “理解”——AI 语言能力的时代跃迁现实锚点&#xff1a;以日常场景切入&#xff08;如 ChatGPT 流畅回应复杂问题、A…

WPF控件随窗体大宽度高度改变而改变

前台控件中&#xff1a;Width"{Binding RelativeSource{RelativeSource AncestorTypeWindow}, PathWidth}"后台代码&#xff1a;定义在加载事件里面this.SizeChanged ProductData_SizeChanged;private void ProductData_SizeChanged(object sender, SizeChangedEven…

E10 通过RPC实现账号批量锁定与解锁

需求背景&#xff1a;账号信息由三方系统管理&#xff0c;包含账号状态&#xff0c;所以需要通过提供给三方的 Rest 接口中&#xff0c;实现账号锁定与解锁。参考基线版本&#xff1a;10.0.2506.01&#xff0c;过低的版本可能无法使用。 锁定分为两种&#xff1a; &#xff08;…

什么是AI宠物

什么是AI宠物AI宠物是由AI大脑驱动的生命体AI产品。它能主动产生情绪和意图&#xff0c;并通过情绪和意图去驱动自己的动作和行为。它根据自己的意愿和用户互动&#xff0c;不受用户控制。从一定意义上讲&#xff0c;它拥有了人工生命和自由意志。它有自己的行为逻辑&#xff0…

简单AI:搜狐公司旗下AI绘画产品

本文转载自&#xff1a;简单AI&#xff1a;搜狐公司旗下AI绘画产品 - Hello123工具导航 ** 一、平台定位与技术特性 搜狐简单 AI 是搜狐推出的多模态 AI 创作平台&#xff0c;基于自研大模型提供文生图、文生文等能力。它专注于零门槛内容生成&#xff0c;用户无需专业技能即…

vue3 3d饼图

完整3D饼图项目下载 https://download.csdn.net/download/weixin_54645059/91716476 只有一个vue文件 直接下滑到完整代码就阔以 本文介绍了如何使用ECharts和ECharts-GL插件实现3D饼图效果&#xff0c;并提出了数值显示未解决的问题。主要包含以下内容&#xff1a; 安装所需…

全球电商业财一体化趋势加速,巨益科技助力品牌出海精细化运营

行业背景&#xff1a;跨境电商进入品牌化发展新阶段随着国内电商市场竞争日趋激烈&#xff0c;跨境电商已成为中国品牌寻求增长突破的重要赛道&#xff0c;在TikTok、Temu等平台出海浪潮推动下&#xff0c;越来越多的中国品牌开始布局全球市场。然而&#xff0c;从单一市场的铺…

【序列晋升】13 Spring Cloud Bus微服务架构中的消息总线

Spring Cloud Bus作为微服务架构中的关键组件&#xff0c;通过消息代理实现分布式系统中各节点的事件广播与状态同步&#xff0c;解决了传统微服务架构中配置刷新效率低下、系统级事件传播复杂等问题。它本质上是一个轻量级的事件总线&#xff0c;将Spring Boot Actuator的端点…

[激光原理与应用-314]:光学设计 - 光学系统设计与电子电路设计的相似或相同点

光学系统设计与电子电路设计虽分属不同工程领域&#xff0c;但在设计理念、方法论和工程实践中存在诸多相似或相同点。这些共性源于两者均需解决复杂系统的优化问题&#xff0c;并遵循工程设计的通用规律。以下是具体分析&#xff1a;一、设计流程的相似性需求分析与规格定义光…

Linux学习:信号的保存

目录1. 进程的异常终止与core dump标志位1.1 进程终止的方式1.2 core方案的作用与使用方式2. 信号的保存2.1 信号的阻塞2.2 操作系统中的sigset_t信号集类型2.3 进程PCB中修改block表的系统调用接口2.4 信号阻塞的相关问题验证1. 进程的异常终止与core dump标志位 1.1 进程终止…

数据分析编程第二步: 最简单的数据分析尝试

2.1 数据介绍有某公司的销售数据表 sales.csv 如下:第一行是标题&#xff0c;解释每一列存了什么东西。第二行开始每一行是一条数据&#xff0c;对应一个订单。这种数据有个专业的术语&#xff0c;叫结构化数据。这是现代数据处理中最常见的数据类型。整个表格的数据统称为一个…

UDP报文的数据结构

主要内容参照https://doc.embedfire.com/net/lwip/zh/latest/doc/chapter14/chapter14.html#id6&#xff0c;整理出来自用。 1. UDP 报文首部结构体&#xff08;udp_hdr&#xff09; 为清晰定义 UDP 报文首部的各个字段&#xff0c;LwIP 设计了udp_hdr结构体&#xff0c;其包含…

图论与最短路学习笔记

图论与最短路在数学建模中的应用 一、图论模型图 G(V,E)G(V,E)G(V,E) VVV&#xff1a;顶点集合EEE&#xff1a;边集合每条边 (u,v)(u,v)(u,v) 赋予权值 w(u,v)w(u,v)w(u,v)&#xff0c;可用 邻接矩阵 或 邻接表 表示。二、最短路问题的数学形式 目标&#xff1a;寻找从源点 sss…

第九节 Spring 基于构造函数的依赖注入

当容器调用带有一组参数的类构造函数时&#xff0c;基于构造函数的 DI 就完成了&#xff0c;其中每个参数代表一个对其他类的依赖。接下来&#xff0c;我们将通过示例来理解 Spring 基于构造函数的依赖注入。示例&#xff1a;下面的例子显示了一个类 TextEditor&#xff0c;只能…

【数据库】PostgreSQL详解:企业级关系型数据库

文章目录什么是PostgreSQL&#xff1f;核心特性1. 标准兼容性2. 扩展性3. 高级功能4. 可靠性数据类型1. 基本数据类型2. 高级数据类型基本操作1. 数据库操作2. 表操作3. 数据操作高级查询1. 连接查询2. 子查询3. 窗口函数JSON操作1. JSON数据类型2. JSON查询3. JSON索引全文搜索…

FFMPEG相关解密,打水印,合并,推流,

1&#xff1a;ffmepg进行打水印解密 前提ffmepg安装利用静态版就可以这个什么都有&#xff0c;不用再配置其他信息&#xff1a;&#xff08;这个利用ffmpeg终端命令是没问题的&#xff0c;但是如果要是再C中调用ffmpeg库那么还需要从新编译安装下&#xff09; 各个版本 Inde…