always re-encode to mp4
This commit is contained in:
@@ -23,6 +23,7 @@ docker build -t server .
|
|||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
-p 3000:8080 \
|
-p 3000:8080 \
|
||||||
--env YTDLP_SITE_ADMIN_INITIAL_PASSWORD=abc123 \
|
--env YTDLP_SITE_ADMIN_INITIAL_PASSWORD=abc123 \
|
||||||
|
--env YTDLP_SITE_SESSION_AUTH_KEY=avowt7n8 \
|
||||||
server
|
server
|
||||||
|
|
||||||
docker run --rm -it \
|
docker run --rm -it \
|
||||||
|
33
handlers.go
33
handlers.go
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@@ -99,32 +98,22 @@ func downloadPostHandler(c echo.Context) error {
|
|||||||
|
|
||||||
type Meta struct {
|
type Meta struct {
|
||||||
title string
|
title string
|
||||||
ext string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMeta(url string) (Meta, error) {
|
func getMeta(url string) (Meta, error) {
|
||||||
cmd := exec.Command("yt-dlp", "--simulate", "--print", "%(title)s.%(ext)s", url)
|
cmd := exec.Command("yt-dlp",
|
||||||
|
"--simulate", "--print", "%(title)s",
|
||||||
|
url)
|
||||||
|
|
||||||
var stdout bytes.Buffer
|
var stdout bytes.Buffer
|
||||||
cmd.Stdout = &stdout
|
cmd.Stdout = &stdout
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("getTitle error:", err)
|
fmt.Println("getTitle error:", err, stdout.String())
|
||||||
return Meta{}, err
|
return Meta{}, err
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
isDot := func(r rune) bool {
|
|
||||||
return r == '.'
|
|
||||||
}
|
|
||||||
|
|
||||||
fields := strings.FieldsFunc(strings.TrimSpace(stdout.String()), isDot)
|
|
||||||
if len(fields) < 2 {
|
|
||||||
return Meta{}, errors.New("couldn't parse ytdlp output")
|
|
||||||
}
|
|
||||||
|
|
||||||
return Meta{
|
return Meta{
|
||||||
title: strings.Join(fields[:len(fields)-1], "."),
|
title: strings.TrimSpace(stdout.String()),
|
||||||
ext: fields[len(fields)-1],
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,7 +172,7 @@ func humanSize(bytes int64) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func startDownload(videoID uint, videoURL string) {
|
func startDownload(videoID uint, videoURL string) {
|
||||||
db.Model(&Video{}).Where("id = ?", videoID).Update("status", "downloading")
|
db.Model(&Video{}).Where("id = ?", videoID).Update("status", "metadata")
|
||||||
|
|
||||||
meta, err := getMeta(videoURL)
|
meta, err := getMeta(videoURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -193,15 +182,21 @@ func startDownload(videoID uint, videoURL string) {
|
|||||||
fmt.Println("set video title:", meta.title)
|
fmt.Println("set video title:", meta.title)
|
||||||
db.Model(&Video{}).Where("id = ?", videoID).Update("title", meta.title)
|
db.Model(&Video{}).Where("id = ?", videoID).Update("title", meta.title)
|
||||||
|
|
||||||
videoFilename := fmt.Sprintf("%d-%s.%s", videoID, meta.title, meta.ext)
|
db.Model(&Video{}).Where("id = ?", videoID).Update("status", "downloading")
|
||||||
|
videoFilename := fmt.Sprintf("%d-%s.mp4", videoID, meta.title)
|
||||||
videoFilepath := filepath.Join(getDownloadDir(), "video", videoFilename)
|
videoFilepath := filepath.Join(getDownloadDir(), "video", videoFilename)
|
||||||
cmd := exec.Command("yt-dlp", "-o", videoFilepath, videoURL)
|
cmd := exec.Command("yt-dlp",
|
||||||
|
"-f", "bestvideo[height<=720]+bestaudio/best[height<=720]",
|
||||||
|
"--recode-video", "mp4",
|
||||||
|
"-o", videoFilepath,
|
||||||
|
videoURL)
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
db.Model(&Video{}).Where("id = ?", videoID).Update("status", "failed")
|
db.Model(&Video{}).Where("id = ?", videoID).Update("status", "failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db.Model(&Video{}).Where("id = ?", videoID).Update("status", "audio")
|
||||||
audioFilename := fmt.Sprintf("%d-%s.mp3", videoID, meta.title)
|
audioFilename := fmt.Sprintf("%d-%s.mp3", videoID, meta.title)
|
||||||
audioFilepath := filepath.Join(getDownloadDir(), "audio", audioFilename)
|
audioFilepath := filepath.Join(getDownloadDir(), "audio", audioFilename)
|
||||||
audioDir := filepath.Dir(audioFilepath)
|
audioDir := filepath.Dir(audioFilepath)
|
||||||
|
@@ -19,6 +19,7 @@ func authMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
|
|||||||
userID, ok := session.Values["user_id"]
|
userID, ok := session.Values["user_id"]
|
||||||
if !ok {
|
if !ok {
|
||||||
fmt.Println("authMiddleware: session does not contain user_id. Redirect to /login")
|
fmt.Println("authMiddleware: session does not contain user_id. Redirect to /login")
|
||||||
|
// return c.String(http.StatusForbidden, "not logged in")
|
||||||
return c.Redirect(http.StatusSeeOther, "/login")
|
return c.Redirect(http.StatusSeeOther, "/login")
|
||||||
}
|
}
|
||||||
fmt.Println("set user_id", userID, "in context")
|
fmt.Println("set user_id", userID, "in context")
|
||||||
|
@@ -10,10 +10,8 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>Downloaded Video {{.video.Title}}</h1>
|
<h1>Downloaded Video {{.video.Title}}</h1>
|
||||||
|
|
||||||
<video controls width="250">
|
<video controls playsinline width="250" preload="metadata">
|
||||||
<source src="/downloads/video/{{.video.VideoFilename}}" type="video/mp4" />
|
<source src="/downloads/video/{{.video.VideoFilename}}" type="video/mp4" />
|
||||||
|
|
||||||
<!-- <source src="/media/cc0-videos/flower.mp4" type="video/mp4" /> -->
|
|
||||||
</video>
|
</video>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@@ -35,8 +35,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{{range .videos}}
|
{{range .videos}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{.ID}} {{.Title}}</td>
|
<td><a href="/video/{{.ID}}">{{.Title}}</a></td>
|
||||||
<td>{{.URL}}</td>
|
<td><a href="{{.URL}}">{{.URL}}</a></td>
|
||||||
<td>{{.Length}}</td>
|
<td>{{.Length}}</td>
|
||||||
<td>{{.Status}}</td>
|
<td>{{.Status}}</td>
|
||||||
<td>
|
<td>
|
||||||
|
Reference in New Issue
Block a user