mirror of
https://github.com/mxpv/podsync.git
synced 2024-05-11 05:55:04 +00:00
108 lines
2.2 KiB
Go
108 lines
2.2 KiB
Go
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
|
|
}
|