python flv转mp4_ffmpeg将多个flv文件合成为mp4(golang版)

需求

之前拿python写了个合并flv文件为mp4的脚本,运行感觉有点慢,用go重写下

注意事项

flv文件直接合并生成mp4的话只有第一个flv的内容才能播放,需要先转换成ts再合成mp4

命令行调用ffmpeg,需要自己另外安装,并配置环境变量

-loglevel quiet是调用ffmpeg不输出日志的选项,需要日志的话可以不加

代码

package main

import (

"bytes"

"flag"

"fmt"

"io/ioutil"

"os"

"os/exec"

"path/filepath"

"strings"

"sync"

"time"

)

var (

wg sync.WaitGroup

)

// 判断文件或目录是否存在

func pathExists(path string) (bool, error) {

_, err := os.Stat(path)

if err == nil {

return true, nil

}

if os.IsNotExist(err) {

return false, nil

}

return false, err

}

// 命令行调用

func Cmd(commandName string, params []string) (string, error) {

cmd := exec.Command(commandName, params...)

//fmt.Println("Cmd", cmd.Args)

var out bytes.Buffer

cmd.Stdout = &out

cmd.Stderr = os.Stderr

err := cmd.Start()

if err != nil {

return "", err

}

err = cmd.Wait()

return out.String(), err

}

// 视频格式转换

func videoConvert(in string, out string) {

defer wg.Done()

//fmt.Println(in, out)

cmdStr := fmt.Sprintf("ffmpeg -i %s -loglevel quiet -c copy -bsf:v h264_mp4toannexb -f mpegts %s", in, out)

args := strings.Split(cmdStr, " ")

msg, err := Cmd(args[0], args[1:])

if err != nil {

fmt.Printf("videoConvert failed, %v, output: %v\n", err, msg)

return

}

}

// 视频合成

func videoMerge(in []string, out string) {

//fmt.Println(in, out)

cmdStr := fmt.Sprintf("ffmpeg -i concat:%s -loglevel quiet -c copy -absf aac_adtstoasc -movflags faststart %s",

strings.Join(in, "|"), out)

args := strings.Split(cmdStr, " ")

msg, err := Cmd(args[0], args[1:])

if err != nil {

fmt.Printf("videoMerge failed, %v, output: %v\n", err, msg)

return

}

}

func flvs2mp4(inDir string, outFile string)(err error) {

tsFileDir := filepath.Join(inDir, "tsfile")

if err = os.RemoveAll(tsFileDir); err != nil {

return

}

if err = os.RemoveAll(outFile); err != nil {

return

}

if err = os.Mkdir(tsFileDir,0666); err!=nil {

return

}

infiles, _ := ioutil.ReadDir(inDir)

for _, f := range infiles {

if filepath.Ext(f.Name()) == ".flv" {

tsfileName := filepath.Join(tsFileDir, strings.TrimSuffix(f.Name(), ".flv") + ".ts")

wg.Add(1)

go videoConvert(filepath.Join(inDir, f.Name()), tsfileName)

}

}

wg.Wait()

tsfiles, _ := ioutil.ReadDir(tsFileDir)

tsfileNames := make([]string, 0, len(tsfiles))

for _, f := range tsfiles {

if filepath.Ext(f.Name()) == ".ts" {

tsfileNames = append(tsfileNames, filepath.Join(tsFileDir, f.Name()))

}

}

videoMerge(tsfileNames, outFile)

return

}

func main() {

start := time.Now()

var inputDir string

var outputName string

flag.StringVar(&inputDir, "i", "./dvr-file/flv", "input file dir")

flag.StringVar(&outputName, "o", "out.mp4", "output file name")

//解析命令行参数

flag.Parse()

exist, err := pathExists(inputDir)

if err != nil {

fmt.Printf("get dir error!: %v", err)

return

}

if !exist {

inputDir = os.Args[0]

}

inputDir, _ = filepath.Abs(inputDir)

fmt.Println("argv: ", inputDir, outputName)

if err = flvs2mp4(inputDir, outputName); err != nil {

fmt.Printf("flv to mp4 error!: %v", err)

}

elapsed := time.Since(start)

fmt.Println("Running time:", elapsed)

}

运行结果

82c4c6bd564b449dd0acbb43e1231c45.png

flvs2mp4-go-2020-3-22-22-55-44.png

11个30s左右的flv合成mp4不用groutine需要时间5.74秒,开启groutine只要3.2秒,确实快了不少

有疑问加站长微信联系(非本文作者)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值