android build

This commit is contained in:
Pacoshao 2025-06-20 17:18:28 +08:00
parent a2d65257da
commit eefe25c8b8
6 changed files with 71 additions and 191 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.14)
cmake_minimum_required(VERSION 3.14)
project(ncmdump LANGUAGES CXX)
project("ncmdump")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@ -10,10 +10,6 @@ set(WITH_ZLIB OFF)
set(BUILD_TESTING OFF)
add_subdirectory(taglib)
if(MSVC)
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/execution-charset:utf-8>")
endif()
FILE(GLOB COMMON_HEADERS src/include/*.h)
FILE(GLOB COMMON_SOURCES src/ncmcrypt.cpp src/utils/*.cpp)
FILE(GLOB EXECUTABLE_SOURCES src/main.cpp)
@ -21,66 +17,20 @@ FILE(GLOB LIBRARY_HEADERS src/lib/libncmdump.h)
FILE(GLOB LIBRARY_SOURCES src/lib/*.cpp)
FILE(GLOB WIN_SOURCES src/platform/win32_init.cpp)
if(WIN32)
add_executable(ncmdump_exec
${COMMON_HEADERS}
${COMMON_SOURCES}
${EXECUTABLE_SOURCES}
${WIN_SOURCES}
)
add_library(ncmdump_lib SHARED
${COMMON_HEADERS}
${COMMON_SOURCES}
${LIBRARY_HEADERS}
${LIBRARY_SOURCES}
${WIN_SOURCES}
)
add_library(ncmdump_lib SHARED
${COMMON_HEADERS}
${COMMON_SOURCES}
${LIBRARY_HEADERS}
${LIBRARY_SOURCES})
set_target_properties(ncmdump_lib PROPERTIES OUTPUT_NAME "libncmdump")
set_target_properties(ncmdump_lib PROPERTIES OUTPUT_NAME "ncmdump")
target_include_directories(ncmdump_lib PRIVATE src/include)
target_include_directories(ncmdump_lib PRIVATE src/include)
target_link_libraries(ncmdump_lib tag)
target_include_directories(ncmdump_lib PRIVATE taglib)
target_include_directories(ncmdump_lib PRIVATE taglib/taglib)
target_include_directories(ncmdump_lib PRIVATE taglib/taglib/toolkit)
target_include_directories(ncmdump_lib PRIVATE taglib/taglib/mpeg/id3v2)
target_link_libraries(ncmdump_lib tag)
target_include_directories(ncmdump_lib PRIVATE taglib)
target_include_directories(ncmdump_lib PRIVATE taglib/taglib)
target_include_directories(ncmdump_lib PRIVATE taglib/taglib/toolkit)
target_include_directories(ncmdump_lib PRIVATE taglib/taglib/mpeg/id3v2)
if(CMAKE_COMPILER_IS_GNUCXX)
# static link when using MinGW
target_link_options(ncmdump_exec PRIVATE -static)
target_link_options(ncmdump_lib PRIVATE -static)
endif()
else()
add_executable(ncmdump_exec
${COMMON_HEADERS}
${COMMON_SOURCES}
${EXECUTABLE_SOURCES}
)
endif()
# all executable target
set_target_properties(ncmdump_exec PROPERTIES OUTPUT_NAME "ncmdump")
target_include_directories(ncmdump_exec PRIVATE src/include)
target_link_libraries(ncmdump_exec tag)
target_include_directories(ncmdump_exec PRIVATE taglib)
target_include_directories(ncmdump_exec PRIVATE taglib/taglib)
target_include_directories(ncmdump_exec PRIVATE taglib/taglib/toolkit)
target_include_directories(ncmdump_exec PRIVATE taglib/taglib/mpeg/id3v2)
include(GNUInstallDirs)
if(WIN32)
install(TARGETS ncmdump_exec ncmdump_lib
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
else()
install(TARGETS ncmdump_exec
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif()
include(GNUInstallDirs)

View File

@ -1,9 +1,13 @@
# ncmdump
# ncmdump-android
使用本程序可将下载的网易云音乐缓存文件ncm转换为 mp3 或 flac 格式
## 简介
本分支是ncmdump在Android平台上的移植taglib的android调整改自[taglib-ndk](https://github.com/tumugin/taglib-ndk)
下为原简介:
该版本为最早的 C++ 版本,也是作者开发的市面上第一个支持 ncm 转换的程序
源码复刻自 anonymous5l/ncmdump (2021年10月6日原作者已经删库)
@ -18,7 +22,7 @@
### 命令行工具
从 [Release](https://github.com/taurusxin/ncmdump/releases) 下载最新版本的对应系统的已编译好的二进制文件
用法与原版相同
使用 `-h``--help` 参数来打印帮助
@ -65,9 +69,7 @@ ncmdump -d source_dir -o output_dir -r
### 动态库
或者,如果你想利用此项目进行二次开发,例如在你的 C#、Python、Java 等项目中调用,你可以使用 `libncmdump` 动态库,具体使用方法见仓库的 `example` 文件夹
请注意!如果你在 Windows 下开发,传递到库构造函数的文件名编码**必须为 UTF-8 编码**,否则会抛出运行时错误。
或者如果你想利用此项目进行二次开发例如在你的Android应用中调用你可以使用 `libncmdump` 动态库,具体使用方法如下
## 编译项目
@ -84,34 +86,31 @@ cd ncmdump
git submodule update --init --recursive
```
使用 CMake 配置项目。Windows 下若使用 GNU 套件,推荐使用 [msys2](https://www.msys2.org/) 或者 [winlibs](https://winlibs.com/)
调整CMakeLists.txt
```shell
# Windows MinGW
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -B build
# Android Studio
置于你项目的cpp文件夹下
# Windows MSVC
cmake -G "Visual Studio 17 2022" -A x64 -B build
编译Android项目时自动编译生成numdump和libncmdump.so
# Linux / macOS
cmake -DCMAKE_BUILD_TYPE=Release -B build
# 使用
```kotlin
init {
System.loadLibrary("ncmdump") // 你的库名
}
# 如果需要在 macOS 下交叉编译,可以指定 `CMAKE_OSX_ARCHITECTURES` 变量来指明目标系统架构
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64 -B build # arm64
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64 -B build # Intel-based
external fun DumpFileTo(inputFilePath: String, outputCachePath: String): Int
```
编译项目
# DumpFileTo用法
inputFilePath输入文件路径
outputCachePath:输出文件路径
返回:
-1失败
0成功
```shell
# Windows MSVC 需要在构建阶段指定 --config Release
cmake --build build -j 8 --config Release
# Windows MinGW / Linux / macOS
cmake --build build -j 8
```
你可以在 `build` 文件夹下找到编译好的二进制文件,以及一个可供其它项目使用的动态库(Windows Only),使用方法见仓库的 `example` 文件夹
# 注意
在 Android 11 以上的版本Android对文件读取和写入有较严格的规定因此上述目录应为应用私有的目录比如cache
[![Powered by DartNode]( https://dartnode.com/branding/DN-Open-Source-sm.png)]( https://dartnode.com "Powered by DartNode - Free VPS for Open Source")

View File

@ -1,74 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace libncmdump_demo_cli
{
/// <summary>
/// NeteaseCrypt C# Wrapper
/// </summary>
class NeteaseCrypt
{
const string DLL_PATH = "libncmdump.dll";
[DllImport(DLL_PATH, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateNeteaseCrypt(IntPtr path);
[DllImport(DLL_PATH, CallingConvention = CallingConvention.Cdecl)]
private static extern int Dump(IntPtr NeteaseCrypt, IntPtr outputPath);
[DllImport(DLL_PATH, CallingConvention = CallingConvention.Cdecl)]
private static extern void FixMetadata(IntPtr NeteaseCrypt);
[DllImport(DLL_PATH, CallingConvention = CallingConvention.Cdecl)]
private static extern void DestroyNeteaseCrypt(IntPtr NeteaseCrypt);
private IntPtr NeteaseCryptClass = IntPtr.Zero;
/// <summary>
/// 创建 NeteaseCrypt 类的实例。
/// </summary>
/// <param name="FileName">网易云音乐 ncm 加密文件路径</param>
public NeteaseCrypt(string FileName)
{
byte[] bytes = Encoding.UTF8.GetBytes(FileName);
IntPtr inputPtr = Marshal.AllocHGlobal(bytes.Length + 1);
Marshal.Copy(bytes, 0, inputPtr, bytes.Length);
Marshal.WriteByte(inputPtr, bytes.Length, 0);
NeteaseCryptClass = CreateNeteaseCrypt(inputPtr);
}
/// <summary>
/// 启动转换过程。
/// </summary>
/// <param name="OutputPath">指定一个路径输出,如果为空,则输出到原路径</param>
/// <returns>返回一个整数指示转储过程的结果。如果成功返回0如果失败返回1。</returns>
public int Dump(string OutputPath)
{
byte[] bytes = Encoding.UTF8.GetBytes(OutputPath);
IntPtr outputPtr = Marshal.AllocHGlobal(bytes.Length + 1);
Marshal.Copy(bytes, 0, outputPtr, bytes.Length);
Marshal.WriteByte(outputPtr, bytes.Length, 0);
return Dump(NeteaseCryptClass, outputPtr);
}
/// <summary>
/// 修复音乐文件元数据。
/// </summary>
public void FixMetadata()
{
FixMetadata(NeteaseCryptClass);
}
/// <summary>
/// 销毁 NeteaseCrypt 类的实例。
/// </summary>
public void Destroy()
{
DestroyNeteaseCrypt(NeteaseCryptClass);
}
}
}

View File

@ -1,26 +0,0 @@
using System;
using System.Threading.Tasks;
namespace libncmdump_demo_cli
{
internal class Program
{
static void Main(string[] args)
{
// 文件名
string filePath = "test.ncm";
// 创建 NeteaseCrypt 类的实例
NeteaseCrypt neteaseCrypt = new NeteaseCrypt(filePath);
// 启动转换过程
int result = neteaseCrypt.Dump(""); // 为空则输出到源
// 修复元数据
neteaseCrypt.FixMetadata();
// [务必]销毁 NeteaseCrypt 类的实例
neteaseCrypt.Destroy();
}
}
}

View File

@ -1,5 +1,6 @@
#include "libncmdump.h"
#include <filesystem>
#include <jni.h>
namespace fs = std::filesystem;
@ -28,4 +29,34 @@ extern "C" {
API void DestroyNeteaseCrypt(NeteaseCrypt* neteaseCrypt) {
delete neteaseCrypt;
}
}
extern "C" JNIEXPORT jint JNICALL
Java_com_pks_dencm_NativeConverter_DumpFileTo( // 替换为你的包名和类名
JNIEnv* env,
jobject /* this */,
jstring filePathJ,
jstring outputFolderJ) { // 这个 outputFolder 是 C++ 用来构造完整输出文件路径的目录
const char* ncmFilePathNativeChars = env->GetStringUTFChars(filePathJ, nullptr);
const char* outputDirNativeChars = env->GetStringUTFChars(outputFolderJ, nullptr);
if (ncmFilePathNativeChars == nullptr || outputDirNativeChars == nullptr) {
if (ncmFilePathNativeChars) env->ReleaseStringUTFChars(filePathJ, ncmFilePathNativeChars);
if (outputDirNativeChars) env->ReleaseStringUTFChars(outputFolderJ, outputDirNativeChars);
return -2; // JNI string conversion error
}
// 将 C 风格字符串转换为 std::filesystem::path
fs::path inputPath = fs::u8path(ncmFilePathNativeChars); // 从 C-string 构建 path
fs::path outputDirectoryForCpp = fs::u8path(outputDirNativeChars); // 从 C-string 构建 path
try{
NeteaseCrypt crypt(inputPath.u8string());
crypt.Dump(outputDirectoryForCpp.u8string());
crypt.FixMetadata();
return 0;
}catch (...){
return -1;
}
}

Binary file not shown.