diff --git a/.gitattributes b/.gitattributes index 7fdaaf4e..b6df76f8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,7 @@ **/*.gif filter=lfs diff=lfs merge=lfs -text **/*.mp4 filter=lfs diff=lfs merge=lfs -text **/*.webm filter=lfs diff=lfs merge=lfs -text +**/*.webp filter=lfs diff=lfs merge=lfs -text **/*.png filter=lfs diff=lfs merge=lfs -text *.tape linguist-language=elixir themes*.json linguist-generated diff --git a/README.md b/README.md index 8e3384ae..892b27b0 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,9 @@ Write terminal GIFs as code for integration testing and demoing your CLI tools. -Welcome to VHS +Welcome to VHS -The above example was generated with VHS ([view source](./examples/neofetch/neofetch.tape)). +The above example was generated with VHS ([view source](./examples/fastfetch/fastfetch.tape)). ## Tutorial @@ -248,6 +248,7 @@ will render them to the respective locations. Output out.gif Output out.mp4 Output out.webm +Output out.webp Output frames/ # a directory of frames as a PNG sequence ``` diff --git a/command.go b/command.go index 4e5b0d06..d55bbcbe 100644 --- a/command.go +++ b/command.go @@ -414,6 +414,8 @@ func ExecuteOutput(c parser.Command, v *VHS) error { v.Options.Video.Output.Frames = c.Args case ".webm": v.Options.Video.Output.WebM = c.Args + case ".webp": + v.Options.Video.Output.WebP = c.Args default: v.Options.Video.Output.GIF = c.Args } diff --git a/examples/demo.tape b/examples/demo.tape index 46edfd04..ea0f4bd5 100644 --- a/examples/demo.tape +++ b/examples/demo.tape @@ -4,6 +4,7 @@ # Output .gif Create a GIF output at the given # Output .mp4 Create an MP4 output at the given # Output .webm Create a WebM output at the given +# Output .webp Create a WebP output at the given # # Require: # Require Ensure a program is on the $PATH to proceed diff --git a/examples/fastfetch/README.md b/examples/fastfetch/README.md new file mode 100644 index 00000000..f7c4203d --- /dev/null +++ b/examples/fastfetch/README.md @@ -0,0 +1,7 @@ +# fastfetch + + + +# Source code for the VHS fastfetch example + +See [fastfetch.tape](fastfetch.tape) diff --git a/examples/fastfetch/config.jsonc b/examples/fastfetch/config.jsonc new file mode 100644 index 00000000..d6e3ecf8 --- /dev/null +++ b/examples/fastfetch/config.jsonc @@ -0,0 +1,70 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "type": "file-raw", + "source": "examples/fastfetch/vhs-color.ascii", + "padding": { + "right": 2 + } + }, + "display": { + "separator": ": " + }, + "modules": [ + { + "type": "custom", + "format": "charmbracelet/vhs", + "outputColor": "magenta" + }, + "break", + { + "type": "custom", + "key": "OS", + "format": "Video Home System", + "keyColor": "green" + }, + { + "type": "custom", + "key": "Packages", + "format": "(2) tree-sitter-vhs, vhs-action", + "keyColor": "green" + }, + { + "type": "custom", + "key": "Shell", + "format": "bash 5.2", + "keyColor": "green" + }, + { + "type": "custom", + "key": "Resolution", + "format": "1200x600", + "keyColor": "green" + }, + { + "type": "custom", + "key": "Theme", + "format": "VHS", + "keyColor": "green" + }, + { + "type": "custom", + "key": "Icons", + "format": "VHS", + "keyColor": "green" + }, + { + "type": "custom", + "key": "Terminal", + "format": "xterm.js", + "keyColor": "green" + }, + { + "type": "custom", + "key": "Font", + "format": "JetBrains Mono", + "keyColor": "green" + }, + "colors" + ] +} diff --git a/examples/fastfetch/fastfetch.gif b/examples/fastfetch/fastfetch.gif new file mode 100644 index 00000000..42617329 Binary files /dev/null and b/examples/fastfetch/fastfetch.gif differ diff --git a/examples/fastfetch/fastfetch.mp4 b/examples/fastfetch/fastfetch.mp4 new file mode 100644 index 00000000..ceb0fde2 Binary files /dev/null and b/examples/fastfetch/fastfetch.mp4 differ diff --git a/examples/fastfetch/fastfetch.tape b/examples/fastfetch/fastfetch.tape new file mode 100644 index 00000000..358891a1 --- /dev/null +++ b/examples/fastfetch/fastfetch.tape @@ -0,0 +1,36 @@ +# Source code for the VHS fastfetch example. +# +# To run: +# +# vhs < fastfetch.tape + +Output examples/fastfetch/fastfetch.gif +Output examples/fastfetch/fastfetch.mp4 +Output examples/fastfetch/fastfetch.webm +Output examples/fastfetch/fastfetch.webp +Output examples/fastfetch/frames/ + +Set TypingSpeed 75ms +Set FontSize 18 +Set Width 1300 +Set Height 550 + +Hide +Type "fastfetch() { command fastfetch -c examples/fastfetch/config.jsonc --pipe false; }" +Enter +Type "clear" +Enter +Show + +Type "fastfetch" + +Sleep 500ms +Enter +Sleep 2s + +Type "Welcome to VHS!" +Sleep 1 +Space +Type "A tool for generating terminal GIFs from code." + +Sleep 5s diff --git a/examples/fastfetch/fastfetch.webm b/examples/fastfetch/fastfetch.webm new file mode 100644 index 00000000..0cfea71d Binary files /dev/null and b/examples/fastfetch/fastfetch.webm differ diff --git a/examples/fastfetch/fastfetch.webp b/examples/fastfetch/fastfetch.webp new file mode 100644 index 00000000..c9f1d35f Binary files /dev/null and b/examples/fastfetch/fastfetch.webp differ diff --git a/examples/neofetch/vhs-color.ascii b/examples/fastfetch/vhs-color.ascii similarity index 100% rename from examples/neofetch/vhs-color.ascii rename to examples/fastfetch/vhs-color.ascii diff --git a/examples/neofetch/vhs.ascii b/examples/fastfetch/vhs.ascii similarity index 100% rename from examples/neofetch/vhs.ascii rename to examples/fastfetch/vhs.ascii diff --git a/examples/fixtures/all.tape b/examples/fixtures/all.tape index c72be570..06360877 100644 --- a/examples/fixtures/all.tape +++ b/examples/fixtures/all.tape @@ -4,6 +4,7 @@ Output examples/fixtures/all.gif Output examples/fixtures/all.mp4 Output examples/fixtures/all.webm +Output examples/fixtures/all.webp # Settings: Set Shell "fish" diff --git a/examples/neofetch/README.md b/examples/neofetch/README.md deleted file mode 100644 index d3aa7281..00000000 --- a/examples/neofetch/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Neofetch - - - -``` -# Source code for the VHS neofetch example. -# -# To run: -# -# vhs < neofetch.tape - -Output examples/neofetch/neofetch.gif -Output examples/neofetch/neofetch.mp4 -Output examples/neofetch/neofetch.webm -Output examples/neofetch/frames/ - -Set TypingSpeed 75ms -Set FontSize 22 -Set Width 1300 -Set Height 650 - -Type "neofetch" - -Sleep 500ms - -Enter - -Sleep 2s - -Type "Welcome to VHS!" - -Sleep 1 - -Space - -Type "A tool for generating terminal GIFs from code." - -Sleep 5s -``` diff --git a/examples/neofetch/colorize-ascii.go b/examples/neofetch/colorize-ascii.go deleted file mode 100644 index a0d9387a..00000000 --- a/examples/neofetch/colorize-ascii.go +++ /dev/null @@ -1,46 +0,0 @@ -// Package neofetch is an example package. -// -//nolint:unused -package neofetch - -import ( - _ "embed" - "fmt" - "strings" - - "github.com/charmbracelet/lipgloss" - "github.com/muesli/termenv" -) - -//go:embed vhs.ascii -var art string - -func main() { - lipgloss.SetColorProfile(termenv.TrueColor) - - var ( - b strings.Builder - lines = strings.Split(art, "\n") - colors = []string{"#AD92FF", "#9D7CFF", "#906BFF", "#8056FF"} - step = len(lines) / len(colors) - ) - - for i, l := range lines { - n := clamp(0, len(colors)-1, i/step) - b.WriteString(colorize(colors[n], l)) - b.WriteRune('\n') - } - - fmt.Print(b.String()) -} - -func colorize(c, s string) string { - return lipgloss.NewStyle().Foreground(lipgloss.Color(c)).Render(s) -} - -func clamp(v, low, high int) int { - if high < low { - low, high = high, low - } - return min(high, max(low, v)) -} diff --git a/examples/neofetch/neofetch.gif b/examples/neofetch/neofetch.gif deleted file mode 100644 index 6252fa7a..00000000 --- a/examples/neofetch/neofetch.gif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:87d4c62af968c29ac92005ae590428bbe8fa0cc363741bb0bcf34a3276b8b9ab -size 140587 diff --git a/examples/neofetch/neofetch.mp4 b/examples/neofetch/neofetch.mp4 deleted file mode 100644 index 3541d30c..00000000 --- a/examples/neofetch/neofetch.mp4 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b2105bdc9233889dc6e9d2d0c891c0f6e11396808d418f29284563ba0326e8f5 -size 178995 diff --git a/examples/neofetch/neofetch.tape b/examples/neofetch/neofetch.tape deleted file mode 100644 index ff0e4b3f..00000000 --- a/examples/neofetch/neofetch.tape +++ /dev/null @@ -1,33 +0,0 @@ -# Source code for the VHS neofetch example. -# -# To run: -# -# vhs < neofetch.tape - -Output examples/neofetch/neofetch.gif -Output examples/neofetch/neofetch.mp4 -Output examples/neofetch/neofetch.webm -Output examples/neofetch/frames/ - -Set TypingSpeed 75ms -Set FontSize 22 -Set Width 1300 -Set Height 650 - -Type "neofetch" - -Sleep 500ms - -Enter - -Sleep 2s - -Type "Welcome to VHS!" - -Sleep 1 - -Space - -Type "A tool for generating terminal GIFs from code." - -Sleep 5s diff --git a/examples/neofetch/neofetch.webm b/examples/neofetch/neofetch.webm deleted file mode 100644 index 630a2302..00000000 --- a/examples/neofetch/neofetch.webm +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c21bf41b43a78165a5f9f2ba8344ad26b89c1ef02bafff6a53ace70fcf848972 -size 290879 diff --git a/examples/neofetch/vhs.conf b/examples/neofetch/vhs.conf deleted file mode 100644 index 298be642..00000000 --- a/examples/neofetch/vhs.conf +++ /dev/null @@ -1,19 +0,0 @@ -print_info () { - prin - prin "$(color 5)charmbracelet/vhs" - prin - prin "$(color 2)OS" "Video Home System" - prin "$(color 2)Packages" "(2) tree-sitter-vhs, vhs-action" - prin "$(color 2)Shell" "bash 5.2" - prin "$(color 2)Resolution" "1200x600" - info "Theme" theme - info "Icons" icons - prin "$(color 2)Terminal" "xterm.js" - prin "$(color 2)Font" "JetBrains Mono" - prin "$(color 2)Format" "Graphics Interchange" - - info cols -} - -image_source="$(cat ~/.config/neofetch/vhs-color.ascii)" -gap=-18 diff --git a/ffmpeg.go b/ffmpeg.go index d35823af..edbe5710 100644 --- a/ffmpeg.go +++ b/ffmpeg.go @@ -318,6 +318,21 @@ func (sb *StreamBuilder) WithWebm() *StreamBuilder { return sb } +// WithWebP adds animated WebP stream configuration. +func (sb *StreamBuilder) WithWebP() *StreamBuilder { + sb.args = append(sb.args, + "-vcodec", "libwebp_anim", + "-pix_fmt", "yuva420p", + "-quality", "100", + "-compression_level", "3", + "-lossless", "0", + "-loop", "0", + "-an", + ) + + return sb +} + // Build returns streams for using with ffmepg. func (sb *StreamBuilder) Build() []string { return sb.args diff --git a/lexer/lexer_test.go b/lexer/lexer_test.go index fd637a72..8d8bd9e2 100644 --- a/lexer/lexer_test.go +++ b/lexer/lexer_test.go @@ -163,6 +163,8 @@ func TestLexTapeFile(t *testing.T) { {token.STRING, "examples/fixtures/all.mp4"}, {token.OUTPUT, "Output"}, {token.STRING, "examples/fixtures/all.webm"}, + {token.OUTPUT, "Output"}, + {token.STRING, "examples/fixtures/all.webp"}, {token.COMMENT, " Settings:"}, {token.SET, "Set"}, {token.SHELL, "Shell"}, diff --git a/main.go b/main.go index 4e319bb5..6fc9d1ef 100644 --- a/main.go +++ b/main.go @@ -106,6 +106,8 @@ var ( v.Options.Video.Output.GIF = output } else if strings.HasSuffix(output, webm) { v.Options.Video.Output.WebM = output + } else if strings.HasSuffix(output, webp) { + v.Options.Video.Output.WebP = output } else if strings.HasSuffix(output, mp4) { v.Options.Video.Output.MP4 = output } diff --git a/man.go b/man.go index 816343b2..02dd830c 100644 --- a/man.go +++ b/man.go @@ -24,7 +24,7 @@ A tape file is a script made up of commands describing what actions to perform i The following is a list of all possible commands in VHS: -* %Output% .(gif|webm|mp4) +* %Output% .(gif|webm|webp|mp4) * %Require% * %Set% * %Sleep%