From c52290392dc040bf25030fc0638476f3b3a4b4a4 Mon Sep 17 00:00:00 2001 From: ari melody Date: Sat, 31 Jan 2026 04:19:20 +0000 Subject: [PATCH 1/3] update README --- README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b36d3c7..ff53e8f 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,13 @@ I built this to greatly simplify the process of getting my full-quality livestre $ vodular New config file created (config.toml). Please edit this file before running again! ``` +The directory which holds your configuration file and templates varies, +depending on platform: +- **Linux:** `~/.config/vodular/templates` +- **macOS:** `~/Library/Application Support/vodular/templates` +- **Windows:** `%AppData%/vodular/templates` -2. Edit configuration file as necessary (You will need to create a [YouTube Data API v3](https://developers.google.com/youtube/v3) service and provide its credentials here). +2. Edit your configuration file as necessary (You will need to create a [YouTube Data API v3](https://developers.google.com/youtube/v3) service and provide its credentials here). **IMPORTANT:** `config.toml` contains very sensitive credentials. Do not share this file with anyone. 3. Initialise a VOD directory: @@ -63,10 +68,11 @@ url = 'https://example.org' ``` ## Templates -Template files can be created at `templates/title.txt`, -`template/description.txt`, and `templates/tags.txt` respectively. These -files can use Go's [text template format](https://pkg.go.dev/text/template) to -customise VOD metadata on upload. +There are three template files, `title.txt`, `description.txt`, and `tags.txt`, +which can be created in `/path/to/vodular/templates`. These templates can be +created and tweaked to customise your VOD metadata on upload. They are enhanced +with Go's [template format](https://pkg.go.dev/text/template) to inject +information provided in `metadata.toml`, and other neat functionality! You can use the following data in templates: - **`.Title`:** The title of the stream. From 9f32aedc3b193aa1e1004b4f955dacb9f2e7aa9e Mon Sep 17 00:00:00 2001 From: ari melody Date: Sat, 31 Jan 2026 18:10:39 +0000 Subject: [PATCH 2/3] exclude dot-prefixed files from footage scan --- main.go | 1 + scanner/scanner.go | 1 + 2 files changed, 2 insertions(+) diff --git a/main.go b/main.go index 0768f0a..3c28cd9 100644 --- a/main.go +++ b/main.go @@ -317,6 +317,7 @@ func main() { log.Print("Video uploaded successfully!") // update metadata to reflect VOD is uploaded + // TODO: rather than a boolean flag, link to actual video metadata.Uploaded = true err = scanner.WriteMetadata(directory, metadata) if err != nil { diff --git a/scanner/scanner.go b/scanner/scanner.go index 394c4f1..1ff5bd9 100644 --- a/scanner/scanner.go +++ b/scanner/scanner.go @@ -51,6 +51,7 @@ func ScanSegments(directory string, extension string) ([]string, error) { for _, item := range entries { if item.IsDir() { continue } + if strings.HasPrefix(item.Name(), ".") { continue } if !strings.HasSuffix(item.Name(), "." + extension) { continue } if strings.HasSuffix(item.Name(), "-fullvod." + extension) { continue } files = append(files, item.Name()) From dd54e8cc494092544df6446a79bc5268f18d8c3d Mon Sep 17 00:00:00 2001 From: ari melody Date: Sun, 1 Feb 2026 17:08:16 +0000 Subject: [PATCH 3/3] add warnings for exceeding metadata character length --- main.go | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index 3c28cd9..341711a 100644 --- a/main.go +++ b/main.go @@ -26,7 +26,9 @@ import ( //go:embed res/help.txt var helpText string -const segmentExtension = "mkv" +const SEGMENT_EXTENSION = "mkv" +const MAX_TITLE_LEN = 100 +const MAX_DESCRIPTION_LEN = 5000 func showHelp() { fmt.Println(helpText) @@ -194,7 +196,7 @@ func main() { } // scan for VOD segments - vodFiles, err := scanner.ScanSegments(metadata.FootageDir, segmentExtension) + vodFiles, err := scanner.ScanSegments(metadata.FootageDir, SEGMENT_EXTENSION) if err != nil { log.Fatalf("Failed to fetch VOD filenames: %v", err) os.Exit(1) @@ -202,7 +204,7 @@ func main() { if len(vodFiles) == 0 { log.Fatalf( "Directory contained no VOD files (expecting .%s)", - segmentExtension, + SEGMENT_EXTENSION, ) os.Exit(1) } @@ -221,21 +223,35 @@ func main() { log.Fatalf("Failed to build video template: %v", err) os.Exit(1) } + title, err := yt.BuildTemplate(video, templates.Title) + if err != nil { + log.Fatalf("Failed to build video title: %v", err) + os.Exit(1) + } + description, err := yt.BuildTemplate(video, templates.Description) + if err != nil { + log.Fatalf("Failed to build video description: %v", err) + os.Exit(1) + } + if len(title) > 100 { + log.Fatalf( + "Video title length exceeds %d characters (%d). YouTube may reject this!", + MAX_TITLE_LEN, + len(video.Title), + ) + } + if len(description) > 5000 { + log.Fatalf( + "Video description length exceeds %d characters (%d). YouTube may reject this!", + MAX_DESCRIPTION_LEN, + len(description), + ) + } if verbose { enc := json.NewEncoder(os.Stdout) fmt.Printf("\nVideo template: ") enc.Encode(video) - title, err := yt.BuildTemplate(video, templates.Title) - if err != nil { - log.Fatalf("Failed to build video title: %v", err) - os.Exit(1) - } - description, err := yt.BuildTemplate(video, templates.Description) - if err != nil { - log.Fatalf("Failed to build video description: %v", err) - os.Exit(1) - } fmt.Printf( "\n================================\n\n" + "< TITLE >\n%s\n\n" +