mmdhx commited on
Commit
cd2f3db
·
verified ·
1 Parent(s): d47b450

Update egg-api.js

Browse files
Files changed (1) hide show
  1. egg-api.js +50 -28
egg-api.js CHANGED
@@ -5,52 +5,63 @@ const ffmpeg = require('fluent-ffmpeg');
5
  const axios = require('axios');
6
  const fs = require('fs');
7
  const app = express();
8
- const PORT = 7860; // 将端口改为 7860
9
-
10
 
11
  app.use(express.json());
12
- // GIF转换为视频
13
- async function gifToVideo(gifStream,tempVideoPath) {
14
 
 
 
 
15
  await new Promise((resolve, reject) => {
16
- // 将内存流传递给 ffmpeg
17
  ffmpeg(gifStream)
18
  .inputFormat('gif')
19
- .on('end', resolve)
20
- .on('error', reject)
21
- .output(tempVideoPath) // 将输出指定为内存流
 
 
 
 
 
 
22
  .run();
23
  });
24
-
25
-
26
  }
27
 
28
  // 添加将输出视频转换为 GIF 的函数
29
  async function videoToGif(inputVideoPath, outputGifPath) {
 
30
  await new Promise((resolve, reject) => {
31
  ffmpeg()
32
  .input(inputVideoPath)
33
  .output(outputGifPath)
34
- .on('end', resolve)
35
- .on('error', reject)
36
- .run()
37
-
 
 
 
 
 
38
  });
39
  }
40
 
41
  // 从文件夹加载所有分类器
42
  async function loadClassifiersFromFolder(folderPath) {
43
- const classifiers = []
 
44
 
45
- // 读取文件夹中的所有文件
46
- const files = fs.readdirSync(folderPath)
47
  for (const file of files) {
48
- const filePath = `${folderPath}/${file}`
49
- const classifier = new cv.CascadeClassifier(filePath)
50
- classifiers.push(classifier)
 
51
  }
52
 
53
- return classifiers
 
54
  }
55
 
56
  // 处理 GIF 的 Express 接口
