mirror of
https://github.com/mxpv/podsync.git
synced 2024-05-11 05:55:04 +00:00
Merge pull request #442 from Harnas/feature/custom_file_format
feat: added custom format support
This commit is contained in:
@ -50,14 +50,18 @@ vimeo = [ # Multiple keys will be rotated.
|
||||
# How often query for updates, examples: "60m", "4h", "2h45m"
|
||||
update_period = "12h"
|
||||
|
||||
quality = "high" # or "low"
|
||||
format = "video" # or "audio"
|
||||
quality = "high" # "high" or "low"
|
||||
format = "video" # "audio", "video" or "custom"
|
||||
# When format = "custom"
|
||||
# YouTubeDL format parameter and result file extension
|
||||
custom_format = { youtube_dl_format = "bestaudio[ext=m4a]", extension = "m4a" }
|
||||
|
||||
playlist_sort = "asc" # or "desc", which will fetch playlist items from the end
|
||||
|
||||
# Optional maximal height of video, example: 720, 1080, 1440, 2160, ...
|
||||
max_height = 720
|
||||
|
||||
# Optinally include this feed in OPML file (default value: false)
|
||||
# Optionally include this feed in OPML file (default value: false)
|
||||
opml = true
|
||||
|
||||
# Optional cron expression format for more precise update schedule.
|
||||
|
@ -28,6 +28,8 @@ type Config struct {
|
||||
MaxHeight int `toml:"max_height"`
|
||||
// Format to use for this feed
|
||||
Format model.Format `toml:"format"`
|
||||
// Custom format properties
|
||||
CustomFormat CustomFormat `toml:"custom_format"`
|
||||
// Only download episodes that match this regexp (defaults to matching anything)
|
||||
Filters Filters `toml:"filters"`
|
||||
// Clean is a cleanup policy to use for this feed
|
||||
@ -44,6 +46,11 @@ type Config struct {
|
||||
PlaylistSort model.Sorting `toml:"playlist_sort"`
|
||||
}
|
||||
|
||||
type CustomFormat struct {
|
||||
YouTubeDLFormat string `toml:"youtube_dl_format"`
|
||||
Extension string `toml:"extension"`
|
||||
}
|
||||
|
||||
type Filters struct {
|
||||
Title string `toml:"title"`
|
||||
NotTitle string `toml:"not_title"`
|
||||
|
@ -133,6 +133,9 @@ func Build(_ctx context.Context, feed *model.Feed, cfg *Config, hostname string)
|
||||
if feed.Format == model.FormatAudio {
|
||||
enclosureType = itunes.MP3
|
||||
}
|
||||
if feed.Format == model.FormatCustom {
|
||||
enclosureType = EnclosureFromExtension(cfg)
|
||||
}
|
||||
|
||||
var (
|
||||
episodeName = EpisodeName(cfg, episode)
|
||||
@ -165,6 +168,31 @@ func EpisodeName(feedConfig *Config, episode *model.Episode) string {
|
||||
if feedConfig.Format == model.FormatAudio {
|
||||
ext = "mp3"
|
||||
}
|
||||
if feedConfig.Format == model.FormatCustom {
|
||||
ext = feedConfig.CustomFormat.Extension
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s.%s", episode.ID, ext)
|
||||
}
|
||||
|
||||
func EnclosureFromExtension(feedConfig *Config) itunes.EnclosureType {
|
||||
ext := feedConfig.CustomFormat.Extension
|
||||
|
||||
switch {
|
||||
case ext == "m4a":
|
||||
return itunes.M4A
|
||||
case ext == "m4v":
|
||||
return itunes.M4V
|
||||
case ext == "mp4":
|
||||
return itunes.MP4
|
||||
case ext == "mp3":
|
||||
return itunes.MP3
|
||||
case ext == "mov":
|
||||
return itunes.MOV
|
||||
case ext == "pdf":
|
||||
return itunes.PDF
|
||||
case ext == "epub":
|
||||
return itunes.EPUB
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
@ -16,8 +16,9 @@ const (
|
||||
type Format string
|
||||
|
||||
const (
|
||||
FormatAudio = Format("audio")
|
||||
FormatVideo = Format("video")
|
||||
FormatAudio = Format("audio")
|
||||
FormatVideo = Format("video")
|
||||
FormatCustom = Format("custom")
|
||||
)
|
||||
|
||||
// Playlist sorting style
|
||||
|
@ -198,6 +198,10 @@ func (dl *YoutubeDl) Download(ctx context.Context, feedConfig *feed.Config, epis
|
||||
if feedConfig.Format == model.FormatAudio {
|
||||
ext = "mp3"
|
||||
}
|
||||
if feedConfig.Format == model.FormatCustom {
|
||||
ext = feedConfig.CustomFormat.Extension
|
||||
}
|
||||
|
||||
// filePath now with the final extension
|
||||
filePath = filepath.Join(tmpDir, fmt.Sprintf("%s.%s", episode.ID, ext))
|
||||
f, err := os.Open(filePath)
|
||||
@ -236,7 +240,7 @@ func buildArgs(feedConfig *feed.Config, episode *model.Episode, outputFilePath s
|
||||
}
|
||||
|
||||
args = append(args, "--format", format)
|
||||
} else {
|
||||
} else if feedConfig.Format == model.FormatAudio {
|
||||
// Audio, mp3, high by default
|
||||
format := "bestaudio"
|
||||
if feedConfig.Quality == model.QualityLow {
|
||||
@ -244,6 +248,8 @@ func buildArgs(feedConfig *feed.Config, episode *model.Episode, outputFilePath s
|
||||
}
|
||||
|
||||
args = append(args, "--extract-audio", "--audio-format", "mp3", "--format", format)
|
||||
} else {
|
||||
args = append(args, "--audio-format", feedConfig.CustomFormat.Extension, "--format", feedConfig.CustomFormat.YouTubeDLFormat)
|
||||
}
|
||||
|
||||
// Insert additional per-feed youtube-dl arguments
|
||||
|
@ -11,14 +11,15 @@ import (
|
||||
|
||||
func TestBuildArgs(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
format model.Format
|
||||
quality model.Quality
|
||||
maxHeight int
|
||||
output string
|
||||
videoURL string
|
||||
ytdlArgs []string
|
||||
expect []string
|
||||
name string
|
||||
format model.Format
|
||||
customFormat feed.CustomFormat
|
||||
quality model.Quality
|
||||
maxHeight int
|
||||
output string
|
||||
videoURL string
|
||||
ytdlArgs []string
|
||||
expect []string
|
||||
}{
|
||||
{
|
||||
name: "Audio unknown quality",
|
||||
@ -101,6 +102,15 @@ func TestBuildArgs(t *testing.T) {
|
||||
ytdlArgs: []string{"--write-sub", "--embed-subs", "--sub-lang", "en,en-US,en-GB"},
|
||||
expect: []string{"--format", "bestvideo[ext=mp4][vcodec^=avc1]+bestaudio[ext=m4a]/best[ext=mp4][vcodec^=avc1]/best[ext=mp4]/best", "--write-sub", "--embed-subs", "--sub-lang", "en,en-US,en-GB", "--output", "/tmp/2", "http://url1"},
|
||||
},
|
||||
{
|
||||
name: "Custom format",
|
||||
format: model.FormatCustom,
|
||||
customFormat: feed.CustomFormat{YouTubeDLFormat: "bestaudio[ext=m4a]", Extension: "m4a"},
|
||||
quality: model.QualityHigh,
|
||||
output: "/tmp/2",
|
||||
videoURL: "http://url1",
|
||||
expect: []string{"--audio-format", "m4a", "--format", "bestaudio[ext=m4a]", "--output", "/tmp/2", "http://url1"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tst := range tests {
|
||||
@ -108,6 +118,7 @@ func TestBuildArgs(t *testing.T) {
|
||||
result := buildArgs(&feed.Config{
|
||||
Format: tst.format,
|
||||
Quality: tst.quality,
|
||||
CustomFormat: tst.customFormat,
|
||||
MaxHeight: tst.maxHeight,
|
||||
YouTubeDLArgs: tst.ytdlArgs,
|
||||
}, &model.Episode{
|
||||
|
Reference in New Issue
Block a user