1
0
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:
Maksym Pavlenko
2022-11-22 17:58:32 -08:00
committed by GitHub
6 changed files with 71 additions and 14 deletions

View File

@ -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.

View File

@ -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"`

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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{