代码拉取完成,页面将自动刷新
同步操作将从 全糖咖啡/B站缓存转视频工具-Golang 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
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
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。