Add length and download sizes

This commit is contained in:
Carl Pearson
2024-09-06 15:21:42 -06:00
parent c7d65bf999
commit 6b50fbcc6f
3 changed files with 79 additions and 5 deletions

View File

@@ -129,6 +129,59 @@ func getMeta(url string) (Meta, error) {
}
}
// return the length in seconds of a video file at `path`
func getLength(path string) (float64, error) {
cmd := exec.Command("ffprobe", "-v", "error", "-show_entries", "format=duration",
"-of", "default=noprint_wrappers=1:nokey=1", path)
var stdout bytes.Buffer
cmd.Stdout = &stdout
err := cmd.Run()
if err != nil {
fmt.Println("getLength cmd error:", err)
return -1, err
}
result, err := strconv.ParseFloat(strings.TrimSpace(stdout.String()), 64)
if err != nil {
fmt.Println("getLength parse error:", err, stdout.String())
}
return result, nil
}
func humanLength(s float64) string {
ss := int64(s)
mm, ss := ss/60, ss%60
hh, mm := mm/60, mm%60
return fmt.Sprintf("%d:%02d:%02d", hh, mm, ss)
}
func getSize(path string) (int64, error) {
fi, err := os.Stat(path)
if err != nil {
return -1, err
}
return fi.Size(), nil
}
func humanSize(bytes int64) string {
const (
KiB = 1024
MiB = 1024 * KiB
GiB = 1024 * MiB
)
if bytes >= GiB {
return fmt.Sprintf("%.1f GiB", float64(bytes)/float64(GiB))
} else if bytes >= MiB {
return fmt.Sprintf("%.1f MiB", float64(bytes)/float64(MiB))
} else if bytes >= KiB {
return fmt.Sprintf("%.1f KiB", float64(bytes)/float64(KiB))
}
return fmt.Sprintf("%d bytes", bytes)
}
func startDownload(videoID uint, videoURL string) {
db.Model(&Video{}).Where("id = ?", videoID).Update("status", "downloading")
@@ -177,6 +230,22 @@ func startDownload(videoID uint, videoURL string) {
"audio_filename": audioFilename,
"status": "completed",
})
length, err := getLength(videoFilepath)
if err == nil {
db.Model(&Video{}).Where("id = ?", videoID).Update("length", humanLength(length))
}
videoSize, err := getSize(videoFilepath)
if err == nil {
db.Model(&Video{}).Where("id = ?", videoID).Update("video_size", humanSize(videoSize))
}
audioSize, err := getSize(audioFilepath)
if err == nil {
db.Model(&Video{}).Where("id = ?", videoID).Update("audio_size", humanSize(audioSize))
}
}
func videosHandler(c echo.Context) error {

View File

@@ -15,6 +15,9 @@ type Video struct {
VideoFilename string
AudioFilename string
UserID uint
Length string
AudioSize string
VideoSize string
Status string // "pending", "downloading", "completed", "failed", "cancelled"
}

View File

@@ -3,7 +3,7 @@
<head>
<title>Downloaded Videos</title>
<meta http-equiv="refresh" content="5">
<meta http-equiv="refresh" content="10">
<style>
table {
width: 100%;
@@ -27,20 +27,22 @@
<h1>Downloaded Videos</h1>
<table>
<tr>
<th>URL</th>
<th>Title</th>
<th>URL</th>
<th>Length</th>
<th>Status</th>
<th>Actions</th>
</tr>
{{range .videos}}
<tr>
<td>{{.URL}}</td>
<td>{{.Title}}</td>
<td>{{.URL}}</td>
<td>{{.Length}}</td>
<td>{{.Status}}</td>
<td>
{{if eq .Status "completed"}}
<a href="/downloads/video/{{.VideoFilename}}">Download Video</a> |
<a href="/downloads/audio/{{.AudioFilename}}">Download Audio</a>
<a href="/downloads/video/{{.VideoFilename}}">Download Video ({{.VideoSize}})</a> |
<a href="/downloads/audio/{{.AudioFilename}}">Download Audio ({{.AudioSize}})</a>
{{else if eq .Status "failed"}}
<form action="/video/{{.ID}}/restart" method="post" style="display:inline;">
<button type="submit">Restart</button>