progress shenanigan!
This commit is contained in:
parent
386be2bd37
commit
c263ccbda0
|
@ -194,7 +194,7 @@ func (c *CopyCommand) _transcode_file(file *types.File, trans_config *transcoder
|
|||
log.Info().Str("file", new_filename).Msg("Transcoding File")
|
||||
}
|
||||
|
||||
output, err := transcoder.Transcode(file, trans_config, dest_filepath)
|
||||
output, err := transcoder.Transcode(file, trans_config, nil, dest_filepath)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Str("output", output).Msg("Transcode Failed")
|
||||
}
|
||||
|
|
|
@ -95,7 +95,22 @@ func (c *TranscodeCommand) Run() {
|
|||
output_file.Extension, transcode_config.FileExtension)
|
||||
}
|
||||
|
||||
output, err := transcoder.Transcode(input_file, transcode_config, output_file.JoinPathTo())
|
||||
progress_chan := make(chan string)
|
||||
go func() {
|
||||
for {
|
||||
progress, isnt_closed := <-progress_chan
|
||||
if isnt_closed {
|
||||
log.Info().
|
||||
Str("src", *c.Args.Source).
|
||||
Str("progress", progress).
|
||||
Msg("Transcoding")
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
output, err := transcoder.Transcode(input_file, transcode_config, progress_chan, output_file.JoinPathTo())
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Str("output", output).Msg("Transcode Failed")
|
||||
}
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
package transcoder
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitlab.com/ChaotiCryptidz/musicutil/types"
|
||||
)
|
||||
|
@ -29,7 +35,59 @@ func isNotEmptyString(x string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func Transcode(file *types.File, config *TranscodeConfig, dest string) (string, error) {
|
||||
func progressDurationToMilliSeconds(duration string) int64 {
|
||||
fields := strings.Split(strings.TrimSpace(duration), ":")
|
||||
durationNs := int64(0)
|
||||
|
||||
h, _ := strconv.ParseInt(fields[0], 10, 64)
|
||||
durationNs += int64(time.Hour) * h
|
||||
|
||||
m, _ := strconv.ParseInt(fields[1], 10, 64)
|
||||
durationNs += int64(time.Minute) * m
|
||||
|
||||
s, _ := strconv.ParseFloat(fields[2], 64)
|
||||
durationNs += int64(float64(time.Second) * s)
|
||||
|
||||
return time.Duration(durationNs).Milliseconds()
|
||||
}
|
||||
|
||||
func getFileLengthMilliSeconds(filename string) (int64, error) {
|
||||
type FFProbeFormat struct {
|
||||
Duration string `json:"duration"`
|
||||
}
|
||||
type FFProbeOutput struct {
|
||||
Format FFProbeFormat `json:"format"`
|
||||
}
|
||||
|
||||
ffprobe_output_str, err := exec.Command(
|
||||
"ffprobe",
|
||||
"-v", "quiet",
|
||||
"-print_format", "json",
|
||||
"-show_format",
|
||||
filename,
|
||||
).Output()
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var ffprobe_output FFProbeOutput
|
||||
err = json.Unmarshal([]byte(ffprobe_output_str), &ffprobe_output)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
duration_str := ffprobe_output.Format.Duration
|
||||
duration_float, err := strconv.ParseFloat(duration_str, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
duration_millis := int64(math.Round(duration_float * 1000))
|
||||
return duration_millis, nil
|
||||
}
|
||||
}
|
||||
|
||||
func Transcode(file *types.File, config *TranscodeConfig, progress_chan chan string, dest string) (string, error) {
|
||||
command_args := make([]string, 0)
|
||||
command_args = append(command_args, "-y")
|
||||
command_args = append(command_args, "-hide_banner")
|
||||
|
@ -69,11 +127,55 @@ func Transcode(file *types.File, config *TranscodeConfig, dest string) (string,
|
|||
|
||||
command_args = append(command_args, dest)
|
||||
|
||||
// Progress Shenanigans
|
||||
|
||||
if progress_chan != nil {
|
||||
total_length_milliseconds, err := getFileLengthMilliSeconds(file.JoinPathTo())
|
||||
if err != nil {
|
||||
goto end
|
||||
}
|
||||
|
||||
progress_temp_dir, err := os.MkdirTemp("", "*-musicutil_transcode_temp")
|
||||
if err != nil {
|
||||
goto end
|
||||
}
|
||||
defer os.RemoveAll(progress_temp_dir)
|
||||
|
||||
progress_filename := progress_temp_dir + "/progress.log"
|
||||
progress_file, err := os.Create(progress_filename)
|
||||
if err != nil {
|
||||
goto end
|
||||
}
|
||||
defer os.Remove(progress_filename)
|
||||
|
||||
command_args = append(command_args, "-progress", progress_filename, "-nostats")
|
||||
|
||||
go func() {
|
||||
reader := bufio.NewReader(progress_file)
|
||||
for {
|
||||
line, err := reader.ReadBytes('\n')
|
||||
if err == nil {
|
||||
if strings.HasPrefix(string(line), "out_time=") {
|
||||
out_time := strings.TrimSuffix(strings.TrimPrefix(string(line), "out_time="), "\n")
|
||||
out_time_ms := progressDurationToMilliSeconds(out_time)
|
||||
|
||||
progress_chan <- fmt.Sprintf("%0.2f%%", (float64(out_time_ms) / float64(total_length_milliseconds) * 100))
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
end:
|
||||
cmd := exec.Command("ffmpeg", command_args...)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(output)
|
||||
return string(output), errors.New("ffmpeg error")
|
||||
}
|
||||
|
||||
if progress_chan != nil {
|
||||
close(progress_chan)
|
||||
}
|
||||
return string(output), nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue