项目搭建

This commit is contained in:
2025-03-26 19:00:28 +08:00
commit fd2a75dce2
7 changed files with 276 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/.vscode
/build
/node_modules
/thirdpart/_source
/thirdpart/FFmpeg
/package-lock.json

96
CMakeLists.txt Normal file
View File

@ -0,0 +1,96 @@
cmake_minimum_required(VERSION 3.10.0)
project(ai-box VERSION 0.1.0 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
if (POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif (POLICY CMP0091)
if(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
set(NODE_ADDON_FOUND OFF)
include_directories(cxx)
# FFmpeg
set(FFMPEG_CMAKE_FILE ${CMAKE_SOURCE_DIR}/thirdpart/FFmpeg/config.cmake)
if(EXISTS ${FFMPEG_CMAKE_FILE})
include(${FFMPEG_CMAKE_FILE})
message(STATUS "FFMPEG_LIB_DIR: ${FFMPEG_LIB_DIR}")
message(STATUS "FFMPEG_INCLUDE_DIR: ${FFMPEG_INCLUDE_DIR}")
message(STATUS "FFMPEG_LIBS: ${FFMPEG_LIBS}")
include_directories(${FFMPEG_INCLUDE_DIR})
link_directories(${FFMPEG_LIB_DIR})
else()
message(FATAL_ERROR "FFmpeg not found")
endif()
# NodeJS
execute_process(
COMMAND node ${CMAKE_SOURCE_DIR}/thirdpart/cmake-js-util.js --include
RESULT_VARIABLE CMAKE_JS_RESULT
OUTPUT_VARIABLE CMAKE_JS_INC
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(CMAKE_JS_RESULT EQUAL 0)
execute_process(
COMMAND node ${CMAKE_SOURCE_DIR}/thirdpart/cmake-js-util.js --src
RESULT_VARIABLE CMAKE_JS_RESULT
OUTPUT_VARIABLE CMAKE_JS_SRC
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(CMAKE_JS_RESULT EQUAL 0)
execute_process(
COMMAND node ${CMAKE_SOURCE_DIR}/thirdpart/cmake-js-util.js --lib
RESULT_VARIABLE CMAKE_JS_RESULT
OUTPUT_VARIABLE CMAKE_JS_LIB
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
# ReleaseVersion
if(CMAKE_JS_RESULT EQUAL 0)
execute_process(
COMMAND node ${CMAKE_SOURCE_DIR}/thirdpart/cmake-js-util.js --release
RESULT_VARIABLE CMAKE_JS_RESULT
OUTPUT_VARIABLE RELEASE_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(CMAKE_JS_RESULT EQUAL 0)
message(STATUS "RELEASE_VERSION: ${RELEASE_VERSION}")
add_compile_definitions(RELEASE_VERSION="${RELEASE_VERSION}")
endif()
endif()
# NAPI
if(CMAKE_JS_RESULT EQUAL 0)
execute_process(
COMMAND node ${CMAKE_SOURCE_DIR}/thirdpart/cmake-js-util.js --napi
RESULT_VARIABLE CMAKE_JS_RESULT
OUTPUT_VARIABLE NODE_ADDON_API_DIR
)
endif()
if(CMAKE_JS_RESULT EQUAL 0)
message(STATUS "CMAKE_JS_INC: ${CMAKE_JS_INC}")
message(STATUS "CMAKE_JS_SRC: ${CMAKE_JS_SRC}")
message(STATUS "CMAKE_JS_LIB: ${CMAKE_JS_LIB}")
message(STATUS "NODE_ADDON_API_DIR: ${NODE_ADDON_API_DIR}")
include_directories(${CMAKE_JS_INC} ${NODE_ADDON_API_DIR})
set(NODE_ADDON_FOUND ON)
endif()
endif()
if(NOT (CMAKE_JS_RESULT EQUAL 0))
message(FATAL_ERROR "cmake js config failed")
endif()
# 平台特定的库
if(MSVC)
set(PLATFORM_LIBS ws2_32 winmm strmiids mfplat mfuuid Ws2_32 Secur32 Bcrypt)
endif()
include_directories(thirdpart/FFmpeg/include)
link_directories(thirdpart/FFmpeg/lib)
add_executable(ffmpeg cxx/main.cc)
target_link_libraries(ffmpeg ${PLATFORM_LIBS} ${FFMPEG_LIBS})

25
README.md Normal file
View File

@ -0,0 +1,25 @@
## Windows下的FFmpeg 编译
1. 安装msys2
从 https://www.msys2.org 下载Windows安装包进行安装。
1. 安装 Visual Studio Build Tools
1. 打开构建工具(x64)并启动msys2。
可以在msys2的安装目录下新建一个`msvc_build.bat`,并输入以下内容:
```
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
msys2_shell.cmd -mingw64
```
1. 安装依赖库
1. 编译项目
在msys2中执行
```
cd /path/to/project
node thirdpart/build_ffmpeg_win.js
```

28
cxx/main.cc Normal file
View File

@ -0,0 +1,28 @@
#include <iostream>
// #pragma comment(lib, "ws2_32.lib")
// #pragma comment(lib, "winmm.lib")
// #pragma comment(lib, "strmiids")
// #pragma comment(lib, "mfplat")
// #pragma comment(lib, "mfuuid")
// #pragma comment(lib, "Ws2_32")
// #pragma comment(lib, "Secur32")
// #pragma comment(lib, "Bcrypt")
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavformat/avformat.h>
#ifdef __cplusplus
}
#endif
int main(int, char **)
{
AVFormatContext *ifmt_ctx = nullptr;
if (avformat_open_input(&ifmt_ctx, "http://vjs.zencdn.net/v/oceans.mp4", nullptr, nullptr) < 0)
printf("avformat_open_input failed\n");
printf("nb_stream=%d\n", ifmt_ctx->nb_streams);
std::cout << "Hello, from ffmpeg!\n";
}

20
package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "@yizhi/ffmpeg",
"version": "1.0.1",
"releaseVersion": "1.0.1",
"main": "dist/index.js",
"types": "typing/index.d.ts",
"scripts": {
"build": "rm -rf dist typing && tsc",
"watch": "tsc -w --inlineSourceMap"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"@types/node": "^22.13.5",
"cmake-js": "^7.3.0",
"node-addon-api": "^8.3.1"
}
}

View File

@ -0,0 +1,82 @@
const { spawnSync } = require("child_process");
const fs = require("fs");
const path = require("path");
const os = require("os");
const FFMPEG_REPO = "https://git.ffmpeg.org/ffmpeg.git";
const FFMPEG_TAG = "release/7.1"
const FFMPEG_SOURCE_DIR = path.join(__dirname, "_source/FFmpeg");
const FFMPEG_INSTALL_DIR = path.join(__dirname, "FFmpeg");
function checkEnv() {
if (!process.env.MSYSTEM_PREFIX) throw new Error("Please use msys2 environment to run this script");
const bash = process.env.SHELL;
if (!bash || !bash.endsWith("bash.exe")) throw new Error("bash.exe is not found in environments");
}
function download() {
console.log("Downloading ffmpeg source...");
if (0 != spawnSync("git", [
"clone", FFMPEG_REPO,
"-b", FFMPEG_TAG, FFMPEG_SOURCE_DIR
], { stdio: "inherit" }).status) throw new Error("Failed to download ffmpeg");
}
function build() {
//configure
if (!fs.existsSync(path.join(FFMPEG_SOURCE_DIR, "ffbuild/config.mak"))) {
console.log("Configuring ffmpeg...");
if (0 != spawnSync(process.env.SHELL, [
path.join(FFMPEG_SOURCE_DIR, "configure"),
`--prefix=${FFMPEG_INSTALL_DIR}`,
"--enable-static",
"--enable-small",
"--toolchain=msvc",
"--disable-programs",
], { stdio: "inherit", cwd: FFMPEG_SOURCE_DIR }).status) throw new Error("Failed to configure ffmpeg");
}
//make
if (0 != spawnSync("make", [
"-j", os.cpus().length.toString(),
], { stdio: "inherit" }).status) throw new Error("Failed to build ffmpeg");
//install
if (0 != spawnSync("make", [
"install",
], { stdio: "inherit", cwd: FFMPEG_SOURCE_DIR }).status) throw new Error("Failed to install ffmpeg");
}
function resolve() {
console.log("Resolving ffmpeg ...");
const libs = [];
for (const file of fs.readdirSync(path.join(FFMPEG_INSTALL_DIR, "lib"))) {
if (path.extname(file) == ".a") {
const libName = file.replace(/\.a$/, "").replace(/^lib/, "");
fs.renameSync(path.join(FFMPEG_INSTALL_DIR, "lib", file), path.join(FFMPEG_INSTALL_DIR, "lib", libName + ".lib"));
libs.push(libName);
}
}
fs.writeFileSync(path.join(FFMPEG_INSTALL_DIR, "config.cmake"), [
"set(FFMPEG_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/include)",
"set(FFMPEG_LIB_DIR ${CMAKE_CURRENT_LIST_DIR}/lib)",
`set(FFMPEG_LIBS ${libs.join(" ")})`,
"",
].join("\n"));
}
async function main() {
fs.mkdirSync(path.dirname(FFMPEG_SOURCE_DIR), { recursive: true });
fs.mkdirSync(path.dirname(FFMPEG_INSTALL_DIR), { recursive: true });
checkEnv();
if (!fs.existsSync(path.join(FFMPEG_SOURCE_DIR, "configure"))) download();
if (!fs.existsSync(path.join(FFMPEG_INSTALL_DIR, "config.cmake"))) {
build();
resolve();
}
console.log(`FFmpeg build done !`);
}
main().catch(err => console.error(err.message));

View File

@ -0,0 +1,19 @@
const os = require("os");
const path = require("path");
const { execSync, spawnSync, exec } = require("child_process");
const args = process.argv.slice(2);
const cmakeJS = path.join(__dirname, "../node_modules/.bin/cmake-js")
function runCmakeJS(args) {
const child = exec(`${cmakeJS} ${args.join(" ")}`, (err, stdout, stderr) => console.log(stdout));
child.once("close", code => process.exit(code));
}
if (args.includes("--include")) runCmakeJS(["print-cmakejs-include"]);
else if (args.includes("--src")) runCmakeJS(["print-cmakejs-src"]);
else if (args.includes("--lib")) runCmakeJS(["print-cmakejs-lib"]);
else if (args.includes("--napi")) console.log(require("node-addon-api").include.replace(/^"/, "").replace(/"$/, ""));
else if (args.includes("--release")) console.log(require("../package.json").releaseVersion);