代码拉取完成,页面将自动刷新
同步操作将从 haha_Dashen/TCS_Main 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
package main
import (
"fmt"
"log"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
)
/*
Thread Pool 信号
1 = Worker已被主线程初始化 等待Worker反馈
200 = Worker已经确认工作
201 = MP4转码进行中
202 = MP4转码结束
203 = HLS切片进行中
204 = HLS切片结束
205 = DASH切片进行中
206 = DASH切片结束
210 = 所有工作结束
100 = 无法正确加载工作
101 = Worker被多次初始化
120 = Worker已经崩溃
*/
func Worker(WorkerID int,WorkID int) {
var WorkFilename string
var WorkRandom string
var WorkTime int64
var WorkTimeDay int64
var WorkStatus int
var WorkMD5 string
var FFmpeg *exec.Cmd
//Video Filter
var VFCommand string
var VFInit bool
defer func() {
log.Println("[Worker",WorkerID,"][WARN] Worker可能崩溃 已重置进程池 如下方输出崩溃信息 请联系开发者")
ThreadPool[WorkerID]=0
if err := recover(); err != nil {
log.Println("[Panic Log]"+identifyPanic())
return
}
return
}()
if ThreadPool[WorkerID] != 1 {
log.Println("[Worker",WorkerID,"][WARN] Worker可能被多次初始化 请联系开发者")
return
}
//Get Work
err = Database.QueryRow("SELECT * FROM VideoList WHERE ID = '?'",WorkID).Scan(&WorkID,&WorkFilename,&WorkRandom,&WorkTimeDay,&WorkTime,&WorkStatus,&WorkMD5)
if err != nil {
log.Println("[Worker",WorkerID,"][WARN] 无法正常读取工作数据 ",err.Error())
return
}
FileExt := filepath.Ext(WorkFilename)
EncodingFile := WorkRandom+FileExt
//Start
log.Println("[Worker",WorkerID,"] Worker已启动")
VFInit = false
VFCommand = ""
//开始转码MP4
//TODO: GPU Support
var TCommand string
TCommand = "-i "+EncodingFile
//分辨率
if VFInit {
VFCommand = VFCommand+",scale="+EncodeRes
}else{
VFCommand = "-vf scale="+EncodeRes
}
//帧率
if VFInit {
VFCommand = VFCommand+",fps="+strconv.Itoa(EncodeFramerate)
}else{
VFCommand = "-vf fps="+strconv.Itoa(EncodeFramerate)
}
TCommand=TCommand+" "+VFCommand
//Codec
TCommand=TCommand+" -c:v libx264 -c:a aac"
//Bitrate
FFmpeg = exec.Command(TCommand)
FFmpeg.Stderr = &BufferPool[WorkerID]
FFmpeg.Stdout = &BufferPool[WorkerID]
WorkerMonitor(WorkerID,FFmpeg)
//开始组合HLS
var HLSCommand string
if EncodeHLS {
HLSCommand = "-i "+EncodingFile
FFmpeg = exec.Command("ffmpeg.exe",strings.Split(HLSCommand," ")...)
FFmpeg.Stderr = &BufferPool[WorkerID]
FFmpeg.Stdout = &BufferPool[WorkerID]
WorkerMonitor(WorkerID,FFmpeg)
}
}
func WorkerMonitor(WorkerID int,FFmpeg *exec.Cmd) {
var err error
var Percent float64
var Cache []byte
RealTimeProcessRegex := regexp.MustCompile(`time=(.*)bitrate`)
TotalTimeRegex := regexp.MustCompile(`Duration: (.*), start`)
TotalTime:=0
for {
if string(Cache) != string(BufferPool[WorkerID].Bytes()) {
Output := strings.Replace(string(BufferPool[WorkerID].Bytes()),string(Cache),"",-1)
Cache = BufferPool[WorkerID].Bytes()
//Get Total Time
fmt.Println(Output)
if TotalTime == 0 {
TotalMatches := TotalTimeRegex.FindStringSubmatch(Output)
if len(TotalMatches) > 0 {
fmt.Println(TotalMatches[1])
TotalTime,err = SecondConvert(TotalMatches[1])
if err == nil {
fmt.Println("TotalTime:",TotalTime)
}
}
}else{
ProcessMatches:= RealTimeProcessRegex.FindStringSubmatch(Output)
if len(ProcessMatches) > 0{
TimeSecond,err := SecondConvert(ProcessMatches[1])
if err == nil {
Percent = float64(TimeSecond)/float64(TotalTime)*100
fmt.Println(TotalTime,"|",TimeSecond,"|",fmt.Sprintf("%.3f",Percent),"%")
}
}
}
}
time.Sleep(200*time.Millisecond)
if FFmpeg.ProcessState != nil {
log.Println("[Worker",WorkerID,"][M] 进程已结束")
break
}
}
}
func SecondConvert(Time string)(int,error) {
TimeRune := []rune(Time)
TimeSplit := strings.Split(string(TimeRune[0:len(TimeRune)-4]),":")
if len(TimeSplit) == 3 {
TimeHour,err := strconv.Atoi(TimeSplit[0])
if err != nil {
return 0 , fmt.Errorf("E")
}
TimeMin,err := strconv.Atoi(TimeSplit[1])
if err != nil {
return 0 , fmt.Errorf("E")
}
TimeSec,err := strconv.Atoi(TimeSplit[2])
if err != nil {
return 0 , fmt.Errorf("E")
}
TimeEnd := (TimeHour*3600)+(TimeMin*60)+TimeSec
return TimeEnd,nil
}else{
return 0 , fmt.Errorf("E")
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。