ffmpegutil.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package ffmpegutil
  2. import (
  3. "fmt"
  4. "net/http"
  5. "os"
  6. "os/exec"
  7. "path/filepath"
  8. "imuslab.com/arozos/mod/utils"
  9. )
  10. /*
  11. FFmepg Utilities function
  12. for agi.ffmpeg.go
  13. */
  14. /*
  15. ffmpeg_conv support input of a limited video, audio and image formats
  16. Compression value can be set if compression / resize is needed.
  17. Different conversion type have different meaning for compression values
  18. Video -> Video | compression means resolution in scale, e.g. 720 = 720p
  19. Video / Audio -> Audio | compression means bitrate, e.g. 128 = 128kbps
  20. Image -> Image | compression means final width of compression e.g. 1024 * 2048 with compression value
  21. set to 512, then the output will be 512 * 1024
  22. Set compression to 0 if resizing / compression is not required
  23. */
  24. func FFmpeg_conv(input string, output string, compression int, w *http.ResponseWriter) error {
  25. var cmd *exec.Cmd
  26. switch {
  27. case isVideo(input) && isVideo(output):
  28. // Video to video with resolution compression
  29. if compression == 0 {
  30. cmd = exec.Command("ffmpeg", "-i", input, output)
  31. } else {
  32. cmd = exec.Command("ffmpeg", "-i", input, "-vf", fmt.Sprintf("scale=-1:%d", compression), output)
  33. }
  34. case (isAudio(input) || isVideo(input)) && isAudio(output):
  35. // Audio or video to audio with bitrate compression
  36. if compression == 0 {
  37. cmd = exec.Command("ffmpeg", "-i", input, output)
  38. } else {
  39. cmd = exec.Command("ffmpeg", "-i", input, "-b:a", fmt.Sprintf("%dk", compression), output)
  40. }
  41. case (isImage(input) && isImage(output)) || (isVideo(input) && filepath.Ext(output) == ".gif"):
  42. // Resize image with width compression
  43. if compression == 0 {
  44. cmd = exec.Command("ffmpeg", "-i", input, output)
  45. } else {
  46. cmd = exec.Command("ffmpeg", "-i", input, "-vf", fmt.Sprintf("scale=%d:-1", compression), output)
  47. }
  48. default:
  49. // Handle other cases or leave it for the user to implement
  50. return fmt.Errorf("unsupported conversion: %s to %s", input, output)
  51. }
  52. // Set the output of the command to os.Stdout so you can see it in your console
  53. cmd.Stdout = os.Stdout
  54. // Set the output of the command to os.Stderr so you can see any errors
  55. cmd.Stderr = os.Stderr
  56. // Run the command
  57. err := cmd.Run()
  58. if err != nil {
  59. return fmt.Errorf("error running ffmpeg command: %v", err)
  60. }
  61. return nil
  62. }
  63. // Helper functions to check file types
  64. func isVideo(filename string) bool {
  65. videoFormats := []string{
  66. ".mp4", ".mkv", ".avi", ".mov", ".flv", ".webm",
  67. }
  68. return utils.StringInArray(videoFormats, filepath.Ext(filename))
  69. }
  70. func isAudio(filename string) bool {
  71. audioFormats := []string{
  72. ".mp3", ".wav", ".aac", ".ogg", ".flac",
  73. }
  74. return utils.StringInArray(audioFormats, filepath.Ext(filename))
  75. }
  76. func isImage(filename string) bool {
  77. imageFormats := []string{
  78. ".jpg", ".png", ".gif", ".bmp", ".tiff", ".webp",
  79. }
  80. return utils.StringInArray(imageFormats, filepath.Ext(filename))
  81. }