SDL2:Android APP编译使用 -- SDL2多媒体库使用音频实例


更多内容:XiaoJ的知识星球


SDL2:Android APP编译使用


SDL2(Simple DirectMedia Layer 2)是一个开源的跨平台多媒体开发库,它提供了一套简洁高效的API,用于处理图形渲染、音频播放、输入设备管理等功能,帮助开发者轻松创建出能在多种操作系统上运行的多媒体应用程序。

3. SDL2:Android APP编译使用

参考:https://github.com/mayzelf/SDL2/blob/release-2.28.4/docs/README-android.md

3.1 Android Studio环境准备:

(1)安装JDK、Android Studio

(2)安装Android SDK、Android NDK

shell 复制代码
export AS_DIR=$MY_ENV_HOME/App/Android_Studio/android-studio-2022.1.1.19
export ANDROID_HOME=$MY_ENV_HOME/App/Android_Studio/Android-2022.1.1.19
export ANDROID_NDK_HOME=$ANDROID_HOME/Sdk/ndk/28.0.12674087
export PATH=$PATH:$AS_DIR

3.2 构建Android APP

先下载SDL2源代码,SDL2官方网站下载或以下方式:

shell 复制代码
wget https://www.libsdl.org/release/SDL2-2.28.4.tar.gz
tar -zxvf SDL2-2.28.4.tar.gz
mv  SDL2-2.28.4   /home/SDL

有以下方式,构建不同程度需求的APK:

(1)方式一:快速构建APK工程
shell 复制代码
cd /home/SDL 
cd build-scripts
./androidbuild.sh org.libsdl.testgles ../test/testgles.c
# 或
# ./androidbuild.sh org.libsdl.audio ../test/*audio*


# 输出
To build and install to a device for testing, run the following:
cd /home/SDL/build/org.libsdl.testgles
./gradlew installDebug
(2)方式二:自定义APK工程

1.将 SDL/android-project 目录复制并重命名,如YOURPROJECT。

2.将 SDL 目录移动或符号链接到 YOURPROJECT/app/jni目录。

3.编辑YOURPROJECT/app/jni/src/Android.mk以包含您的源文件:

  • 它们应该在 LOCAL_SRC_FILES := 声明后用空格分隔

4a.如想用 Android Studio,只需打开您的YOURPROJECT目录并开始构建。

4b. 如要手动构建,在项目目录运行 ./gradlew installDebug。

  • 它将在任何连接的 Android 设备上构建和安装您的 .apk

实际操作如下:

shell 复制代码
# 构建工程目录
cp -rf  SDL/android-project/  YOURPROJECT
cp -rf  SDL  YOURPROJECT/app/jni/SDL

# APK工程相应修改
    # (1) 替换源和gradle版本:
    # 打开YOURPROJECT/gradle/wrapper/gradle-wrapper.properties
    #distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
    distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.5-bin.zip
    # 打开YOURPROJECT/build.gradle
        // classpath 'com.android.tools.build:gradle:8.1.1'
        classpath 'com.android.tools.build:gradle:7.4.0'

    # (2) 添加音频权限声明: 在AndroidManifest.xml中添加
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>

    # (3) 生成源文件:YOURPROJECT/app/jni/src/*.cpp(例如testSDL2.cpp, 代码详情附在下面)
    # 在YOURPROJECT/app/jni/src/Android.mk中,"LOCAL_SRC_FILES := " 声明*.cpp后用空格分隔

# 编译运行apk
  # 方式一:用 Android Studio构建
  # 方式二:运行 ./gradlew installDebug
cpp 复制代码
#include "SDL.h"

#include <stdlib.h>
#include <stdio.h>

static SDL_AudioSpec spec;
static SDL_AudioDeviceID devid_in = 0;
static SDL_AudioDeviceID devid_out = 0;

static void
audio_callback(void *userdata, Uint8 *stream, int len)
{
    // 这里可以添加音频处理逻辑
    SDL_Log("标志:音频回调函数被调用,数据长度 = %d\n", len);
}

