ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

whisper.cpp Android 示例应用实战:在 Android 设备上运行 Whisper 语音转文字(Voice-to-Text)

whisper.cpp Android 示例应用实战:在 Android 设备上运行 Whisper 语音转文字(Voice-to-Text) 人工智能语音音频本地部署推理引擎【免费下载链接】whisper.cppPort of OpenAIs Whisper model in C/C项目地址https://gitcode.com/GitHub_Trending/wh/whisper.cpp点击查看免费下载导读本文围绕 whisper.cpp 仓库中的 Android 示例应用 examples/whisper.android 展开完整讲解如何把一个 Whisper 语音识别模型跑在 Android 手机上从模型下载、资源放置、Android Studio 构建部署到 Kotlin 封装层、JNI 桥接层与 C/C 原生构建的源码级原理。读完本文你将掌握 whisper.cpp 在 Android 端落地的最小可行方案并能按需替换模型、样例音频乃至修改转写参数。示例应用概览用 whisper.cpp 在 Android 上做语音转文字examples/whisper.android 是一个基于 whisper.cpp 的 Android 示例应用功能定位非常明确在 Android 设备上做 voice-to-text语音转文字。它复用 whisper.cpp 的 C/C 推理核心src/whisper.cpp 与 GGML 计算图后端通过 JNI 暴露给 Kotlin 层再以 Jetpack Compose 提供录音、回放、转写、基准测试等交互界面。该目录是一个 Gradle 多模块工程由 settings.gradle 定义:app演示应用主体UI、录音、音频解码、转写编排包名com.whispercppdemo:libwhisper.cpp 的 Android 库封装Kotlin 封装、JNI 桥接、原生 CMake 构建包名com.whispercpp.whisper根工程名WhisperCppDemo依赖仓库google()/mavenCentral()并启用android.useAndroidXtrue等设置见 gradle.propertiesGradle JVM 堆建议-Xmx2048m。需要特别强调的是 README 中的一句提醒不要把这个 android 工程目录单独挪到其他文件夹。原因在于:lib的 CMakeLists.txt 通过WHISPER_LIB_DIR ${CMAKE_SOURCE_DIR}/../../../../../../..反向引用整个 whisper.cpp 仓库根目录直接以源码形式编译src/whisper.cpp和ggml/下的源文件一旦目录结构被破坏原生库将无法编译。快速开始5 步在 Android Studio 中跑起来README 给出的使用流程共 5 步下面结合仓库内容逐条展开确保可直接照做。第一步下载模型并放入app/src/main/assets/models模型须为 whisper.cpp 的 GGML 格式。仓库的 models 目录 提供了转换好的 GGML 模型下载脚本 download-ggml-model.sh脚本支持的模型清单包括基础系列tiny、tiny.en、base、base.en、small、small.en、medium、medium.en、large-v1、large-v2、large-v3、large-v3-turbo量化系列tiny-q5_1、tiny.en-q5_1、tiny-q8_0、base-q5_1、base.en-q5_1、base-q8_0、small-q5_1、small.en-q5_1、small-q8_0、medium-q5_0、medium.en-q5_0、medium-q8_0、large-v2-q5_0、large-v2-q8_0、large-v3-q5_0、large-v3-turbo-q5_0、large-v3-turbo-q8_0等完整列表见脚本内models变量。下载完成后把模型文件复制到app/src/main/assets/models目录。README 脚注特别建议Android 设备上优先使用 tiny 或 base 模型。原因从后续源码也能印证模型会整体加载进内存并参与全部转写计算机型算力与内存受限时较小的模型才能保证可用性仓库同时提供了用于测试的 tiny/base 系列 GGML 模型models/for-tests-ggml-*.bin可用于本地快速验证。第二步准备样例音频并放入app/src/main/assets/samples选择一段样例音频README 推荐 samples/jfk.wav仓库同时提供 samples/jfk.mp3将其复制到app/src/main/assets/samples目录。从 MainScreenViewModel.kt 的copyAssets()可以看到应用首次启动会把assets/samples下的文件拷贝到应用私有目录filesDir/samples随后由getFirstSample()取第一个音频文件用于转写而assets/models则直接通过 asset 流加载loadBaseModel()使用createContextFromAsset加载assets/models/下的第一个模型。因此两个目录都不能为空否则示例无法运行。第三步选择 release 构建变体并在 Android Studio 中部署打开 Android Studio 导入本工程后在 Build Variants 面板把active build variant 切换为release然后运行并部署到已连接的 Android 设备需要 USB 调试或无线调试环境。选择 release 的原因与 CMakeLists.txt 中的构建策略一致非 Debug 构建会启用-O3、-fvisibilityhidden、-ffunction-sections -fdata-sections以及链接期-Wl,--gc-sections、-Wl,--exclude-libs,ALL、-flto等优化对包体和性能都更友好。重要注意事项工程依赖整个仓库README 的 PS 已明确请勿把 android 工程文件夹单独移出 whisper.cpp 仓库。除 CMake 反向引用外examples 顶层 CMakeLists.txt 也参与构建组织。保持工程位于仓库原路径即可保证模型路径、样例路径与原生源码引用全部有效。源码拆解从 Kotlin 到 JNI 再到 whisper.cpp示例虽小却是一条完整的Kotlin → JNI → C/C链路。下面按层剖析。:lib的 Kotlin 封装层WhisperContextLibWhisper.kt 定义了核心类WhisperContext它持有原生上下文指针ptr并提供三类工厂方法createContextFromFile(filePath)从文件系统路径加载模型createContextFromInputStream(stream)从任意 JavaInputStream加载createContextFromAsset(assetManager, assetPath)直接从 APK 的 assets 资源加载示例应用实际使用的方式。一个关键的实现约束写在代码注释里Meet Whisper C constraint: Dont access from more than one thread at a time。whisper.cpp 的上下文不允许被多线程并发访问因此WhisperContext内部用一个Executors.newSingleThreadExecutor()派生的协程作用域把所有调用转写、释放、基准测试串行化从架构上规避并发问题。transcribeData()LibWhisper.kt是核心转写入口先按WhisperCpuConfig.preferredThreadCount选定线程数调用 JNIfullTranscribe再遍历getTextSegmentCount()返回的段数逐段拼接文本printTimestamp为 true 时会用toTimestamp()把段起止时间getTextSegmentT0/T1单位为 10ms 刻度格式化为[00:00.500 -- 00:05.000]式的时间戳前缀。此外WhisperContext还暴露benchMemory(nthreads)与benchGgmlMulMat(nthreads)分别对应 C API 的whisper_bench_memcpy_str与whisper_bench_ggml_mul_mat_str供机型性能评估使用。:lib的 JNI 桥接层jni.cjni.c 承担了 Java/Kotlin 与 whisper.cpp C API 之间的翻译。值得注意的几个实现细节三种模型加载路径initContextFromAsset通过 Android NDK 的AAssetManager_open打开 asset 流构造whisper_model_loader回调asset_read/asset_is_eof/asset_close后调用whisper_init_with_params见 jni.cinitContextFromInputStream则封装了 JavaInputStream.available/read回调实现同样的流式加载initContext直接走whisper_init_from_file_with_params。转写参数jni.cfullTranscribe使用whisper_full_default_params(WHISPER_SAMPLING_GREEDY)后显式覆盖关键参数——print_realtimetrue、print_timestampstrue、translatefalse、languageen、n_threadsnumThreads、no_contexttrue、single_segmentfalse。这意味着示例当前固定以英文en运行若需识别中文应在此处将params.language改为zh并配合中文模型。结果读取getTextSegmentCount→whisper_full_n_segmentsgetTextSegment(i)→whisper_full_get_segment_textgetTextSegmentT0/T1→whisper_full_get_segment_t0/t1与 include/whisper.h 中公开的 C API 一一对应。:lib的原生构建层多 ABI 变体与 CPU 特性CMakeLists.txt 直接把 whisper.cpp 及其 GGML 依赖作为源码编译进一个共享库SOURCE_FILES包含src/whisper.cpp、jni.c以及ggml/src/下的一批.c/.cpp文件并针对 ABI 构建三个变体whisper默认目标兼容所有 ABIwhisper_vfpv4armeabi-v7a专用追加-mfpuneon-vfpv4见 CMakeLists.txtwhisper_v8fp16_vaarm64-v8a专用追加-marcharmv8.2-afp16以启用 FP16 算术加速CMakeLists.txt。而 LibWhisper.kt 的静态初始化块会在运行时读取/proc/cpuinfo做CPU 特性探测armeabi-v7a检测到vfpv4则加载libwhisper_vfpv4.soarm64-v8a检测到fphp则加载libwhisper_v8fp16_va.so否则回退到通用libwhisper.so。这种构建期多库 运行期探测的设计让同一 APK 在高低配设备上都能选到最合适的指令集实现。:app的 Compose 界面与转写编排:app 模块以 Jetpack Compose 实现 UIMainActivity.kt 挂载MainScreen业务逻辑集中在 MainScreenViewModel.kt启动流程loadData()先把assets/samples拷贝到filesDir再从assets/models加载第一个模型成功后canTranscribetrue转写样例transcribeSample()→readAudioSamples()先通过MediaPlayer播放再用 RiffWaveHelper.kt 的decodeWaveFile()解码 WAV 为 16kHz 的FloatArray交给WhisperContext.transcribeData并按data.size / (16000/1000)打印音频时长录音转写toggleRecord()使用 Recorder.kt 录制临时 WAV录制结束即触发同样的转写流程基准测试runBenchmark(6)以 6 线程运行内存拷贝与 GGML 矩阵乘基准输出耗时统计。模块内还包含ExampleInstrumentedTest/ExampleUnitTest两个默认测试脚手架可在此基础上补充转写正确性断言。线程数策略WhisperCpuConfig 的自适应选核WhisperCpuConfig.kt 展示了示例应用对移动端大小核调度的一种务实做法preferredThreadCount始终coerceAtLeast(2)至少 2 线程优先按/sys/devices/system/cpu/cpuN/cpufreq/cpuinfo_max_freq读取各核最高频率并分箱统计丢弃频率最低的一档后计数即只把高频大核算作可用线程若频率读取失败则回退读取/proc/cpuinfo的CPU variant分箱保留最小档再退化为availableProcessors() - 4的经验估算。这套逻辑让fullTranscribe的n_threads能随设备动态变化避免把任务压在小核上拖慢推理。常见问题与排查提示转写结果为空或模型加载失败优先确认app/src/main/assets/models与app/src/main/assets/samples均已放入文件且未被 Gradle 资源过滤模型加载失败时 Kotlin 层会抛出RuntimeException(Couldnt create context ...)。识别语言与预期不符如前述示例默认languageenjni.c转写中文需修改该参数并换用相应模型。性能偏慢按 README 建议改用 tiny/base 模型或使用-q5_1、-q8_0等量化版设备为 arm64 时确认命中whisper_v8fp16_va分支Logcat 会打印Loading libwhisper_v8fp16_va.so。日志定位各层日志 TAG 分别为LibWhisper、WhisperCpuConfig、JNI、MainScreenViewModel用adb logcat过滤即可跟踪从模型加载到转写完成的完整链路。工程结构被破坏若把 android 目录单独移出仓库CMakeLists.txt 中的../../../../../../..相对引用将失效原生库无法编译——务必保留完整仓库目录。综上examples/whisper.android 是一个可运行、可裁剪的 whisper.cpp Android 参考实现模型与音频只需放入 assets 即可切换线程数与语言等行为均可通过源码中的WhisperCpuConfig与jni.c参数快速定制是二次开发本地语音转文字应用的理想起点。赞分享人工智能语音音频本地部署推理引擎【免费下载链接】whisper.cppPort of OpenAIs Whisper model in C/C项目地址https://gitcode.com/GitHub_Trending/wh/whisper.cpp点击查看免费下载相关推荐whisper.cpp SwiftUI 示例深度解析在 iOS 上构建语音转文字应用whisper.cpp SwiftUI 示例深度解析在 iOS 上构建语音转文字应用 本指南以仓库中 examples/whisper.swiftui/REA人工智能语音音频本地部署推理引擎基于 whisper.cpp 的 Android Java 语音转文字示例whisper.android.java 完整使用指南基于 whisper.cpp 的 Android Java 语音转文字示例whisper.android.java 完整使用指南 导读 whisper.and人工智能语音音频本地部署推理引擎IoT-For-Beginners 实战用 Azure 语音服务在虚拟 IoT 设备上实现语音转文本Speech to TextIoT For Beginners 实战用 Azure 语音服务在虚拟 IoT 设备上实现语音转文本Speech to Text 导读 本文是开源课程 I教程文档教育物联网嵌入式上一篇replexica/integration-directus 演进与实现全解在 Directus CMS 中接入 Replexica AI 本地化引擎下一篇Aptos Secure Storage 深度解析KVStorage / CryptoStorage 双接口、四种后端与命名空间隔离机制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表