核心思想:使用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
}