项目搭建
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/.vscode
|
||||
/build
|
||||
/node_modules
|
||||
/thirdpart/_source
|
||||
/thirdpart/FFmpeg
|
||||
/package-lock.json
|
96
CMakeLists.txt
Normal file
96
CMakeLists.txt
Normal 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
25
README.md
Normal 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
28
cxx/main.cc
Normal 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
20
package.json
Normal 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"
|
||||
}
|
||||
}
|
82
thirdpart/build_ffmpeg_win.js
Normal file
82
thirdpart/build_ffmpeg_win.js
Normal 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));
|
19
thirdpart/cmake-js-util.js
Normal file
19
thirdpart/cmake-js-util.js
Normal 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);
|
Reference in New Issue
Block a user