diff --git a/src/templates/tpl1.txt b/src/templates/tpl1.txt new file mode 100644 index 0000000..4f9f412 --- /dev/null +++ b/src/templates/tpl1.txt @@ -0,0 +1,20 @@ +ffmpeg -y \ + -f image2 -loop 1 \ + -i ${data.tts.img} \ + ${ (data.tts.pcm.endsWith('.pcm') ? '-f s16le -ac 1 -ar 16k -i ' : '-i ') + data.tts.pcm} \ + -t ${data.tts.duration} -f nut pipe: | \ +ffmpeg -y \ + -i ${data.audio.path} \ + -i pipe: ${data.videos.map(video => ' -i ' + video.path).join(' ')} \ + -filter_complex ' +${new Array(data.videos.length + 1).fill(1) + .map((item, index) => " ["+ (index + 1) + ":v]scale=720:1280[in" + (index + 1) + "]") + .join(";\n") +} + ${ + new Array(data.videos.length + 1).fill(1) + .map((item, index) => "[in" + (index + 1) + "]") + .join("") +} concat=n=${ data.videos.length + 1}:v=1:a=0 [v]; + [0:a][1:a] amix=inputs=2 [a]' \ + -map '[v]' -map '[a]' -c:v libx264 -pix_fmt yuv420p -c:a aac -t ${data.duration} ${data.output} \ No newline at end of file diff --git a/src/vmTemplate.js b/src/vmTemplate.js index fe22ada..9d94e07 100644 --- a/src/vmTemplate.js +++ b/src/vmTemplate.js @@ -2,7 +2,7 @@ const { NodeVM } = require('vm2') export const template = (code, options = {}) => { const fn = new NodeVM(options).run( - code.startsWith('module') + code.includes('module.exports') ? code : `module.exports = (data) => \`${code}\`` ) diff --git a/src/vmTemplate.test.js b/src/vmTemplate.test.js index e87070d..6d8b762 100644 --- a/src/vmTemplate.test.js +++ b/src/vmTemplate.test.js @@ -1,4 +1,6 @@ const assert = require('power-assert') +const fs = require('fs') +const path = require('path') const { template } = require('./vmTemplate') /* eslint-env jest */ @@ -33,4 +35,41 @@ describe('vmTemplate', () => { ret = await fn({ timestamp }) assert(ret === `timestamp: ${timestamp}`) }) + it('code has function', async () => { + // eslint-disable-next-line no-template-curly-in-string + const fn = template('const tet = (data) => {return `timestamp: ${data.timestamp}`}; module.exports = (ctx) => `${tet(ctx)}`') + const timestamp = Date.now() + const ret = await fn({ timestamp }) + assert(ret === `timestamp: ${timestamp}`) + }) + it('template command module exports', async () => { + // eslint-disable-next-line no-template-curly-in-string + const text = 'module.exports = (data) => `ffmpeg -y -i ${data.audio.path} -i ${data.cover.path}`' + const fn = template(text) + const data = { + audio: { + path: 'audio/FoWL_zGcLjEgLC_OZrG6JhhDXsNs.mp3' + }, + cover: { + path: 'imgs/FhbOJPU2feifsJzBGspsyASxkNy5' + } + } + const ret = await fn(data) + assert(ret === `ffmpeg -y -i ${data.audio.path} -i ${data.cover.path}`) + }) + it('template command', async () => { + const text = fs.readFileSync(path.resolve(__dirname, './templates/tpl1.txt')).toString() + const fn = template(text) + const data = { + tts: { img: 'imgs/img.jpg', pcm: 'tts/wd.pcm', duration: 6 }, audio: { path: 'audio/audio.mp3' }, cover: { path: 'imgs/f.jpg' }, output: 'video/3_2019_11_15_test4.mp4', videos: [{ path: 'video/1.mp4' }, { path: 'video/2.mp4' }, { path: 'video/3.mp4' }], duration: 30 + } + const ret = await fn(data) + assert(ret === `ffmpeg -y -f image2 -loop 1 -i imgs/img.jpg -f s16le -ac 1 -ar 16k -i tts/wd.pcm -t 6 -f nut pipe: | ffmpeg -y -i audio/audio.mp3 -i pipe: -i video/1.mp4 -i video/2.mp4 -i video/3.mp4 -filter_complex ' + [1:v]scale=720:1280[in1]; + [2:v]scale=720:1280[in2]; + [3:v]scale=720:1280[in3]; + [4:v]scale=720:1280[in4] + [in1][in2][in3][in4] concat=n=4:v=1:a=0 [v]; + [0:a][1:a] amix=inputs=2 [a]' -map '[v]' -map '[a]' -c:v libx264 -pix_fmt yuv420p -c:a aac -t 30 video/3_2019_11_15_test4.mp4`) + }) })