mirror of
https://github.com/mxpv/podsync.git
synced 2024-05-11 05:55:04 +00:00
Implement episode downloader
This commit is contained in:
107
pkg/ytdl/ytdl.go
Normal file
107
pkg/ytdl/ytdl.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package ytdl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/mxpv/podsync/pkg/config"
|
||||
"github.com/mxpv/podsync/pkg/model"
|
||||
)
|
||||
|
||||
const DownloadTimeout = 10 * time.Minute
|
||||
|
||||
type YoutubeDl struct{}
|
||||
|
||||
func New(ctx context.Context) (*YoutubeDl, error) {
|
||||
ytdl := &YoutubeDl{}
|
||||
|
||||
// Make sure youtube-dl exists
|
||||
version, err := ytdl.exec(ctx, "--version")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not find youtube-dl")
|
||||
}
|
||||
|
||||
log.Infof("using youtube-dl %s", version)
|
||||
|
||||
// Make sure ffmpeg exists
|
||||
output, err := exec.CommandContext(ctx, "ffmpeg", "-version").CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not find ffmpeg")
|
||||
}
|
||||
|
||||
log.Infof("using ffmpeg %s", output)
|
||||
|
||||
return ytdl, nil
|
||||
}
|
||||
|
||||
func (dl YoutubeDl) Download(ctx context.Context, feedConfig *config.Feed, url string, destPath string) (string, error) {
|
||||
if feedConfig.Format == model.FormatAudio {
|
||||
// Audio
|
||||
if feedConfig.Quality == model.QualityHigh {
|
||||
// High quality audio (encoded to mp3)
|
||||
return dl.exec(ctx,
|
||||
"--extract-audio",
|
||||
"--audio-format",
|
||||
"mp3",
|
||||
"--format",
|
||||
"bestaudio",
|
||||
"--output",
|
||||
destPath,
|
||||
url,
|
||||
)
|
||||
} else {
|
||||
// Low quality audio (encoded to mp3)
|
||||
return dl.exec(ctx,
|
||||
"--extract-audio",
|
||||
"--audio-format",
|
||||
"mp3",
|
||||
"--format",
|
||||
"worstaudio",
|
||||
"--output",
|
||||
destPath,
|
||||
url,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
Video
|
||||
*/
|
||||
if feedConfig.Quality == model.QualityHigh {
|
||||
// High quality
|
||||
return dl.exec(ctx,
|
||||
"--format",
|
||||
"bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best",
|
||||
"--output",
|
||||
destPath,
|
||||
url,
|
||||
)
|
||||
} else {
|
||||
// Low quality
|
||||
return dl.exec(ctx,
|
||||
"--format",
|
||||
"worstvideo[ext=mp4]+worstaudio[ext=m4a]/worst[ext=mp4]/worst",
|
||||
"--output",
|
||||
destPath,
|
||||
url,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (YoutubeDl) exec(ctx context.Context, args ...string) (string, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, DownloadTimeout)
|
||||
defer cancel()
|
||||
|
||||
cmd := exec.CommandContext(ctx, "youtube-dl", args...)
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return string(output), errors.Wrap(err, "failed to execute youtube-dl")
|
||||
}
|
||||
|
||||
return string(output), nil
|
||||
}
|
||||
Reference in New Issue
Block a user