1
0
mirror of https://github.com/mxpv/podsync.git synced 2024-05-11 05:55:04 +00:00

108 lines
2.2 KiB
Go
Raw Normal View History

2019-11-13 18:16:35 -08:00
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
}