加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
ffmpeg.go 3.98 KB
一键复制 编辑 原始数据 按行查看 历史
package main
import (
"BilibiliConvertGo/util"
"bufio"
"bytes"
"fmt"
"github.com/google/uuid"
"io"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"syscall"
"time"
)
// 检测ffmpeg环境是否存在
func checkFFmpeg() bool {
cmd := exec.Command("cmd", "/c", "start", "/b", "ffmpeg", "-version")
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
pipe, err := cmd.StdoutPipe()
if err != nil {
return false
}
if err := cmd.Start(); err != nil {
return false
}
reader := bufio.NewReader(pipe)
for true {
line, _, err := reader.ReadLine()
if err != nil {
fmt.Printf("err: %v", err)
return false
}
if strings.Index(string(line[:]), "version") != -1 {
return true
}
}
return false
}
func mergeM4S(videoPath string, audioPath string, outputPath string, overrideFlag bool, onlyAudio bool, bitrate int64, progressCallBack func(p float32)) {
modifyBitrate := false
finalBitrate := -1
if bitrate != 100 {
videoBitrate := parseBitrateInfo(videoPath)
if videoBitrate != -1 {
finalBitrate = int(float64(videoBitrate) * 0.01 * float64(bitrate))
modifyBitrate = true
}
}
// 创建文件夹
_ = os.Mkdir(".bilibili_convert_temp", os.ModePerm)
progressPath := ".bilibili_convert_temp" + string(filepath.Separator) + uuid.New().String()
// 是否覆盖输出文件
overrideOutput := "-n"
if overrideFlag {
overrideOutput = "-y"
}
// 执行转换命令
cmd := exec.Command("cmd", "/c")
if onlyAudio {
cmd = exec.Command(
"cmd",
"/c",
"start",
"/b",
"ffmpeg",
"-i",
audioPath,
"-progress",
progressPath,
outputPath,
overrideOutput)
} else {
if modifyBitrate && finalBitrate != -1 {
cmd = exec.Command(
"cmd",
"/c",
"start",
"/b",
"ffmpeg",
"-i",
videoPath,
"-i",
audioPath,
"-b:v",
strconv.FormatInt(int64(finalBitrate), 10)+"k",
"-progress",
progressPath,
outputPath,
overrideOutput)
} else {
cmd = exec.Command(
"cmd",
"/c",
"start",
"/b",
"ffmpeg",
"-i",
videoPath,
"-i",
audioPath,
"-progress",
progressPath,
"-codec",
"copy",
outputPath,
overrideOutput)
}
}
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
// 开启线程,检测文件转换进度
go func() {
time.Sleep(time.Duration(500) * time.Millisecond)
// 计算文件转换完成之后的文件大小
size2 := util.GetFileSize(audioPath)
totalSize := float32(size2)
if !onlyAudio {
size1 := util.GetFileSize(videoPath)
totalSize = float32(size1) + float32(size2)
}
file, err := os.Open(progressPath)
if err != nil {
return
}
defer file.Close()
reader := bufio.NewReader(file)
for {
line, _, err := reader.ReadLine()
if err == io.EOF {
continue
}
// 获取已转换的文件大小
if strings.Index(string(line), "total_size=") != -1 {
// 计算转换的进度
f1, _ := strconv.ParseInt(string(line[11:]), 10, 64)
pro := float32(f1) / totalSize * 100
if pro >= 100 {
pro = 99.99
}
progressCallBack(pro)
}
// 判断是否转换完成
if strings.Index(string(line), "progress=end") != -1 {
progressCallBack(100)
return
}
}
}()
err := cmd.Run()
if err != nil {
return
}
}
func parseBitrateInfo(filepath string) int64 {
cmd := exec.Command("ffmpeg", "-i", filepath)
infoOutput, _ := cmd.CombinedOutput()
output := string(infoOutput)
// 示例:假设输出中含有 "bitrate: 2000 kb/s" 的信息
// 使用字符串处理方法截取 "bitrate: " 后面的部分
startIndex := strings.Index(output, "bitrate: ")
if startIndex == -1 {
return -1
}
startIndex += len("bitrate: ")
// 使用字符串处理方法截取 " kb/s" 前面的部分
endIndex := strings.Index(output[startIndex:], " kb/s")
if endIndex == -1 {
return -1
}
parseInt, err := strconv.ParseInt(output[startIndex:startIndex+endIndex], 10, 64)
if err != nil {
return -1
}
return parseInt
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化