summaryrefslogtreecommitdiff
path: root/scripts/ffut
blob: 87cf2b84b54ae6e473d48dbabd7997b4d6f463f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/usr/bin/env bash

# Strict mode for bash; used when wanting to find errors while scripting
set -euo pipefail
IFS=$'\n\t'

RED="\033[1;31m"
RESET="\033[0m"

# Already defining the input file as a variable
# as it was being a pain to check for the input file.
input_file="$1"

# Usage for script
usage() {
  clear
  cat <<'EOF'

TUI for ffmpeg to cut & change codec.

Usage: ffut video_file

EOF

}

# Bash expanded [] conditions of "video/*" to [..] which
# is a blank string. That was why it was always giving
# error message.
check_for_vid_file() {
  if [[ ! $(file --mime-type -b "$input_file") =~ video ]]; then
    printf "\n%b\n" "${RED}Error${RESET}: video file not provided (got: %s)." && exit 1
  fi
}

# Check for audio file for audio codec converstion
check_audio_file() {
  check_input_audio_file=$(file --mime-type -b "$input_file")
  if [[ ! $(file --mime-type -b "$input_file") =~ audio ]]; then
    printf "\n%b\n" "${RED}Error${RESET}: audio file not provided." && exit 1
  fi
}

CommandArgs=$(gum choose --limit 1 --header="Choose: cut or codec" "cut" "codec" || exit 1)

case "$CommandArgs" in
# Trimming videos
cut)
  # Funcion call for checking video file
  check_for_vid_file
  # Take input from the user; what to do?
  cut_opt=$(gum choose --limit 1 --header="Choose cut option:" "1. One point to Another" "2. One point to end of video" || exit 1)
  case "$cut_opt" in
  1*)
    # First asking from where to cut and till how much
    # then takes the input of the data and applies it to
    # ffmpeg command. Finally, asks if original file
    # should be deleted.
    seek_start=$(gum input --placeholder "Start: HH:MM:SS or MM:SS or sec")
    seek_end=$(gum input --placeholder "End: HH:MM:SS or MM:SS or sec")
    ffmpeg -ss "$seek_start" -to "$seek_end" -i "$input_file" -c copy "$(date +"%Y%m%d_%H%M ")$input_file" || exit 1
    gum confirm "Delete original file?" && rm "$1"
    ;;
  2*)
    # Just does the same thing as above but only asks for
    # starting point and cuts to the end of the video.
    seek_start=$(gum input --placeholder "Start: HH:MM:SS or MM:SS or sec")
    ffmpeg -ss "$seek_start" -i "$input_file" -c copy "$(date +"%Y%m%d_%H%M ")$input_file"
    gum confirm "Delete original file?" && rm "$1"
    ;;
  *)
    # Anything which is not a file after cut option
    # will give out usage output.
    usage
    exit 1
    ;;
  esac
  ;;
# Codec change
codec)
  [[ check_for_vid_file || check_audio_file ]]
  # Take input for changin either video or audio codec.
  codec_opt=$(gum choose --limit 1 --header="Choose:" "video" "audio" || exit 1)
  # On the basis of choice choose video or audio option.
  case "$codec_opt" in
  video)
    video_codec_opt=$(gum choose --limit 1 --header="Choose: video format" "H.264" "H.265" "VP9 [webm]" || exit 1)
    case "$video_codec_opt" in
    H.264)
      ffmpeg -i "$input_file" -c:v libx264 -crf 23 -c:a copy "$(date +"%Y%m%d_%H%M")_h264_$input_file" || exit 1
      ;;
    H.265)
      ffmpeg -i "$input_file" -c:v libx265 -crf 28 -c:a copy "$(date +"%Y%m%d_%H%M")_h265_$input_file" || exit 1
      ;;
    "VP9 [webm]")
      # Take the input file name, removes extension name with dot
      # and changes codec to libvpx-vp9 and ext to webm
      output_video_file=$(basename "$input_file" | sed 's/\.[^.]*$//')
      output_video_file_name_webm=$(date +"%Y%m%d_%H%M")"_$output_video_file".webm
      ffmpeg -i "$input_file" -c:v libvpx-vp9 -crf 30 -b:v 0 -cpu-used -0 -c:a copy -compression_level 10 "$output_video_file_name_webm" || exit 1
      ;;
    *)
      usage
      exit 1
      ;;
    esac
    ;;
  audio)
    check_audio_file
    audio_codec_opt=$(gum choose --limit 1 --header="Choose:" "AAC" "OPUS" "MP3" || exit 1)
    case "$audio_codec_opt" in
    AAC)
      output_audio_file=$(basename "$input_file" | sed 's/\.[^.]*$//')
      output_audio_file_aac="$output_audio_file".m4a
      if ffmpeg -codecs 2>/dev/null | grep -q libfdk_aac; then
        ffmpeg -i "$input_file" -c:v copy -c:a libfdk_aac -b:a 192k "$output_audio_file_aac"
      else
        ffmpeg -i "$input_file" -c:v copy -c:a aac -b:a 192k "$output_audio_file_aac"
      fi
      ;;
    OPUS)
      # Basically taking audio file and changing codec to libopus
      # and file extension to .opus
      output_audio_file=$(basename "$input_file" | sed 's/\.[^.]*$//')
      output_audio_file_opus="$output_audio_file".opus
      # opus codec for best efficiency
      ffmpeg -i "$input_file" -c:a libopus -b:a 128k -vn "$output_audio_file_opus"
      ;;
    MP3)
      # Same thing changing codec to libmp3lame and file
      # extension to .mp3
      output_audio_file=$(basename "$input_file" | sed 's/\.[^.]*$//')
      output_audio_file_mp3="$output_audio_file".mp3
      # High quality mp3 conversion
      ffmpeg -i "$input_file" -c:a libmp3lame -q:a 2 -vn "$output_audio_file_mp3"
      ;;
    *)
      usage
      exit 1
      ;;
    esac
    ;;
  esac
  ;;
*)
  usage
  exit 1
  ;;
esac