Skip to content

Commit

Permalink
Support to gif
Browse files Browse the repository at this point in the history
  • Loading branch information
wzshiming committed Nov 1, 2024
1 parent 96ed1f7 commit ce5d587
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
111 changes: 111 additions & 0 deletions cmd/democtl/gif/gif.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package gif

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"

"github.com/spf13/cobra"
"github.com/wzshiming/democtl/pkg/renderer"
"github.com/wzshiming/democtl/pkg/renderer/video"
)

func NewCommand() *cobra.Command {
var (
input string
output string
)
cmd := &cobra.Command{
Use: "gif",
Short: "Convert terminal session to gif",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
if input == "" {
return fmt.Errorf("no input file specified")
}
err := run(input, output)
if err != nil {
return err
}
return nil
},
}
cmd.Flags().StringVarP(&input, "input", "i", input, "input filename")
cmd.Flags().StringVarP(&output, "output", "o", output, "output directory")
return cmd
}

func run(inputPath, outputPath string) error {
input, err := os.OpenFile(inputPath, os.O_RDONLY, 0)
if err != nil {
return err
}
defer input.Close()

if outputPath == "" {
inputExt := filepath.Ext(inputPath)
outputPath = inputPath[:len(inputPath)-len(inputExt)] + ".gif"
}

rawDir := outputPath + ".raw"

err = os.MkdirAll(rawDir, 0755)
if err != nil {
return err
}

err = renderer.Render(context.Background(), video.NewCanvas(rawDir, false), input)
if err != nil {
return err
}

stat, err := os.Stat(outputPath)
if err == nil {
if stat.IsDir() {
return fmt.Errorf("output directory already exists")
} else {
os.Remove(outputPath)
}
}

ffmpegPath, err := exec.LookPath("ffmpeg")
if err != nil {
fmt.Printf(`# Next step: run the following command to generate the video
###############################
ffmpeg \
-f concat \
-safe 0 \
-i %q \
%q
rm -rf %q
###############################
`, filepath.Join(rawDir, "frames.txt"), outputPath, rawDir)
return nil
}

args := []string{
"-f", "concat",
"-safe", "0",
"-i", filepath.Join(rawDir, "frames.txt"),
outputPath,
}

info, err := exec.Command(ffmpegPath, args...).CombinedOutput()
if err != nil {
return fmt.Errorf("ffmpeg failed: %w:%s", err, string(info))
}

_, err = os.Stat(outputPath)
if err != nil {
return err
}

err = os.RemoveAll(rawDir)
if err != nil {
return err
}

return nil
}
2 changes: 2 additions & 0 deletions cmd/democtl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"

"github.com/spf13/cobra"
"github.com/wzshiming/democtl/cmd/democtl/gif"
"github.com/wzshiming/democtl/cmd/democtl/mp4"
"github.com/wzshiming/democtl/cmd/democtl/play"
"github.com/wzshiming/democtl/cmd/democtl/record"
Expand All @@ -25,6 +26,7 @@ func main() {
play.NewCommand(),
svg.NewCommand(),
mp4.NewCommand(),
gif.NewCommand(),
)

err := cmd.Execute()
Expand Down

0 comments on commit ce5d587

Please sign in to comment.