int main(int argc, char **argv)
{
    SDL_AudioSpec wanted;
    int devcount;
    int i;

    /* 启用标准应用程序日志 */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    /* 加载SDL库 */
    if (SDL_Init(SDL_INIT_AUDIO) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "标志:无法初始化SDL: %s\n", SDL_GetError());
        return 1;
    }

    SDL_Log("标志:使用的音频驱动: %s\n", SDL_GetCurrentAudioDriver());

    devcount = SDL_GetNumAudioDevices(SDL_TRUE);
    for (i = 0; i < devcount; i++) {
        SDL_Log("标志:捕获设备 #%d: '%s'\n", i, SDL_GetAudioDeviceName(i, SDL_TRUE));
    }

	SDL_zero(wanted);
	wanted.freq = 44100;  // 采样率
	wanted.format = AUDIO_S16SYS;  // 格式
	wanted.channels = 1;  // 通道数
	wanted.samples = 1024;  // 样本数
	wanted.callback = audio_callback;

    SDL_zero(spec);

    /* 打开默认播放设备 */
    SDL_Log("标志:打开默认播放设备...\n");
    devid_out = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wanted, &spec, SDL_AUDIO_ALLOW_ANY_CHANGE);
    if (!devid_out) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "标志:无法打开音频播放设备: %s!\n", SDL_GetError());
        SDL_Quit();
        exit(1);
    }

    /* 打开默认捕获设备 */
    SDL_Log("标志:打开默认捕获设备...\n");
    // devid_in = SDL_OpenAudioDevice(NULL, SDL_TRUE, &spec, &spec, 0);
    devid_in = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(0, SDL_TRUE), SDL_TRUE, &spec, &spec, 0);
    if (!devid_in) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "标志:无法打开音频捕获设备: %s!\n", SDL_GetError());
        SDL_Quit();
        exit(1);
    }

    SDL_Log("标志:音频设备成功打开!\n");

    /* 启动音频播放和捕获 */
    SDL_PauseAudioDevice(devid_out, 0);
    SDL_PauseAudioDevice(devid_in, 0);

    SDL_Log("标志:音频播放和捕获已启动。按回车键停止。\n");

    /* 等待用户输入停止 */
    getchar();

    /* 停止音频播放和捕获 */
    SDL_PauseAudioDevice(devid_out, 1);
    SDL_PauseAudioDevice(devid_in, 1);

    SDL_Log("标志:关闭音频设备。\n");

    /* 关闭音频设备 */
    SDL_CloseAudioDevice(devid_out);
    SDL_CloseAudioDevice(devid_in);

    /* 退出SDL库 */
    SDL_Quit();

    return 0;
}
(3)方式三:CMake构建APK工程

1.将 SDL/android-project 目录复制并重命名,如YOURPROJECT。

2.将 SDL 目录移动或符号链接到 YOURPROJECT/app/jni目录。

3.编辑YOURPROJECT/app/build.gradle:注掉 ndk-build 的部分,取消注释 cmake 部分。向CMake调用添加参数。

4.编辑YOURPROJECT/app/jni/CMakeLists.txt以包含您的项目(默认添加src子目录):

  • 请注意,您的项目中将 SDL2、SDL2main 和 SDL2-static 作为目标,因此您的 CMakeLists.txt 文件中应该有target_link_libraries(yourgame SDL2 SDL2main)。

  • 另请注意,对包含main函数的目标,应使用add_library()而不是add_executable()。

5a. 如想用 Android Studio,只需打开您的YOURPROJECT目录并开始构建。

6b. 如要手动构建,在项目目录运行 ./gradlew installDebug。

  • 它将在任何连接的 Android 设备上构建和安装您的 .apk

3.3 android-project 项目文件说明

bash 复制代码
android-project/app
    build.gradle            - 构建信息,包括应用程序版本和SDK
    src/main/AndroidManifest.xml    - 包清单。其中包含主Activity的类名和应用程序的包名等信息。
    jni/                    - 存放原生代码的目录
    jni/Application.mk      - 应用程序JNI设置,包括目标平台和STL库
    jni/Android.mk          - 可递归调用所有子目录中Android.mk文件的Android makefile
    jni/CMakeLists.txt      - 顶级CMake项目,将SDL作为子项目添加
    jni/SDL/                - (指向)存放SDL库文件的目录
    jni/SDL/Android.mk      - 创建SDL共享库的Android makefile
    jni/src/                - 存放C/C++源代码的目录
    jni/src/Android.mk      - 你应该定制的Android makefile,用于包含源代码和任何库引用
    jni/src/CMakeLists.txt  - 你可以定制的CMake文件,用于包含源代码和任何库引用
    src/main/assets/        - 存放应用程序资产文件的目录
    src/main/res/           - 存放应用程序资源的目录
    src/main/res/mipmap-*   - 存放不同手机硬件图标文件的目录
    src/main/res/values/strings.xml - 应用程序中使用的字符串,包括应用程序名称
    src/main/java/org/libsdl/app/SDLActivity.java - 处理SDL初始化和绑定的Java类。要非常小心地修改这个类,因为SDL库依赖于这个实现。你应该为你的应用程序继承这个类。

.


声明:资源可能存在第三方来源,若有侵权请联系删除!

相关推荐
千里马学框架5 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台5 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone5 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc5 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo5 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077005 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone5 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen5 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone5 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui