核心思想:使用go的exec.Command突破壁垒

必备组件:Nodejs,FFmpeg,go项目下的FFCreator

package demo

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strconv"
	"time"
)

func Make() {
	unixtime := strconv.FormatInt(time.Now().Unix(), 10)
	path := "./js/" + unixtime + ".js"
	fmt.Println(path)
	file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, os.ModeAppend|os.ModePerm)
	if err != nil {
		fmt.Println(err)
	}
	s1 := `path = require('path');
	const { FFScene, FFText, FFVideo, FFAlbum, FFImage, FFCreator, FFSubtitle, FFCreatorCenter } = require('ffcreator');
	const width = 400;
	const height = 300;
	const fps = 25;
	const cacheDir = path.join(__dirname, '../cache');
	const outputDir = path.join(__dirname, '../output');
	const output = path.join(__dirname, '`

	s2 := "../output/" + unixtime + ".mp4"
	s3 := `');
	
	const cover = 'http://img.funi.com/images/upload/95e/e06c69da4329b9d60b30b7dc2cf2.jpg.500x375.jpg';
	const audio = 'https://www.tyzspy.com/uploadfile/bjyy/%E8%BD%BB%E6%9F%94%E7%9A%84%E8%83%8C%E6%99%AF%E9%9F%B3%E4%B9%90/%E8%BD%BB%E6%9F%94%E7%9A%84%E8%83%8C%E6%99%AF%E9%9F%B3%E4%B9%904.mp3';
	
	let imgs = [];
	
	imgs = [{ src: 'http://img.funi.com/images/upload/d73/556a38e844098a99ad82f9516897.jpg.500x375.jpg', title: '花园新城' }, { src: 'http://img.funi.com/images/upload/4fc/f4399c3143b6b46e4cc0547a8295.jpg.500x375.jpg', title: '喜乐居' }, { src: 'http://img.funi.com/images/upload/308/0570aace44bba0a039e0006bff94.jpg.500x375.jpg', title: '雅湖岛' }]
	
	const createVideo = () => {
		const creator = new FFCreator({
			cacheDir,
			outputDir,
			width,
			height,
			fps,
			audioLoop: true,
			output,
			cover
		});
		creator.addAudio(audio);
	
		for (let i = 0; i < imgs.length; i++) {
			const scene = new FFScene();
			scene.setBgColor('#000000');
			scene.setDuration(5);
			scene.setTransition('Slice', 1);
	
			const image = new FFImage({ path: imgs[i].src, x: width / 2, y: height / 2 });
			image.addEffect('fadeInUp', 1, 1);
			image.setDuration(5);
			scene.addChild(image);
	
			const text = new FFText({ text: imgs[i].title, x: width / 2, y: height / 2 });
			text.setColor('#ffffff');
			text.addEffect('fadeInDown', 1, 1);
			text.alignCenter();
			scene.addChild(text);

			creator.addChild(scene);
		}
		creator.start();
		creator.closeLog();
		creator.on('error', e => {
			console.log('失败:'+'JSON.stringify(e)}');
		});
		creator.on('complete', e => {
			console.log('完成:'+e.output);
		});
		return creator;
	}
	createVideo()
	`
	runjs := s1 + s2 + s3
	file.WriteString(runjs)
	file.Close()

	fp := "./js/" + unixtime + ".js"

	Exec("node", fp)

}

func Exists(path string) bool {
	_, err := os.Stat(path) //os.Stat获取文件信息
	if err != nil {
		return os.IsExist(err)
	}
	return true
}

func Exec(name string, args ...string) error {
	cmd := exec.Command(name, args...)
	stderr, _ := cmd.StderrPipe()
	stdout, _ := cmd.StdoutPipe()
	if err := cmd.Start(); err != nil {
		log.Println("exec the cmd ", name, " failed")
		fmt.Println(err)
		return err
	}
	// 正常日志
	logScan := bufio.NewScanner(stdout)
	go func() {
		for logScan.Scan() {
			log.Println(logScan.Text())
		}
	}()
	// 错误日志
	errBuf := bytes.NewBufferString("")
	scan := bufio.NewScanner(stderr)
	for scan.Scan() {
		s := scan.Text()
		log.Println("build error: ", s)
		errBuf.WriteString(s)
		errBuf.WriteString("\n")
	}
	// 等待命令执行完
	cmd.Wait()
	if !cmd.ProcessState.Success() {
		// 执行失败,返回错误信息
		return errors.New(errBuf.String())
	}
	return nil
}