diff --git a/CMakeLists.txt b/CMakeLists.txt index d1edf00..14e97a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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("$<$:/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) \ No newline at end of file diff --git a/README.md b/README.md index 6fa29d2..a676783 100644 --- a/README.md +++ b/README.md @@ -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") diff --git a/example/csharp/NeteaseCrypt.cs b/example/csharp/NeteaseCrypt.cs deleted file mode 100644 index db5bb0e..0000000 --- a/example/csharp/NeteaseCrypt.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace libncmdump_demo_cli -{ - /// - /// NeteaseCrypt C# Wrapper - /// - 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; - - /// - /// 创建 NeteaseCrypt 类的实例。 - /// - /// 网易云音乐 ncm 加密文件路径 - 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); - } - - /// - /// 启动转换过程。 - /// - /// 指定一个路径输出,如果为空,则输出到原路径 - /// 返回一个整数,指示转储过程的结果。如果成功,返回0;如果失败,返回1。 - 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); - } - - /// - /// 修复音乐文件元数据。 - /// - public void FixMetadata() - { - FixMetadata(NeteaseCryptClass); - } - - /// - /// 销毁 NeteaseCrypt 类的实例。 - /// - public void Destroy() - { - DestroyNeteaseCrypt(NeteaseCryptClass); - } - } -} diff --git a/example/csharp/Program.cs b/example/csharp/Program.cs deleted file mode 100644 index b296eed..0000000 --- a/example/csharp/Program.cs +++ /dev/null @@ -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(); - } - } -} diff --git a/src/lib/libncmdump.cpp b/src/lib/libncmdump.cpp index 2783f7b..e4374ce 100644 --- a/src/lib/libncmdump.cpp +++ b/src/lib/libncmdump.cpp @@ -1,5 +1,6 @@ #include "libncmdump.h" #include +#include 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; + } } \ No newline at end of file diff --git a/test/test.ncm b/test/test.ncm deleted file mode 100644 index 6fce6bb..0000000 Binary files a/test/test.ncm and /dev/null differ