@@ -62,23 +73,31 @@ app.get('/processGif', async (req, res) => {
62
  const replacementImagePath = './replacement_face.png';
63
  const classifiersFolder = './classifiers';
64
 
65
- // 修改下载 GIF 到本地的部分
 
 
 
66
  const gifData = await axios.get(gifUrl, { responseType: 'stream' });
67
  const gifStream = gifData.data;
 
 
68
  // 从文件夹动态加载分类器
69
  const classifiers = await loadClassifiersFromFolder(classifiersFolder);
70
 
71
  // 将GIF转换为视频
72
- await gifToVideo(gifStream,tempVideoPath);
73
 
74
  // 读取视频文件
 
75
  const videoCapture = new cv.VideoCapture(tempVideoPath);
76
  const frameWidth = videoCapture.get(cv.CAP_PROP_FRAME_WIDTH);
77
  const frameHeight = videoCapture.get(cv.CAP_PROP_FRAME_HEIGHT);
78
  const originalFps = videoCapture.get(cv.CAP_PROP_FPS);
79
  const videoWriter = new cv.VideoWriter('./out.mp4', cv.VideoWriter.fourcc('avc1'), originalFps, new cv.Size(frameWidth, frameHeight));
 
80
 
81
  // 处理每一帧
 
82
  while (true) {
83
  const frame = videoCapture.read();
84
  if (frame.empty) break;
@@ -93,6 +112,7 @@ app.get('/processGif', async (req, res) => {
93
  const replacementFace = await Jimp.read(replacementImagePath);
94
 
95
  if (Array.isArray(faces) && faces.length > 0) {
 
96
  for (const rect of faces) {
97
  const resizedSubstituteImage = await replacementFace.clone().resize(rect.width, rect.height);
98
  const substituteRegion = frame.getRegion(rect);
@@ -110,7 +130,7 @@ app.get('/processGif', async (req, res) => {
110
  substituteMat.copyTo(frame.getRegion(rect));
111
  }
112
  } else {
113
- console.error('Error: No faces detected or faces is not a non-empty iterable array');
114
  }
115
 
116
  videoWriter.write(frame);
@@ -119,16 +139,18 @@ app.get('/processGif', async (req, res) => {
119
  videoCapture.release();
120
  videoWriter.release();
121
  cv.destroyAllWindows();
 
 
122
  await videoToGif('./out.mp4', outputGifPath);
123
 
124
  res.set('Content-Type', 'image/gif');
125
  res.sendFile(outputGifPath, { root: '.' });
126
  } catch (error) {
127
- console.error('Error in processing GIF:', error);
128
- res.status(500).send('Internal Server Error');
129
  }
130
  });
131
 
132
  app.listen(PORT, () => {
133
- console.log(`Server is running on port ${PORT}`);
134
- });
 
5
  const axios = require('axios');
6
  const fs = require('fs');
7
  const app = express();
8
+ const PORT = 7860;
 
9
 
10
  app.use(express.json());
 
 
11
 
12
+ // GIF转换为视频
13
+ async function gifToVideo(gifStream, tempVideoPath) {
14
+ console.log('开始将GIF转换为视频...');
15
  await new Promise((resolve, reject) => {
 
16
  ffmpeg(gifStream)
17
  .inputFormat('gif')
18
+ .on('end', () => {
19
+ console.log('GIF成功转换为视频');
20
+ resolve();
21
+ })
22
+ .on('error', (err) => {
23
+ console.error('GIF转换为视频时出错:', err);
24
+ reject(err);
25
+ })
26
+ .output(tempVideoPath)
27
  .run();
28
  });
 
 
29
  }
30
 
31
  // 添加将输出视频转换为 GIF 的函数
32
  async function videoToGif(inputVideoPath, outputGifPath) {
33
+ console.log('开始将视频转换为GIF...');
34
  await new Promise((resolve, reject) => {
35
  ffmpeg()
36
  .input(inputVideoPath)
37
  .output(outputGifPath)
38
+ .on('end', () => {
39
+ console.log('视频成功转换为GIF');
40
+ resolve();
41
+ })
42
+ .on('error', (err) => {
43
+ console.error('视频转换为GIF时出错:', err);
44
+ reject(err);
45
+ })
46
+ .run();
47
  });
48
  }
49
 
50
  // 从文件夹加载所有分类器
51
  async function loadClassifiersFromFolder(folderPath) {
52
+ console.log(`开始从文件夹 ${folderPath} 加载分类器...`);
53
+ const classifiers = [];
54
 
55
+ const files = fs.readdirSync(folderPath);
 
56
  for (const file of files) {
57
+ const filePath = `${folderPath}/${file}`;
58
+ const classifier = new cv.CascadeClassifier(filePath);
59
+ classifiers.push(classifier);
60
+ console.log(`加载分类器: ${file}`);
61
  }
62
 
63
+ console.log('分类器加载完成');
64
+ return classifiers;
65
  }
66
 
67
  // 处理 GIF 的 Express 接口
 
73
  const replacementImagePath = './replacement_face.png';
74
  const classifiersFolder = './classifiers';
75
 
76
+ console.log('接收到GIF处理请求:', gifUrl);
77
+
78
+ // 下载 GIF 到本地
79
+ console.log('开始下载GIF...');
80
  const gifData = await axios.get(gifUrl, { responseType: 'stream' });
81
  const gifStream = gifData.data;
82
+ console.log('GIF下载完成');
83
+
84
  // 从文件夹动态加载分类器
85
  const classifiers = await loadClassifiersFromFolder(classifiersFolder);
86
 
87
  // 将GIF转换为视频
88
+ await gifToVideo(gifStream, tempVideoPath);
89
 
90
  // 读取视频文件
91
+ console.log('开始读取视频文件...');
92
  const videoCapture = new cv.VideoCapture(tempVideoPath);
93
  const frameWidth = videoCapture.get(cv.CAP_PROP_FRAME_WIDTH);
94
  const frameHeight = videoCapture.get(cv.CAP_PROP_FRAME_HEIGHT);
95
  const originalFps = videoCapture.get(cv.CAP_PROP_FPS);
96
  const videoWriter = new cv.VideoWriter('./out.mp4', cv.VideoWriter.fourcc('avc1'), originalFps, new cv.Size(frameWidth, frameHeight));
97
+ console.log('视频文件读取完成');
98
 
99
  // 处理每一帧
100
+ console.log('开始处理每一帧...');
101
  while (true) {
102
  const frame = videoCapture.read();
103
  if (frame.empty) break;
 
112
  const replacementFace = await Jimp.read(replacementImagePath);
113
 
114
  if (Array.isArray(faces) && faces.length > 0) {
115
+ console.log(`检测到 ${faces.length} 张脸`);
116
  for (const rect of faces) {
117
  const resizedSubstituteImage = await replacementFace.clone().resize(rect.width, rect.height);
118
  const substituteRegion = frame.getRegion(rect);
 
130
  substituteMat.copyTo(frame.getRegion(rect));
131
  }
132
  } else {
133
+ console.error('未检测到人脸或faces数组为空');
134
  }
135
 
136
  videoWriter.write(frame);
 
139
  videoCapture.release();
140
  videoWriter.release();
141
  cv.destroyAllWindows();
142
+ console.log('帧处理完成');
143
+
144
  await videoToGif('./out.mp4', outputGifPath);
145
 
146
  res.set('Content-Type', 'image/gif');
147
  res.sendFile(outputGifPath, { root: '.' });
148
  } catch (error) {
149
+ console.error('处理GIF时出错:', error);
150
+ res.status(500).send('内部服务器错误');
151
  }
152
  });
153
 
154
  app.listen(PORT, () => {
155
+ console.log(`服务器运行在端口 ${PORT}`);
156
+ });