Class: MultimediaParadise::CutMultimedia

Inherits:
MultimediaBase show all
Defined in:
lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb,
lib/multimedia_paradise/multimedia/cut_multimedia/interactive_menu.rb,
lib/multimedia_paradise/multimedia/cut_multimedia/evaluate_from_this_file.rb

Overview

MultimediaParadise::CutMultimedia

Constant Summary collapse

NAMESPACE =
#

NAMESPACE

#
inspect
DEFAULT_INPUT_FILE =
#

DEFAULT_INPUT_FILE

#
'/home/x/songs/Womack_and_Womack_Teardrops.mp3'
FILE_LAST_USED =
#

FILE_LAST_USED

#
"#{MultimediaParadise.log_dir?}cut_audio_last_file_used.yml"
CREATE_A_LOG_FILE =
#

CREATE_A_LOG_FILE

If this constant is true then we will create a log file.

#
false
PROMPT_TO_USE =
#

PROMPT_TO_USE

#
'> '
USE_THIS_PLAYER =
#

USE_THIS_PLAYER

Which audio/video player to use for audio-playback.

By default we will use the player set on the toplevel MultimediaParadise namespace.

This constant will then return e. g. a String such as “mpv”.

#
MultimediaParadise.player?
ARRAY_LOCATIONS_TO_CHECK_FOR_FFMPEG =

Set it here.

array.flatten.uniq

Constants inherited from Base

Base::ERROR, Base::ERROR_LINE, Base::USE_THIS_NAMESPACE_FOR_THE_COLOURS, Base::USE_THIS_NAMESPACE_FOR_THE_CORE_COLOURS

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#actions, #append_what_into, #be_silent, #be_verbose?, #beautiful_url, #cartoons_directory?, #clear_the_internal_hash, #cliner, #cliner_with_time_stamp, #colourized_comment, #copy_file, #crimson, #dataset_from_file_video_collection, #dd_mm_yyyy, #debug?, #default_readlines, #directory_to_realvids?, #do_not_use_opn, #dodgerblue, #does_the_video_player_support_this_commandline?, #e, #ecomment, #ecrimson, #efancy, #enable_debug, #ensure_main_encoding, #ensure_that_the_output_directory_exists, #eparse, #erev, #ewarn, #file_video_collection?, #filter_for_audio_files, #filter_for_video_files, #forestgreen, #gold, #grey, #hh_mm_ss, #home_x_video?, #indianred, #infer_the_namespace, #internal_hash?, #is_audio_file?, #is_mkv?, #is_mp3?, #is_mp4?, #is_multimedia_file?, #is_on_roebe?, #is_video_file?, #konsole_colour_peru, #lightblue, #lightgreen, #load_yaml, #local_audio_directory?, #log_dir?, #map_symbol_to_locally_existing_file, #mediumorchid, #mediumpurple, #mediumslateblue, #mkdir, #move_file, #namespace?, #no_file_exists, #no_file_exists_at, #olive, #olivedrab, #opne, #opnecomment, #opnn, #orange, #palegoldenrod, #palegreen, #powderblue, #project_base_directory?, #rds, #remove_file, #report_pwd, #reset_the_internal_hash, #return_all_video_files, #return_pwd, #return_random_video, #rev, #royalblue, #save_what_into, #sdir, #seagreen, #seconds_to_time_format, #select_only_video_files_from, #set_be_verbose, #set_use_colours, #sfancy, #sfile, #simp, #skyblue, #slateblue, #springgreen, #steelblue, #swarn, #teal, #time_right_now, #to_hh_mm_ss, #tomato, #true_rev, #try_to_rename_kde_konsole_tab, #ucliner, #use_colours?, #use_opn?, #use_which_video_player?, #verbose_truth, #video_collection?, #violet, #yaml_directory?, #yel

Methods included from CommandlineArgumentsModule

#all_input_starts_with_a_number?, #commandline_arguments?, #commandline_arguments_as_a_string, #first_argument?, #first_non_hyphened_commandline_argument?, #set_commandline_arguments

Constructor Details

#initialize(commandline_arguments = nil, run_already = true) ⇒ CutMultimedia

#

initialize

The very first argument to this class should be location to the file that you may want to edit.

#


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 135

def initialize(
    commandline_arguments = nil,
    run_already           = true
  )
  register_sigint
  reset
  # ======================================================================= #
  # First handle special Symbols given to this class.
  # ======================================================================= #
  case commandline_arguments
  when :interactive,
       :run_interactive
    set_interactive_mode_then_enter_interactive_mode
  end
  if commandline_arguments and commandline_arguments.is_a?(Array) and
     commandline_arguments.empty?
     commandline_arguments << DEFAULT_INPUT_FILE
  end
  set_commandline_arguments(
    commandline_arguments
  )
  # ======================================================================= #
  # === Handle blocks next
  # ======================================================================= #
  if block_given?
    yielded = yield
    case yielded
    # ===================================================================== #
    # === :gui
    # ===================================================================== #
    when :gui
      @usage_mode = :gui
    end
  end
  # ======================================================================= #
  # Next check whether a file exists, before we enter the interactive
  # part potentially.
  # ======================================================================= #
  check_whether_the_commandline_arguments_contain_a_file_and_assign_this_as_the_main_file
  # ======================================================================= #
  # The following check must happen before we invoke set_file()
  # because set_file may also exit the program. This is not
  # deserved when we run the program in interactive mode.
  # ======================================================================= #
  case run_already
  # ======================================================================= #
  # === :dont_run_yet
  # ======================================================================= #
  when :dont_run_yet,
       :do_not_run_yet
    run_already = false
  # ======================================================================= #
  # === :interactive
  # ======================================================================= #
  when :interactive,
       :run_interactive
    set_interactive_mode_then_enter_interactive_mode
    run_already = false
  end
  run if run_already
end

Class Method Details

.[](i, optional_limitation_of_duration = nil) ⇒ Object

#

MultimediaParadise::CutMultimedia[]

This class-method also allows some extra instructions such as to limit the duration.

Example:

MultimediaParadise::CutMultimedia['*.mp3', '60 seconds']

This will fetch all .mp3 files.

#


1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1450

def self.[](
    i, optional_limitation_of_duration = nil
  )
  if i.is_a? String and i.include?('*')
    i = Dir[i] # This performs a glob, essentially.
  end
  if i.is_a? Array
    # ===================================================================== #
    # Work in batch-processing mode in this case.
    # ===================================================================== #
    if optional_limitation_of_duration and
       optional_limitation_of_duration.include?('seconds')
      i.each {|entry|
        _ = self.new(entry, :do_not_run_yet)
        _.set_start_at 0
        _.set_end_at(
          optional_limitation_of_duration.to_s.gsub(/seconds/,'').strip.to_f
        )
        _.cut
      }
    end
  else
    new(i, :run_interactive)
  end
end

.evaluate_from_this_file(i) ⇒ Object

#

MultimediaParadise::CutMultimedia.evaluate_from_this_file

This method can be used to read from a local file and use this file as batch-instruction to cut at the specified position.

#


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
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/evaluate_from_this_file.rb', line 25

def self.evaluate_from_this_file(i)
  if i.is_a? Array
    i = i.first
  end
  i = i.to_s
  if File.exist? i
    file_content = File.readlines(i).map {|inner_line|
      inner_line.strip.delete(' ')
    }.reject {|line|
      line.start_with?('#') or line.strip.empty? # Ignore comments and empty lines.
    }
    all_multimedia_files = Dir['*'] - [i]
    sample = all_multimedia_files.sample
    _ = MultimediaParadise::CutMultimedia.new(nil, :dont_run_yet)
    _.set_work_on_this_file(sample)
    _.interactive_menu(file_content)
    _.do_cut
    # ===================================================================== #
    # Next, merge these files:
    # ===================================================================== #
    files_to_be_merged = Dir['cutted_*']
    result = MultimediaParadise.merge(files_to_be_merged)
    if File.exist? result
      MultimediaParadise.e 'Converting to .wav, then converting back to .mp3.'
      MultimediaParadise.esystem 'lame --decode -v '+result
      FileUtils.mv(
        result.delete_suffix(File.extname(result))+'.wav',
        'new_file.wav'
      )
      result = MultimediaParadise::Audio::WavToMp3.new('new_file.wav')
      if File.exist? 'new_file.mp3'
        MultimediaParadise.e 'The (new) file can be found at: '+
                              File.absolute_path('new_file.mp3')
        # ================================================================= #
        # And do some clean-up actions in this case:
        # ================================================================= #
        File.delete('new_file.wav') if File.exist? 'new_file.wav'
        File.delete('output.mp3')   if File.exist? 'output.mp3'
        Dir['cutted_*'].each {|this_file|
          File.delete(this_file)
        }
      else
        MultimediaParadise.e 'No file exists at new_file.mp3.'
      end
    end
  else
    MultimediaParadise.e 'No file exists at '+sfile(i)+'.'
  end
end

Instance Method Details

#absolute_path_of_the_output_file?(output_file = output_file? ) ⇒ Boolean

#

absolute_path_of_the_output_file?

#

Returns:

  • (Boolean)


1653
1654
1655
1656
1657
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1653

def absolute_path_of_the_output_file?(
    output_file = output_file?
  )
  File.absolute_path(output_file) if output_file
end

#append_the_user_input_onto_the_history(i = @user_input) ⇒ Object

#

append_the_user_input_onto_the_history

#


862
863
864
865
866
867
868
869
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 862

def append_the_user_input_onto_the_history(
    i = @user_input
  )
  # ======================================================================= #
  # Keep track of the input-history next.
  # ======================================================================= #
  @array_input_history << i if i
end

#array_all_end_positions?Boolean Also known as: end_positions?, end_position?, all_end_positions?

#

array_all_end_positions?

#

Returns:

  • (Boolean)


347
348
349
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 347

def array_all_end_positions?
  @array_all_end_positions
end

#array_all_start_positions?Boolean Also known as: start_positions?, all_start_positions?

#

array_all_start_positions?

#

Returns:

  • (Boolean)


1096
1097
1098
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1096

def array_all_start_positions?
  @array_all_start_positions
end

#build_ffmpeg_command(this_file = main_file?, , duration = duration? ) ⇒ Object

#

build_ffmpeg_command

This method will build the proper ffmpeg command.

#


1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1923

def build_ffmpeg_command( # Assemble the FFMPEG main string here.
    this_file = main_file?,
    duration  = duration?
  )
  ensure_that_there_is_at_least_one_end_position
  # ======================================================================= #
  # Next, we must ensure that the @array_all_end_positions is never nil.
  # ======================================================================= #
  ensure_that_array_cut_end_is_valid
  # ======================================================================= #
  # Merge it all into one Array.
  # ======================================================================= #
  merged_array = all_start_positions?.zip(all_end_positions?)
  # ======================================================================= #
  # Iterate over that Array next.
  # ======================================================================= #
  merged_array.each {|entry|
    the_start_position = entry.first # Grab the first entry.
    the_end_position   = entry[1]    # Grab the second entry.
    the_end_position   = duration.to_f if the_end_position.to_f > duration.to_f
    # ===================================================================== #
    # the_end position should never be nil at this point.
    # ===================================================================== #
    @t.set_start_position = the_start_position
    @t.set_end_position   = the_end_position
    e 'Now cutting multimedia-file '+sfancy('`'+this_file+'`')+','
    e "starting at position #{simp(the_start_position.to_s)} and ending at "\
      "position #{simp(the_end_position.to_s)}:"
    e
    # ===================================================================== #
    # Label our output file properly, by prepending the word "cutted_",
    # the start position and the end position.
    # ===================================================================== #
    output_file = 'cutted_'+the_start_position.to_s+
                  '-'+the_end_position.to_s+'_seconds_'+
                  File.basename(this_file)
    set_output_file(output_file)
    # ===================================================================== #
    # === Does the output file exist
    #
    # Check whether the output file exists or whether it does not.
    # ===================================================================== #
    if File.exist? output_file?.to_s
      e "File `#{sfile(output_file?)}` already exists."
      e 'We will remove it before continuing.'
      remove(output_file?)
    end
    # ===================================================================== #
    # Next, build up the ffmpeg command.
    # ===================================================================== #
    if this_file.include? ' '
      this_file = '"'+this_file+'"'
    end
    difference_in_seconds = the_end_position.to_f - the_start_position.to_f
    the_start_position = @t.convert_to_long_format(the_start_position)
    # ===================================================================== #
    # Ok, here we start the real ffmpeg command.
    # ===================================================================== #
    _ = 'ffmpeg -i '.dup
    _ << this_file+' '
    _ << '-acodec copy ' # This will copy. See Stackoverflow here: http://stackoverflow.com/a/44032/722915
    if is_video_file?(this_file)
      _ << '-vcodec copy '
    end
    _ << '-ss '+
         the_start_position
    _ << ' -t '+
         @t.convert_to_long_format(difference_in_seconds)+
         ' '+output_file?.to_s # Relies on ffmpeg.
    # ===================================================================== #
    # Next, determine whether we will log into a text file or whether
    # we will not.
    # ===================================================================== #
    if create_log_file?
      output_file = output_file.dup if output_file.frozen?
      output_file << '.md'
      log_cut_action(@t.start?, @t.end?, _, output_file)
    end
    cliner
    e
    e steelblue(_) # Feedback the command we will use to the user here.
    e
    cliner
    e # And a newline too.
    system _
  }
end

#calculate(n_seconds) ⇒ Object

#

calculate

Calculcate how many seconds are here.

#


1232
1233
1234
1235
1236
1237
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1232

def calculate(
    n_seconds
  )
  n_minutes, n_seconds = n_seconds.to_s.split(':')
  return ((n_minutes.to_i * 60).to_i + n_seconds.to_i).to_s
end

#check_whether_ffmpeg_is_installedObject

#

check_whether_ffmpeg_is_installed

We have to check whether the user has ffmpeg installed. Because if ffmpeg is unavailable, then cut_audio will not work.

#


1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1519

def check_whether_ffmpeg_is_installed
  _ = ARRAY_LOCATIONS_TO_CHECK_FOR_FFMPEG
  is_ffmpeg_installed = false
  _.each {|path|
    is_ffmpeg_installed = true if File.exist? path+'ffmpeg'
  }
  unless is_ffmpeg_installed
    opnn { :no_trailing_colon }; e
    e
    e '  FFmpeg is not installed or could not be found. Please '\
      'install it.'
    e
    e '  The class CutMultimedia, part of the MultimediaParadise namespace,'
    e '  currently requires that ffmpeg is installed.'
    e
    e '  The following paths were checked for the availability of ffmpeg:'
    e
    _.each {|this_path|
      e "    #{sfancy(this_path)}"
    }
    # exit_properly
  end
  return is_ffmpeg_installed
end

#check_whether_the_commandline_arguments_contain_a_file_and_assign_this_as_the_main_file(i = commandline_arguments? ) ⇒ Object

#

check_whether_the_commandline_arguments_contain_a_file_and_assign_this_as_the_main_file

#


1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1709

def check_whether_the_commandline_arguments_contain_a_file_and_assign_this_as_the_main_file(
    i = commandline_arguments?
  )
  if i.is_a? Array
    i.each {|entry| check_whether_the_commandline_arguments_contain_a_file_and_assign_this_as_the_main_file(entry) }
  else
    if i and File.exist?(i)
      # =================================================================== #
      # Designate this as the new file to work with, on startup of 
      # this class.
      # =================================================================== #
      set_work_on_this_file(i)
    end
  end
end

#chop_into_segments_of_n_seconds_size(n_seconds = 60) ⇒ Object

#

chop_into_segments_of_n_seconds_size

Use this method if you wish to chop the input into different sizes, based on seconds.

Invocation example:

chop 300
#


1338
1339
1340
1341
1342
1343
1344
1345
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1338

def chop_into_segments_of_n_seconds_size(n_seconds = 60) # 60 seconds by default.
  n_seconds = n_seconds.first.to_f if n_seconds.is_a? Array
  e "Now chopping up into segments of `#{sfancy(n_seconds.to_s)}"\
    "` seconds duration."
  ::MultimediaParadise.chop_into_segments_of_n_seconds_size(
    main_file?, n_seconds
  )
end

#chop_off(i = 1) ⇒ Object

#

chop_off

Use this method if you want to chop off some seconds from a song, for instance, to get rid of the last 3 seconds of a song.

The argument passed will be assumed to be the number of seconds that you wish to chop off from an audio file - starting from the end.

So, chop_off(3) simply means to chop off the last 3 seconds.

Usage example:

chop off 3 seconds
chop_off 3
#


1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1291

def chop_off(i = 1)
  if i.is_a? Array
    i << 1 if i.empty?
    i = i.join(' ') 
  end
  i = i.to_s.strip.to_f # We need to strip the input here. And use a Float.
  # ======================================================================= #
  # Deduct the input from the end position. We either use the
  # duration, or the last entry.
  # ======================================================================= #
  if duration?
    if end_position? and end_position?.empty?
      the_end_position = duration?.to_f - i
    else # else it is not empty
      last_position = end_positions?.pop.to_f
      the_end_position = last_position - i
    end
    if no_start_point_was_defined_yet?
      set_start(0, :be_silent) # Only set a start point if we do not have defined one yet.
    end
    set_end(the_end_position, :be_silent)
    e "We will chop off the last #{simp(i.to_s)} seconds."
    notify_user_that_he_could_commit_now
  else
    e 'No duration was set. Can not chop off anything.'
  end
end

#chop_off_the_first_n_minutes(n_minutes = 5) ⇒ Object

#

chop_off_the_first_n_minutes

This method can be used to chop away the first n minutes of an audio track. This may be useful if you have some audio-recording of a lecture, and you already know the beginning part, so you quickly chop it away.

Invocation examples:

 7min
13min
#


1218
1219
1220
1221
1222
1223
1224
1225
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1218

def chop_off_the_first_n_minutes(
    n_minutes = 5
  )
  n_seconds = n_minutes.to_f * 60
  set_start_point(n_seconds)
  set_end_point(:to_the_end)
  do_cut_the_multimedia_file
end

#clear_setpointsObject

#

clear_setpoints

This method will clear all setpoints, both the beginning and the end array.

#


1062
1063
1064
1065
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1062

def clear_setpoints
  @array_all_start_positions = []
  @array_all_end_positions   = []
end

#create_a_log_file?Boolean Also known as: create_log_file?

#

create_a_log_file?

#

Returns:

  • (Boolean)


900
901
902
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 900

def create_a_log_file?
  @create_a_log_file
end

#define_end_point(i, be_verbose = true) ⇒ Object Also known as: set_end, set_end_at, set_end_point, set_end_position

#

define_end_point

This method can be used to set the end point of an audio file, as to where we will stop to cut. For example, an end point of “5” is assumed to mean a cut point at 5 seconds.

set_end() is an alias to this method.

#


1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1819

def define_end_point(
    i, be_verbose = true
  )
  be_verbose = false if be_verbose == :be_silent
  i = i.first if i.is_a? Array
  if i.is_a? Symbol
    case i
    when :end_of_the_file,
         :to_the_end
      i = length_of_audio_file?
    end
  end
  i = i.to_s.strip # We require a String past this point here.
  i[0,3] = '' if i.start_with? 'end'
  i[0,1] = '' if i.start_with? 'e'
  i = sanitize(i)
  if i.empty?
    e "#{rev}Won't append empty end points."
  elsif i.include? '%' # User requested percentage-based manipulation.
    i = ((duration? * (i.delete('%').to_i)) / 100)
    define_end_point(i) # Recursive call again.
  else
    # ===================================================================== #
    # Convert into seconds if it includes a ':'.
    # ===================================================================== #
    if i.include?(':') and Object.const_defined?(:HoursToSeconds)
      i = HoursToSeconds[i, :be_quiet]
    end
    # ===================================================================== #
    # Until 19.04.2019 we had the following code to detect a logic error,
    # but it was then realized that not all numbers constitute a logic
    # error, so this was removed again.
    #
    # if i.to_f < starting_position?.to_f 
    #   e 'This input ('+sfancy(i.to_s)+') must be invalid because '\
    #        'it is'
    #   e 'smaller than the starting position.'
    #   return
    # end
    # ===================================================================== #
    # ===================================================================== #
    # === Check for too long size given
    #
    # The following code has been added at 31.08.2019. If i is larger
    # than the length of the audio file then we will notify the user
    # about it, then set it to the maximum length instead.
    #
    # This, however had, only makes sense if the length is larger
    # than 0, hence the double-check below.
    # ===================================================================== #
    length_of_audio_file = length_of_audio_file?.to_f
    if (length_of_audio_file.to_f > 0) and (i.to_f > length_of_audio_file.to_f)
      e "#{rev}Note that #{sfancy(i)} #{rev}is larger than the length of "\
        "the audio file."
      e "#{rev}This is of little practical use, so the input here been reset"
      e "#{rev}to the #{steelblue('maximum length')} #{rev}instead "\
        "(#{seagreen(length_of_audio_file)} #{rev}seconds)."
      i = length_of_audio_file.to_f
    end
    end_positions? << i.to_f # Append the end point as a float-value here.
    if be_verbose
      twentyfour_notation = forestgreen(to_twentyfour_notation(i).to_f.to_s)
      e "#{rev}Setting an end point at: #{simp(i)} "\
        "#{rev}[#{twentyfour_notation}#{rev}]"
      feedback_all_end_points
    end
  end
end

#define_start_point(i, be_verbose = true) ⇒ Object Also known as: set_start, set_start_at, set_start_point, determine_start_position, set_start_position

#

define_start_point (set_start tag)

This method will define a start position, at which we will start to cut an audio file.

set_start is an alias to this method.

#


1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1774

def define_start_point(
    i,
    be_verbose = true
  )
  case be_verbose
  when :be_silent
    be_verbose = false
  end
  i = i.first if i.is_a? Array
  i = i.to_s.strip
  i[0,5] = '' if i.start_with? 'start'
  i[0,1] = '' if i.start_with? 's'
  i = sanitize(i)
  if i.empty?
    e "#{rev}Won't append empty start points."
  elsif i.include? '%' # User requested percentage-based manipulation here.
    i = ((duration? * (i.delete('%').to_i)) / 100)
    define_start_point(i) # Call itself again.
  else
    # ===================================================================== #
    # Simply append to our main Array.
    # ===================================================================== #
    @array_all_start_positions << i.to_f # Store as float.
    if be_verbose
      twentyfour_notation = forestgreen(to_twentyfour_notation(i))
      e "#{rev}Setting a start point at: #{simp(i)} "\
        "#{rev}[#{twentyfour_notation}]"
      feedback_all_start_points
    end
  end
end

#delete_individual_audio_filesObject

#

delete_individual_audio_files

This will delete

#


1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1122

def delete_individual_audio_files
  _ = output_file?
  if _.empty?
    opne 'Nothing to delete.'
  else
    _ = _.join(', ') if _.is_a? Array
    if File.exist? _
      opne "Next deleting the file `#{sfile(_)}`."
      delete(_)
    else
      opnn; no_file_exists_at(_)
    end
  end
end

#delete_the_original_file(i = work_on_which_file? ) ⇒ Object

#

delete_the_original_file

This method will remove the original file.

#


1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1244

def delete_the_original_file(
    i = work_on_which_file?
  )
  unless i
    opnn; no_file_exists
    return
  end
  _ = File.basename(i) if i
  if i and File.exist?(_)
    opne 'Now deleting the original file at '+sfile(_)+'.'
    remove_file(_)
  else
    opnn; no_file_exists_at(_)
  end
end

#determine_the_duration(i = main_file? ) ⇒ Object Also known as: determine_duration

#

determine_the_duration

Set @duration here.

#


428
429
430
431
432
433
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 428

def determine_the_duration(
    i = main_file?
  ) # This will determine the ivar @duration.
  @duration = MultimediaParadise::FileDuration.new(i) { :be_quiet } # Also get the duration of the file here.
  return @duration.duration? # This should return the duration in question, as a Float.
end

#determine_the_output_file(i = input_file? ) ⇒ Object

#

determine_the_output_file

This method will determine the output file based on the input file.

#


1679
1680
1681
1682
1683
1684
1685
1686
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1679

def determine_the_output_file(
    i = input_file?
  )
  i = File.basename(i).dup
  i.prepend('OUTPUT_FILE_') unless i.start_with?('OUTPUT_FILE_')
  i = File.absolute_path(i)
  set_output_file(i)
end

#display_the_prompt_in_use_to_the_userObject

#

display_the_prompt_in_use_to_the_user

#


405
406
407
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 405

def display_the_prompt_in_use_to_the_user
  print PROMPT_TO_USE
end

#do_cut_the_multimedia_fileObject Also known as: do_cut

#

do_cut_the_multimedia_file

#


1894
1895
1896
1897
1898
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1894

def do_cut_the_multimedia_file
  start_cutting
  report_that_we_are_finished_now
  return absolute_path_of_the_output_file?
end

#do_general_exit_actionsObject

#

do_general_exit_actions (exit tag)

#


596
597
598
599
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 596

def do_general_exit_actions
  try_to_rename_kde_konsole_tab('_')
  :exit
end

#do_reset_all_values_to_their_default_valuesObject

#

do_reset_all_values_to_their_default_values

#


1086
1087
1088
1089
1090
1091
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1086

def do_reset_all_values_to_their_default_values
  opne 'Resetting all values to their defaults again.'
  _ = file? # Obtain a reference to the old file.
  reset # Then reset it.
  set_file(_)
end

#do_the_cutting(optional_input = nil) ⇒ Object Also known as: cut, start_cutting

#

do_the_cutting

This will cut our audio file.

#


1913
1914
1915
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1913

def do_the_cutting(optional_input = nil)
  build_ffmpeg_command
end

#do_use_mplayerObject

#

do_use_mplayer

#


1078
1079
1080
1081
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1078

def do_use_mplayer
  e 'We will try to use mplayer.'
  MultimediaParadise.set_use_this_multimedia_player(:mplayer)
end

#do_use_mpvObject

#

do_use_mpv

#


1070
1071
1072
1073
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1070

def do_use_mpv
  e 'We will try to use mpv.'
  MultimediaParadise.set_use_this_multimedia_player(:mpv)
end

#duration?Boolean

#

duration?

#

Returns:

  • (Boolean)


907
908
909
910
911
912
913
914
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 907

def duration?
  if @work_on_this_file
    @duration.n_seconds?
  else
    report_no_file_is_assigned
    0 # 0 seconds in this case.
  end
end

#editor?Boolean

#

editor?

#

Returns:

  • (Boolean)


460
461
462
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 460

def editor?
  ::MultimediaParadise::YOUR_EDITOR
end

#emphasis(i) ⇒ Object

#

emphasis

Internal emphasis.

#


329
330
331
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 329

def emphasis(i)
  orange(i)
end

#end?Boolean

#

end?

Only return the very last entry here, from all stored end positions.

#

Returns:

  • (Boolean)


479
480
481
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 479

def end?
  all_end_positions?.last
end

#end_point_was_defined_yet?Boolean

#

end_point_was_defined_yet?

#

Returns:

  • (Boolean)


500
501
502
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 500

def end_point_was_defined_yet?
  !all_end_positions?.empty?
end

#end_position=(i = 1000) ⇒ Object Also known as: set_length

#

end_position= (end tag)

Usage example:

self.end_position = 5
#


1109
1110
1111
1112
1113
1114
1115
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1109

def end_position=(i = 1000)
  case i
  when :end # special instruction then
    i = duration?.to_f
  end
  all_end_positions?[0,0] = i.to_i
end

#ensure_that_array_cut_end_is_valid(i = duration?) ) ⇒ Object

#

ensure_that_array_cut_end_is_valid

The end positions should always be valid.

#


338
339
340
341
342
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 338

def ensure_that_array_cut_end_is_valid(i = duration?)
  if end_positions?.empty? # We must ensure that it has the length.
    set_length(i)
  end
end

#ensure_that_there_is_at_least_one_end_positionObject

#

ensure_that_there_is_at_least_one_end_position

This method will make sure that the end-array has at least one entry.

#


1665
1666
1667
1668
1669
1670
1671
1672
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1665

def ensure_that_there_is_at_least_one_end_position
  if end_positions?.empty?
    e "#{rev}Note that there is no end position designated yet for "\
      "this file. We will thus set"
    e 'one to the end position of the audio file.'
    set_end :end_of_the_file
  end
end

#enter_the_main_loopObject

#

enter_the_main_loop

The main loop is only to be entered if we are in interactive mode. The GUI in ruby-gtk3 will handle a loop on its own.

#


1420
1421
1422
1423
1424
1425
1426
1427
1428
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1420

def enter_the_main_loop
  loop {
    display_the_prompt_in_use_to_the_user
    obtain_user_input
    append_the_user_input_onto_the_history
    interactive_menu # Feed the input in the interactive menu here.
    break if @may_we_exit
  }
end

#esystem(i) ⇒ Object

#

esystem

#


945
946
947
948
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 945

def esystem(i)
  e "  #{teal(i)}"
  system(i) if @we_are_allowed_to_run_system_command
end

#exit_properlyObject

#

exit_properly

#


1701
1702
1703
1704
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1701

def exit_properly
  do_general_exit_actions
  exit # unless is_interactive?
end

#feedback_all_end_points(i = all_end_positions? ) ⇒ Object

#

feedback_all_end_points

#


356
357
358
359
360
361
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 356

def feedback_all_end_points(
    i = all_end_positions?
  )
  e "#{rev}Feedbacking all #{emphasis('end-points')} #{rev}next."
  pp i
end

#feedback_all_start_points(i = start_positions? ) ⇒ Object

#

feedback_all_start_points

#


1759
1760
1761
1762
1763
1764
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1759

def feedback_all_start_points(
    i = start_positions?
  )
  e "#{rev}Feedbacking all #{emphasis('start-points')} #{rev}next."
  pp i
end

#feedback_start_cutting_atObject

#

feedback_start_cutting_at

#


574
575
576
577
578
579
580
581
582
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 574

def feedback_start_cutting_at
  here = all_start_positions?
  if here.empty?
    e 'No start positions have been determined yet.'
  else
    e 'We will start cutting at '+
      simp(here.first.to_s)+' seconds.'
  end
end

#green_colourObject

#

green_colour

#


604
605
606
607
608
609
610
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 604

def green_colour
  if use_colours?
    ::Colours::CGREEN
  else
    ''.dup
  end
end

#in_commandline_mode?Boolean

#

in_commandline_mode?

#

Returns:

  • (Boolean)


281
282
283
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 281

def in_commandline_mode?
  @usage_mode == :interactive
end

#initialize_twentyfour_hours_notation_objectObject

#

initialize_twentyfour_hours_notation_object

#


1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1547

def initialize_twentyfour_hours_notation_object
  begin
    require 'roebe/classes/twentyfour_hours_notation.rb'
  rescue LoadError; end
  if Object.const_defined?(:Roebe) and Roebe.const_defined?(:TwentyfourHoursNotation)
    @t = Roebe::TwentyfourHoursNotation.new # bl $RUBY_TIME/twentyfour_hours_notation.rb
  else
    e 'The twentyfour_hours_notation class, part of the roebe gem, '\
      'appears to be unavailable.'
    e
    e 'Please consider installing it, such as via:'
    e
    e '  gem install roebe'
    e
  end
end

#interactive_menu(i = @user_input) ⇒ Object Also known as: imenu

#

interactive_menu

#


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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/interactive_menu.rb', line 16

def interactive_menu(
    i = @user_input
  )
  if i.is_a? Array
    i.each {|entry| interactive_menu(entry) }
  else
    work_on_this_file = @work_on_this_file.to_s
    first_argument = nil
    # ===================================================================== #
    # The last check is to prevent "1.5 - 6.86" from being chopped up.
    # ===================================================================== #
    if i and i.include?(' ') and !i.include?(' - ')
      splitted = i.split(' ')
      first_argument = splitted[1]
      all_arguments  = splitted[1..-1]
      cmd = splitted[0]
    else
      cmd = i
    end
    f = first_argument
    case cmd.to_s # case tag
    # ===================================================================== #
    # === run                                                     (cut tag)
    #
    # This is the main entry point for this class: it will commit towards
    # cutting the multimedia file at hand.
    # ===================================================================== #
    when 'run',
         'cut',
         'start',
         '1',
         /commit/,
         /cu/,
         /^do(_|-)?cut$/i
      do_cut_the_multimedia_file
    # ===================================================================== #
    # === set_start
    # ===================================================================== #
    when /^s ?\d+/,
         /^s(\d+:\d+:\d+.\d)/,
         /^start ?\d+/,
         'set_start' # "s1:32:48.2"
      define_start_point(i)
    # ===================================================================== #
    # === set_end
    # ===================================================================== #
    when /^e(\d{1,2}:?\d{1,2}:\d{1,2})\.?\d?/,
         /^e ?\d+/,
         /^end ?\d+/,
         'set_end' # "e1:32:48.2", see: http://rubular.com/r/NX5xENtGzB
      define_end_point(i)
    # ===================================================================== #
    # === 5.5
    #
    # This will match input such as: "5.5   -678.3".
    #
    # It will set both start and end positions.
    #
    # See the following entry at rubular.com:
    #
    #   https://rubular.com/r/APT8nRFhe6OPHq
    #
    # ===================================================================== #
    when /(\d+\.?\d*)\s*-\s*(\d+\.?\d*)/
      set_start($1)
      set_end($2)
    # ===================================================================== #
    # === Only numbers
    #
    # This entry point exists when the user only inputted numbers.
    #
    # The second regex checks for Floats specifically.
    # ===================================================================== #
    when /^\d+$/,
         /^\d+\.?\d*$/,
         /^\d+,?\d*$/
      user_did_input_only_numbers(i)
    # ===================================================================== #
    # === 06:11.6
    #
    # This entry point allows us to more easily use positions that
    # directly come from mplayer, e. g. "06:11.6" meaning "371.6"
    # seconds. This will be used for the start position of the
    # audio file at hand.
    # ===================================================================== #
    when /(\d{1,2}:\d{1,2}\.\d{0,1})$/ # See: http://rubular.com/r/bQMecScBBd
      determine_start_position($1.to_s.dup)
    # ===================================================================== #
    # === 5min
    # ===================================================================== #
    when /^(\d{0,2})min$/
      chop_off_the_first_n_minutes($1.to_s)
    # ===================================================================== #
    # === 6*60
    #
    # This entry point allows us to quickly calculate results for this.
    # ===================================================================== #
    when /^(\d+)\*(\d+)$/
      result = eval(
        $1.to_s.dup+' * '+$2.to_s.dup
      )
      e "#{i} is: #{sfancy(result)}"
    # ===================================================================== #
    # === end
    # ===================================================================== #
    when 'end',
         /^set(_|-)?end(_|-)?position$/,
         'end_position'
      self.end_position = :end
      e 'Setting end position to '+simp(end?.to_s)+rev+'.'
    # ===================================================================== #
    # === gui
    # ===================================================================== #
    when 'gui',
         /^-?-?gtk3?/i
      start_the_graphical_user_interface
    # ===================================================================== #
    # === file?
    # ===================================================================== #
    when 'file?',
         'audio?',
         'name?'
      e sfile(work_on_which_file?)
    # ===================================================================== #
    # === assign
    # ===================================================================== #
    when 'assign'
      assign(f)
    # ===================================================================== #
    # === split
    # ===================================================================== #
    when 'split',
         /split(-|_)?in(-|_)?half$/,
         /split(_|-)?audio(_|-)?file(_|-)?in(_|-)?half$/i,
         /half(-|_)?chop/,
         /chop(-|_)?in(-|_)?half/,
         'half',
         'halfy'
      split_audio_file_in_half
    # ===================================================================== #
    # === q
    #
    # Ways to exit this application. Only really applicable when in
    # the interactive mode.
    # ===================================================================== #
    when 'q',
         'exit',
         'quit',
         'break',
         'out',
         'stop',
         nil
      @may_we_exit = true
    # ===================================================================== #
    # === ends?
    # ===================================================================== #
    when 'ends?','end?',
         /^feedback_?all_?end_?points$/i
      feedback_all_end_points
    # ===================================================================== #
    # === --last-file
    #
    # Usage example:
    #
    #   caudio --last-file
    #
    # ===================================================================== #
    when /^-?-?last(_|-)?file$/i,
         /^-?-?try(_|-)?to(_|-)?use(_|-)?the(_|-)?last(_|-)?file$/i
      try_to_use_the_last_file
    # ===================================================================== #
    # === chop_into_segments_of_n_seconds_size
    # ===================================================================== #
    when /chop(_|-)?into(_|-)?segments(_|-)?of(_|-)?n(_|-)?seconds(_|-)?size$/,
         'segments'
      chop_into_segments_of_n_seconds_size(f) # Create n seconds segments.
    # ===================================================================== #
    # === intersect
    #
    # Intersect allows us to cut away a "central" segment, aka a segment
    # that is between two other parts that are interesting to us.
    #
    # In other words - via intersect we REMOVE a part of the audio file,
    # and only RETAIN the two parts that are on the left border and
    # on the right border.
    # ===================================================================== #
    when 'intersect',
         /^remove_?middle_?segment/,
         /^chop_?out/,
         /^segment$/i
      intersect(f)
    # ===================================================================== #
    # === internal_setpoints
    # ===================================================================== #
    when /^internal(_|-)?setpoints$/,
         'isetpoints'
      '' # This is obviously unfinished.
    # ===================================================================== #
    # === lchop
    # ===================================================================== #
    when 'lchop', /left_?chop/,'-chop',/left_?chop_?off/
      left_chop_off(all_arguments) # Chop at the "left" side of a .mp3 file.
    # ===================================================================== #
    # === points?
    # ===================================================================== #
    when 'points?','p?',/report_?points/
      report_points
    # ===================================================================== #
    # === size?
    # ===================================================================== #
    when 'size?','duration?','size','duration','length','d?','length?',
         /report_?duration_?of_?multimedia_?file/,
         /file_?length\??/,
         /duration\??/
      report_duration_of_multimedia_file
    # ===================================================================== #
    # === cut_and_overwrite
    # ===================================================================== #
    when /cut_?and_?overwrite/,/cut_?then_?overwrite/,'superwrite',
         'cwrite',
         /cut_?then_?o/,
         'cuto'
      start_cutting
      overwrite_old_file(:be_verbose)
      # =================================================================== #
      # Since we overwrote it, no need for error reporting here.
      # =================================================================== #
      report_that_we_are_finished_now(:no_error_reporting)
    # ===================================================================== #
    # === chop_off
    # ===================================================================== #
    when /^chop(_|-)?off$/,
         'chopo','chopper','chop'
      chop_off(all_arguments)
    # ===================================================================== #
    # === intersect?
    # ===================================================================== #
    when 'intersect?',
         /^show(_|-)?how(_|-)?to(_|-)?use(_|-)?intersect$/i
      show_how_to_use_intersect
    # ===================================================================== #
    # === player?
    # ===================================================================== #
    when 'player?',
         /^report(_|-)?which(_|-)?player(_|-)?we(_|-)?will(_|-)?use$/i
      report_which_player_we_will_use
    # ===================================================================== #
    # === exist
    # ===================================================================== #
    when 'exist?',
         'exist',
         /^report(_|-)?does(_|-)?the(_|-)?main(_|-)?file(_|-)?exist\??$/i
      report_does_the_main_file_exist?
    # ===================================================================== #
    # === files?
    # ===================================================================== #
    when 'files?',
         'files',
         /^show(_|-)?audio(_|-)?files$/i,
         'output?'
      show_audio_files
    # ===================================================================== #
    # === cut_then_exit
    # ===================================================================== #
    when /^cut(_|-)?then(_|-)?exit$/,
         /^cut(_|-)?and(_|-)?exit$/
      start_cutting
      report_that_we_are_finished_now
      we_may_quit
    # ===================================================================== #
    # === feed
    # ===================================================================== #
    when 'feed',
         'feedback',
         'setpoints?',
         'feedback?',
         'feed?',
         'pos?',
         'positions?',
         'data?',
         'dataset?'
      feedback_cutting
    # ===================================================================== #
    # === overwrite
    # ===================================================================== #
    when 'overwrite',
         /re(_|-)?merge/,
         'rename',
         'original',
         'overwrite_old_file'
      overwrite_old_file(:be_verbose)
      do_reset_all_values_to_their_default_values
    # ===================================================================== #
    # === done
    # ===================================================================== #
    when /^done$/i
      modify_the_main_file_by_prepending_the_upcased_string_done_to_it
    # ===================================================================== #
    # === output_files?
    # ===================================================================== #
    when 'output_files?',
         'outputfiles?' # Debugging here.
      p output_file?
    # ===================================================================== #
    # === clear
    # ===================================================================== #
    when 'clear',
         'reset',
         'reset_everything'
      do_reset_all_values_to_their_default_values
    # ===================================================================== #
    # === delete_the_original_file
    #
    # Only use this entry point if you really want to delete the audio
    # file at hand.
    # ===================================================================== #
    when /^delete(_|-)?the(_|-)?original(_|-)?file$/,
         /^delete(_|-)?old(_|-)?file$/,
         /^remove$/,
         /^remove(_|-)?file$/,
         /^delete(_|-)?file$/,
         'delete',
         /^delete(_|-)?the(_|-)?audio(_|-)?file$/
      delete_the_original_file
    # ===================================================================== #
    # === delete_individual_audio_files
    # ===================================================================== #
    when /^delete(_|-)?individual(_|-)?audio(_|-)?files$/i
      delete_individual_audio_files
    # ===================================================================== #
    # === disable
    # ===================================================================== #
    when 'disable'
      @we_are_allowed_to_run_system_command = false
    # ===================================================================== #
    # === merge
    # ===================================================================== #
    when 'merge',
         'join'
      merge_created_files
    # ===================================================================== #
    # === pwd?
    # ===================================================================== #
    when 'pwd?',
         'pwd',
         'PWD',
         /^report(_|-)?pwd$/i
      report_pwd
    # ===================================================================== #
    # === open
    # ===================================================================== #
    when 'open',
         /^open(_|-)?this(_|-)?file(_|-)?in(_|-)?editor$/i
      open_this_file_in_editor
    # ===================================================================== #
    # === history?
    # ===================================================================== #
    when /^history\??/,
         /^show(_|-)?history$/i,
         'hist',
         'h',
         'his?',
         'input?'
      show_history
    # ===================================================================== #
    # === ll
    # ===================================================================== #
    when 'll',
         'ls',
         'l'
      Dir['*'].each {|entry| e entry }
    # ===================================================================== #
    # === report_status
    # ===================================================================== #
    when /^report(_|-)?status$/,
         '?',
         '??',
         'info?',
         'debug?'
      report_status
    # ===================================================================== #
    # === start?
    # ===================================================================== #
    when 'start?'
      feedback_start_cutting_at
    # ===================================================================== #
    # === mpv
    # ===================================================================== #
    when 'mpv',
         /^do(_|-)?use(_|-)?mpv$/i,
         /^use(_|-)?mpv$/i
      do_use_mpv
    # ===================================================================== #
    # === mplayer
    # ===================================================================== #
    when 'mplayer',
         /^do(_|-)?use(_|-)?mplayer$/i,
         /^use(_|-)?mplayer$/i
      do_use_mplayer
    # ===================================================================== #
    # === show_audio_files
    # ===================================================================== #
    when /show_audio_files/,
         'audiofiles?'
      show_audio_files
    # ===================================================================== #
    # === report_half_the_duration
    # ===================================================================== #
    when 'half?',
         'h?',
         '1/2',
         /^report(_|-)?half(_|-)?the(_|-)?duration$/i
      report_half_the_duration
    # ===================================================================== #
    # === USE_THIS_PLAYER
    # ===================================================================== #
    when /USE_THIS_PLAYER/i,
         /report_which_player_we_will_use/
      report_which_player_we_will_use
    # ===================================================================== #
    # === play
    # ===================================================================== #
    when 'play',
         'mplay',
         'pla','pl','2','p',
         'lp',
         /^play(_|-)?the(_|-)?audio(_|-)?file$/,
         'player',
         'lpay',
         'pkl',
         'mpa'
      play_the_audio_file
    # ===================================================================== #
    # === trim
    #
    # This will trim from the left-end, left-hand side, aka from the
    # beginning.
    # ===================================================================== #
    when /^-?-?trim/i,
         /^-?-?left(-|_| )?chop/i,
         /^-?-?lchop/i
      if first_argument
        trim_n_seconds = first_argument
      else
        e 'Trim n seconds from the start:'
        trim_n_seconds = $stdin.gets.chomp
      end
      @output_file = "output_#{File.basename(work_on_this_file)}"
      _ = 'ffmpeg -y -i '+work_on_this_file+' -ss '+trim_n_seconds+' '\
          '-vcodec copy -acodec copy '+
          @output_file
      e
      esystem _
      e
    # ===================================================================== #
    # === help
    # ===================================================================== #
    when /-?-?help$/i,
         'help?',
         'hlep',
         'status',
         'status?',
         'stat',
         'stat?',
         'stats?',
         'chelp',
         /show_?help_?options/
      show_help
    else # else tag
      case i # case tag
      when 's'
        define_start_point(f)
      when 'e'
        define_end_point(f)
      else
        # ================================================================= #
        # Handle input containing at the least one '-' character next:
        # ================================================================= #
        if i.include? '-' # assume we specified start and end position.
          splitted = i.split('-')
          # =============================================================== #
          # Note that since as of October 2023 we may not have any value
          # for the start range.
          # =============================================================== #
          start_position = splitted.first
          if start_position.nil? or start_position.empty?
            start_position = 0
          end
          set_start(start_position)
          set_end(splitted[1])
        elsif i.include? ' '
          splitted = i.split ' '
          f = splitted[1] # first argument.
          case splitted.first
          when 'calculate'
            calculate(f)
          end
        elsif i.empty?
          e # Make a newline in this scase.
        else
          e rev+
            'No action is associated with the given '\
            'input `'+steelblue(i.to_s)+'`.'
        end
      end
    end
  end
end

#intersect(i) ⇒ Object

#

intersect

This method will cut out some middle/central part from a .mp3 file.

Usage example:

intersect 29:23-29:45
intersect 11:20-15:45
#


689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 689

def intersect(i)
  i = i.first if i.is_a? Array
  unless main_file?
    opne 'Please assign a valid, existing file.'
    return
  end
  if i.include? '-' # Ok, then we can split there.
    splitted = i.split '-'
    first, last = *splitted
    # ===================================================================== #
    # Next, we must convert these numbers into seconds, if it includes
    # at least one ':' character.
    # ===================================================================== #
    if first.include? ':'
      first.prepend '00:' if first.count(':') == 1
      first = HoursToSeconds[first, :be_silent].to_s
      last.prepend '00:' if last.count(':') == 1
      last = HoursToSeconds[last, :be_silent].to_s
    end
    # ===================================================================== #
    # === Operate on the leading segment first:
    # ===================================================================== #
    e '(1) We will next chop out the leading segment:'
    clear_setpoints
    set_start(0)
    set_end(first)
    do_cut
    clear_setpoints
    # ===================================================================== #
    # === Operater on the trailing segment next:
    # ===================================================================== #
    e '(2) We will next chop out the trailing segment:'
    set_start(last)
    set_end(return_end_of_file_in_seconds)
    do_cut
    clear_setpoints
  end
  store_here = "MERGED_FILES_#{input_file?}" # Where to store the merged files.
  merge(
    output_files?, store_here
  )
  if File.exist? store_here
    opne "The file should now exist at #{sfile(store_here)}."
    remove(output_files?)
  end
end

#is_interactive?Boolean

#

is_interactive?

#

Returns:

  • (Boolean)


1263
1264
1265
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1263

def is_interactive?
  @usage_mode == :interactive
end

#left_chop_off(i) ⇒ Object

#

left_chop_off

This method will chop off to the left side of an audio file.

#


1352
1353
1354
1355
1356
1357
1358
1359
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1352

def left_chop_off(i)
  i = i.join(' ').to_s.strip if i.is_a? Array
  set_start(i)
  if no_end_point_was_defined_yet?
    set_end(duration?, :be_silent) # Only set a start point if we do not have defined one yet.
  end
  notify_user_that_he_could_commit_now
end

#log_cut_action(start_position, end_position, command_that_was_used, output_file) ⇒ Object

#

log_cut_action

We will only create a log file if @create_log_file is true.

This method requires four arguments.

#


1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1039

def log_cut_action(
    start_position,
    end_position,
    command_that_was_used,
    output_file
  )
  append_what_into(
    'Start position: '+start_position.to_s+N,
     output_file)
  append_what_into(
    'End position:   '+end_position.to_s+N,
     output_file)
  append_what_into(
    'Command that was used:'+N+'  '+command_that_was_used.to_s+N,
     output_file)
end

#merge_created_filesObject

#

merge_created_files (merge tag)

This will merge the various audio files.

#


1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1171

def merge_created_files
  if output_files?.size > 1
    output_file = 'merged_audio_files_'+
                   output_file?.
                   sub(/\.mp3$/,'')+'.mp3'
    e 'Next merging the '+sfancy(output_files?.size.to_s)+
      ' files into '+sfile(output_file)+'.'
    merge_these_files(@array_output_files, output_file)
    if File.exist? output_file
      e; cliner {
        e 'We created a new file at `'+sfile(output_file)+'`.'
        e 'You can input the command "'+simp('mpl')+'" or "'+
          simp('play')+'" to play this new file.'
        set_main_file(output_file)
      }; e
    else
      e 'The file at `'+sfile(output_file)+'` does not exist.'
    end
  else
    e 'You seem to have specified only one file ('+sfile(file?)+').'
    e 'We need at least two files for the merge action though.'
  end
end

#merge_these_files(array = @array_output_files, output_file = nil) ⇒ Object Also known as: merge

#

merge_these_files (merge tag)

#


1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1140

def merge_these_files(
    array       = @array_output_files,
    output_file = nil
  )
  if array.respond_to? :join
    array = array.join('\|')
    output_file = 'GENERIC_OUTPUT_FILE_'+input? if output_file.nil?
    cmd = 'ffmpeg -i concat:'+array+' -acodec copy '+output_file.to_s
    esystem cmd
  else
    e 'The input to the method merge_these_files() was not correct.'
    e 'Its class is: '+sfancy(array.class)
  end
end

#modify_the_main_file_by_prepending_the_upcased_string_done_to_it(from = @work_on_this_file, to = "DONE_#{@work_on_this_file}") ⇒ Object

#

modify_the_main_file_by_prepending_the_upcased_string_done_to_it

The point of this method is to mark an audio file as “done”.

#


300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 300

def modify_the_main_file_by_prepending_the_upcased_string_done_to_it(
    from = @work_on_this_file,
    to   = "DONE_#{@work_on_this_file}"
  )
  if from.include? '/'
    # ===================================================================== #
    # In this case, the above won't work, so we must use another approach.
    # ===================================================================== #
    splitted = from.split('/')
    splitted.last.prepend('DONE_')
    to = splitted.join('/')
  end
  opne "Now renaming #{sfile(from)} to #{sfile(to)}."
  File.rename(from, to)
  set_work_on_this_file(to)
end

#no_end_point_was_defined_yet?Boolean

#

no_end_point_was_defined_yet?

#

Returns:

  • (Boolean)


507
508
509
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 507

def no_end_point_was_defined_yet?
  !end_point_was_defined_yet?
end

#no_start_point_was_defined_yet?Boolean

#

no_start_point_was_defined_yet?

#

Returns:

  • (Boolean)


493
494
495
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 493

def no_start_point_was_defined_yet?
  all_start_positions?.empty?
end

#notify_the_user_that_interactive_mode_is_ready_now(this_file = File.basename(work_on_which_file?.to_s)) ⇒ Object

#

notify_the_user_that_interactive_mode_is_ready_now

#


1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1364

def notify_the_user_that_interactive_mode_is_ready_now(
    this_file = File.basename(work_on_which_file?.to_s)
  )
  # ======================================================================= #
  # Build up the intro-string.
  # ======================================================================= #
  intro = rev+'We are in interactive mode'.dup
  if File.exist? this_file
    intro << ', for the file `'+sfile(this_file)+'`.'
  else
    intro << '. No file has yet been assigned to work on.'+N
    intro << 'Use "assign" to assign to a file to work with.'
  end
  e intro
  e
  e rev+'You can now start to assign start and end positions'
  e rev+'of your file in question. When you are '\
    'done, input '+sfancy('run')
  e rev+'to start the cutting. (Remember: Start positions are '+
    'like '+sfancy('s1')+rev+', end'
  e "#{rev}positions are like #{sfancy('e40')}.)#{N}#{N}"
  e rev+'You can also use some extra commands, like "'+
    simp(:length).to_s+rev+'".'
  e "#{rev}Use \"help\" to display the help menu."
  e "#{N}#{simp('Hint:')} #{rev}You can use #{simp('s11')}"\
    "#{rev} and #{simp('e22')} #{rev}to denote a start time"
  e rev+'      at position '+simp('11').to_s+rev+' seconds and an end '+
    rev+'time at position '+simp('22').to_s+rev+' seconds.'
  e
  e
  e "#{rev}Input your command next or type \"help\" for help."
end

#notify_user_that_he_could_commit_nowObject

#

notify_user_that_he_could_commit_now

#


1322
1323
1324
1325
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1322

def notify_user_that_he_could_commit_now
  e 'You could now "'+sfancy('commit')+
    '" to cut the audio file.'
end

#obtain_user_inputObject

#

obtain_user_input

This method will designate @user_input - in other words it will obtain the user input.

#


415
416
417
418
419
420
421
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 415

def obtain_user_input
  if use_readline?
    @user_input = Readline.readline('', true)
  else
    @user_input = $stdin.gets.chomp
  end
end

#output_file?Boolean Also known as: output_files?

#

output_file?

This refers to the file that will be created.

#

Returns:

  • (Boolean)


1200
1201
1202
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1200

def output_file?
  @output_file
end

#overwrite_old_file(optional_argument_be_verbose = false) ⇒ Object

#

overwrite_old_file

Note that when we overwrite the old file, we must re-assign the main file to that file again.

#


441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 441

def overwrite_old_file(
    optional_argument_be_verbose = false
  )
  old_file = output_file?
  case optional_argument_be_verbose
  when :be_verbose
    optional_argument_be_verbose = true
  end
  if optional_argument_be_verbose
    e "#{rev}Now overwriting the file `#{sfile(old_file)}`."
  end
  new_file = input_file?
  mv(old_file, new_file)
  assign_file(new_file) # Assign the new file again here.
end

#play_the_audio_file(i = file?) ) ⇒ Object

#

play_the_audio_file

#


561
562
563
564
565
566
567
568
569
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 561

def play_the_audio_file(i = file?)
  if i
    e "#{Colours.rev}Now playing the assigned "\
      "file `#{sfile(i.to_s)}`."
    esystem("#{MultimediaParadise.player?} #{i}")
  else
    e 'No file was found.'
  end
end

#register_sigintObject

#

register_sigint

#


587
588
589
590
591
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 587

def register_sigint
  Signal.trap('SIGINT') {
    exit_properly
  }
end

#report_does_the_main_file_exist?Boolean

#

report_does_the_main_file_exist?

Notify us whether the main file exists or whether it does not.

#

Returns:

  • (Boolean)


891
892
893
894
895
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 891

def report_does_the_main_file_exist?
  e 'Does the main file exist? '+sfancy(
      verbose_truth(File.exist?(main_file?.to_s).to_s)
    )
end

#report_duration_of_multimedia_file(this_file = nil) ⇒ Object Also known as: feedback_duration, report_duration_of_this_file, report_length

#

report_duration_of_multimedia_file

This method will report the duration of the multimedia file.

There exists an optional argument called ‘this_file`. If this argument is used, then we will report the duration of that file instead.

feedback_duration is an alias to this method.

#


641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 641

def report_duration_of_multimedia_file(
    this_file = nil
  )
  use_this_file = file? # Default assignment.
  use_this_file = this_file if this_file
  duration      = duration?
  if use_this_file and File.exist?(use_this_file.to_s) # Handle alternative duration.
    duration      = determine_duration(use_this_file) # Calculate the new duration of that file.
    if duration
      long_form = '('+Time.at(duration).utc.strftime('%H:%M:%S').to_s+')'
      e
      e "#{rev}The duration of the file #{sfile(use_this_file)} #{rev}is: "
      e
      e simp("  #{duration} seconds #{long_form}")
      e
    end
  else
    report_no_file_is_assigned
  end
end

#report_half_the_durationObject

#

report_half_the_duration

#


467
468
469
470
471
472
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 467

def report_half_the_duration
  e rev+'Half the duration, in seconds, is:'
  e
  e simp('  '+(duration?/2.0).to_s)
  e
end

#report_no_file_is_assignedObject

#

report_no_file_is_assigned

#


882
883
884
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 882

def report_no_file_is_assigned
  opne 'No file is assigned.'
end

#report_pointsObject

#

report_points

This method can be used to report all start and end positions.

#


795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 795

def report_points
  unless all_start_positions?.empty?
    e simp('Startpoints')+' for cutting:'
    print '  '; pp all_start_positions?
  end
  unless all_end_positions?.empty?
    e simp('Endpoints')+' for cutting:'
    print '  '; pp all_end_positions?
  end
  # ======================================================================= #
  # Next check whether both are empty.
  # ======================================================================= #
  if all_end_positions?.empty? and
     all_start_positions?.empty?
    e 'It seems as if you have not yet determined any boundaries '\
      'as to where to cut at, yet.'
  end
end

#report_statusObject

#

report_status

#


1903
1904
1905
1906
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1903

def report_status
  report_duration_of_multimedia_file
  report_points
end

#report_that_we_are_finished_now(shall_we_report_errors = true) ⇒ Object

#

report_that_we_are_finished_now

This method will notify the user that we have finished cutting our audio files.

#


742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 742

def report_that_we_are_finished_now(
    shall_we_report_errors = true
  )
  case shall_we_report_errors
  when :no_error_reporting
    shall_we_report_errors = false
  end
  e "#{rev}We have finished cutting our audio files now."
  e
  _ = output_file?
  if _.nil?
    e 'No output file was assigned.'
    return
  end
  if _.include?(' ') # Handle ' ' characters.
    if _.start_with? '"' and _.end_with? '"'
      _ = _[1..-2]
    end
  end
  if File.exist?(_) and !File.zero?(_)
    output_files = [output_files?].flatten.compact
    if output_files.size > 1
      e 'The output files should now be available at:'
      output_files.each {|file|
        e "  #{sfile(file)}"
      }
      e 'If you want to merge these above-listed files together, '\
        'input "merge".'
    else # Else just one file.
      # =================================================================== #
      # Report the duration of that new file.
      # =================================================================== #
      report_duration_of_this_file(_)
      e "#{rev}The output file should now be available at:"
      e
      e "  #{sfile(_)}"
      e
    end
  else
    if shall_we_report_errors
      e 'It seems as if something has failed. Please check the '\
        'above output from ffmpeg,'
      e 'it may be that ffmpeg faced a problem such as missing '\
        '.mp3 support.'
    end
  end
end

#report_which_player_we_will_useObject

#

report_which_player_we_will_use

#


874
875
876
877
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 874

def report_which_player_we_will_use
  e "#{rev}We will use `#{sfancy(MultimediaParadise.player?)}` "\
    "to play multimedia files."
end

#resetObject

#

reset (reset tag)

#


200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 200

def reset
  super()
  # ======================================================================= #
  # === @namespace
  # ======================================================================= #
  @namespace = NAMESPACE
  # ======================================================================= #
  # === @toggle
  # ======================================================================= #
  @toggle = false
  # ======================================================================= #
  # === @user_input
  #
  # Set the user input nil on startup.
  # ======================================================================= #
  @user_input = nil
  # ======================================================================= #
  # === @array_input_history
  #
  # Keep the input-history stored in the following Array.
  # ======================================================================= #
  @array_input_history = []
  # ======================================================================= #
  # === @we_are_allowed_to_run_system_command
  # ======================================================================= #
  @we_are_allowed_to_run_system_command = true
  # ======================================================================= #
  # === @work_on_this_file
  #
  # This variable will keep track on which file (audio or video) we
  # will work on for the running instance. It will, once set,
  # contain the path (a String) to the local file.
  # ======================================================================= #
  @work_on_this_file = nil
  # ======================================================================= #
  # === @output_file
  #
  # We keep track of the output file, so that any possible GUI we may
  # use also benefits from this.
  # ======================================================================= #
  @output_file = nil
  # ======================================================================= #
  # === @may_we_exit
  # ======================================================================= #
  @may_we_exit = false
  # ======================================================================= #
  # === @array_all_start_positions
  # ======================================================================= #
  @array_all_start_positions = []
  # ======================================================================= #
  # === @create_a_log_file
  #
  # Next determine whether we will create a log file or whether we
  # will not.
  # ======================================================================= #
  @create_a_log_file = CREATE_A_LOG_FILE
  # ======================================================================= #
  # === @t
  # ======================================================================= #
  @t = nil
  # ======================================================================= #
  # === @usage_mode
  #
  # This variable can have the following modes:
  #
  #   :interactive
  #   :gui
  #
  # ======================================================================= #
  @usage_mode = :interactive
  # ======================================================================= #
  # Re-set the two main Arrays that keep track of start and end positions
  # on the assigned main file.
  # ======================================================================= #
  clear_setpoints
  initialize_twentyfour_hours_notation_object
end

#return_end_of_file_in_secondsObject Also known as: length_of_audio_file, length_of_audio_file?

#

return_end_of_file_in_seconds

Will always return a String.

#


964
965
966
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 964

def return_end_of_file_in_seconds
  duration?.to_s
end

#runObject

#

run (run tag)

#


1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1738

def run
  check_whether_ffmpeg_is_installed # After this point we know that ffmpeg is installed.
  if File.exist? work_on_which_file?.to_s
    feedback_duration
  end
  # ======================================================================= #
  # Check against the usage mode.
  # ======================================================================= #
  case @usage_mode
  when :interactive,
       :default
    run_in_interactive_mode
    exit 0 # Signal normal exit.
  when :gui
    # Do nothing for now in this event.
  end
end

#run_in_interactive_modeObject Also known as: enter_interactive_mode, run_interactively

#

run_in_interactive_mode

#


1728
1729
1730
1731
1732
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1728

def run_in_interactive_mode
  try_to_rename_kde_konsole_tab(work_on_which_file?)
  notify_the_user_that_interactive_mode_is_ready_now
  enter_the_main_loop
end

#sanitize(i) ⇒ Object

#

sanitize

This method will sanitize the input that represents time. We want a number to mean “n seconds”.

#


369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 369

def sanitize(i)
  # ======================================================================= #
  # Simply replace all ',' with '.', in the event the user typed these.
  # ======================================================================= #
  i.tr!(',','.') if i.include? ','
  # ======================================================================= #
  # Since as of Dec 2015 we will also check for the input containing
  # ':' tokens. If so then we assume that the user wants to use
  # the 24 hours notation such as 05:30, which would mean 5 minutes
  # and 30 seconds.
  # ======================================================================= #
  if i.include? ':'
    i[0,1] = '' if i.start_with? 'e' # Chop off leading 'e' parts.
    # ===================================================================== #
    # The following code will also work for .mp3 files that are longer
    # than 59:59 seconds.
    # ===================================================================== #
    splitted = i.split(':') # Split on all ':'
    if splitted.size < 3
      # =================================================================== #
      # Prepend 00 in this case.
      # =================================================================== #
      splitted[0,0] = '00'
    end
    i = splitted.join(':')
    # ===================================================================== #
    # Next, convert it into the amount o seconds.
    # ===================================================================== #
    i = HoursToSeconds[i, :be_quiet]
  end
  return i.to_s # This must always return a String.
end

#set_interactive_mode_then_enter_interactive_modeObject

#

set_interactive_mode_then_enter_interactive_mode

#


1433
1434
1435
1436
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1433

def set_interactive_mode_then_enter_interactive_mode
  @usage_mode = :interactive
  enter_interactive_mode
end

#set_output_file(i) ⇒ Object

#

set_output_file

#


1158
1159
1160
1161
1162
1163
1164
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1158

def set_output_file(i)
  i = i.to_s.dup
  # file_exists = false
  # file_exists = true if File.exist? i # Check whether the file exists.
  i = '"'+i+'"' if i.include? ' '
  @output_file = i
end

#set_start_and_end_position(i) ⇒ Object

#

set_start_and_end_position

This variant combines set_start() with set_end().

#


552
553
554
555
556
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 552

def set_start_and_end_position(i)
  splitted = i.split('-')
  set_start(splitted.first)
  set_end(splitted[1])
end

#set_work_on_this_file(i = :default, also_keep_track_of_which_file_we_will_use = true) ⇒ Object Also known as: set_main_file, set_file, assign_file, assign, assign_this_file

#

set_work_on_this_file

#


1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1567

def set_work_on_this_file(
    i                                         = :default,
    also_keep_track_of_which_file_we_will_use = true
  )
  i = i.first if i.is_a? Array # For now we use only the first entry of an Array.
  case also_keep_track_of_which_file_we_will_use
  when :do_not_keep_track
    also_keep_track_of_which_file_we_will_use = false
  end
  case i
  # ======================================================================= #
  # === --help
  # ======================================================================= #
  when /-?-?help/i
    show_help :then_exit
  # ======================================================================= #
  # === :default
  #
  # This entry point will cover :default as well as nil-values.
  # ======================================================================= #
  when :default,
       nil
    i = DEFAULT_INPUT_FILE
  end
  # ======================================================================= #
  # === Make use of the absolute path, if possible
  # ======================================================================= #
  unless i.include? '/'
    i = File.absolute_path(i)
  end
  if i and File.file?(i)
    @work_on_this_file = i
    # ===================================================================== #
    # Always set the duration upon assigning a new file to work with.
    # ===================================================================== #
    determine_the_duration(i) if File.exist? i
    # ===================================================================== #
    # And also always determine the proper output file.
    # ===================================================================== #
    determine_the_output_file
    if also_keep_track_of_which_file_we_will_use and
       File.exist?(i)
      # =================================================================== #
      # We will also keep track of this file in the local filesystem,
      # if the output directory has been set.
      # =================================================================== #
      _ = ::MultimediaParadise.output_directory?
      unless File.directory? _
        mkdir(_)
      end
      if _ and File.directory?(_)
        into = FILE_LAST_USED
        if is_on_roebe?
          opne 'Keeping track of the main file in'
          opne '`'+sfile(into)+'`.'
        end
        # =================================================================== #
        # We must rescue the YAML.dump operation, as it may fail otherwise
        # sometimes, e. g. via:
        #
        #   invalid byte sequence in US-ASCII (ArgumentError)
        #
        # =================================================================== #
        begin
          what = YAML.dump(@work_on_this_file)
          write_what_into(
            what, into
          )
        rescue ArgumentError => error
          pp error
          pp error.class
        end
      end
    else
      opne 'File '+sfile(i)+' does not exist.'
    end
  end
end

#show_audio_filesObject

#

show_audio_files

#


926
927
928
929
930
931
932
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 926

def show_audio_files
  Dir['*'].each {|entry|
    if is_an_audio_file?(entry)
      e sfile(entry)
    end
  }
end

#show_help(i = main_file?, , shall_we_exit = :do_not_exit) ⇒ Object Also known as: show_usage

#

show_help (help tag, usage tag)

This method will show the help-options for this class.

To invoke this from the commandline, try:

cut_audio --help
#


979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 979

def show_help(
    i             = main_file?,
    shall_we_exit = :do_not_exit
  )
  case shall_we_exit
  when :then_exit
    shall_we_exit = true
  else
    shall_we_exit = false
  end
  report_status if File.exist? i.to_s
  show_invocation_usage
  e "#{N}The available options for the #{sfancy('CutMultimedia class')}"\
    " are:#{green_colour}#{N}#{N}"
  e
  eparse '  trim                            # this will trim from the left-hand '\
         'side of the multimedia-file'
  eparse '                                  # ^^^ also known as left-chop or just lchop'
  eparse '  show_audio_files                # show the local audio files'
  eparse '  report_half_the_duration        # report the half-duration of a song'
  eparse '  report_which_player_we_will_use # report which multimedia-player is in use'
  eparse '  play                            # play the currently active song/video file'
  eparse '  q                               # q for quit, to exit. Or '\
         'just use "exit" or "quit".'
  eparse '  feedback                        # provide some general '\
         'information about this class'
  eparse '  cut                             # do the actual cutting'
  eparse '  disable                         # dont run system '\
         'command (in case you have to debug something)'
  eparse '  duration?                       # show the duration '\
         'of the file in question'
  eparse '  s[number]                       # start to cut at this '\
         'start-position in seconds - example: s5'
  eparse '  e[number]                       # stop to cut at this end-position'
  eparse '  play                            # to use mplayer to '\
         'play that file; p is a shorter alias to it'
  eparse '  merge                           # merge the cutted audio files together'
  eparse '  --last-file                     # re-use the last file that was used '\
         'in a prior run'
  eparse '  open                            # open the file cut_audio.rb in your editor'
  eparse '  overwrite                       # overwrite the old file, with the new file'
  eparse '  points?                         # feedback all start and end points'
  eparse '  split                           # split an audio file into half'
  eparse '  chop                            # to chop off some seconds '\
         'from the .mp3 file'
  eparse '  gui                             # start the ruby-gtk3 '\
         'widget, a graphical user interface'
  e
  e
  cliner
  exit_properly if shall_we_exit
end

#show_history(i = @array_input_history) ⇒ Object

#

show_history

This method will show the input-history used for CutMultimedia.

#


669
670
671
672
673
674
675
676
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 669

def show_history(
    i = @array_input_history
  )
  e; i.each_with_index {|command, index|
    index += 1
    e index.to_s.rjust(3)+' '+sfancy(command)
  }; e
end

#show_how_to_use_intersectObject

#

show_how_to_use_intersect

This method will give the user some hints how to use the intersect part. The intersect part allows us to cut out a middle segment from a .mp3 file.

#


1404
1405
1406
1407
1408
1409
1410
1411
1412
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1404

def show_how_to_use_intersect
  e 'intersect can be used to chop out middle-segments from an '\
    'audio file.'
  e
  e 'The format should be something exactly like this:'
  e
  e simp('  intersect 29:23-29:45')
  e
end

#show_invocation_usageObject

#

show_invocation_usage

#


847
848
849
850
851
852
853
854
855
856
857
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 847

def show_invocation_usage
  if in_commandline_mode?
    cliner
    e 'Usage from the commandline:'
    e
    e '   cut_multimedia name_of_audio_file_goes_here'
    e '   cut_multimedia name_of_video_file_goes_here'
    e
    cliner
  end
end

#show_output_files(i = @array_output_files) ⇒ Object

#

show_output_files

#


529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 529

def show_output_files(
    i = @array_output_files
  )
  unless i.empty?
    e N+'We created these output files:'
    e
  end
  i.each_with_index {|entry, index|
    entry = entry.to_s
    index += 1
    index = ('('+index.to_s + ')').rjust(4)
    if entry.start_with? '"' and entry.end_with? '"'
      entry = entry[1..-2]
    end
    e ' '+index+' '+sfancy(entry)
  }; e
end

#split_audio_file_in_half(i = main_file? ) ⇒ Object

#

split_audio_file_in_half

This method will simply split the audio file in half.

To invoke this method, try this command:

split_audio_file_in_half
#


1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1486

def split_audio_file_in_half(
    i = main_file?
  )
  if File.exist? i
    e 'We will next split the audio file `'+sfile(i)+'` in '\
      'half, thus, into two parts.'
    set_start 0
    set_end   '50%'
    cut # Perform the first cut operation here.
    set_start '50%'
    set_end  '100%'
    cut # Perform the second cut operation there.
    # delete_audio_file # Not sure if we should delete it.
    e 'The audio was split in two equal parts.'
  else
    e 'No file called `'+sfile(i)+'` exists.'
  end
end

#start_point_was_defined_yet?Boolean

#

start_point_was_defined_yet?

#

Returns:

  • (Boolean)


486
487
488
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 486

def start_point_was_defined_yet?
  !all_start_positions?.empty?
end

#start_position=(i) ⇒ Object

#

start_position=

#


320
321
322
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 320

def start_position=(i) # This will always set to the first entry point of our array.
  all_start_positions?[0,0] = i.to_i
end

#start_position?Boolean Also known as: start_position, starting_position?

#

start_position?

This method depends on the method called array_all_start_positions?.

#

Returns:

  • (Boolean)


290
291
292
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 290

def start_position?
  start_positions?.first # For now, always use the first entry.
end

#start_the_graphical_user_interfaceObject

#

start_the_graphical_user_interface

#


1508
1509
1510
1511
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1508

def start_the_graphical_user_interface
  require 'multimedia_paradise/gui/gtk3/cut_multimedia/cut_multimedia.rb'
  ::MultimediaParadise::GUI::Gtk::CutMultimedia.run
end

#try_to_use_the_last_file(i = FILE_LAST_USED) ⇒ Object

#

try_to_use_the_last_file

This method can be used to re-use the last used file from a prior run.

#


618
619
620
621
622
623
624
625
626
627
628
629
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 618

def try_to_use_the_last_file(
    i = FILE_LAST_USED
  )
  if File.exist? i
    set_file(
      YAML.load_file(i).strip,
      :do_not_keep_track # <- So to not save into a local .yml file.
    )
  else
    opnn; no_file_exists_at(i)
  end
end

#user_did_input_only_numbers(i) ⇒ Object

#

user_did_input_only_numbers

Simplified start an end point notation.

#


516
517
518
519
520
521
522
523
524
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 516

def user_did_input_only_numbers(i)
  @toggle = !@toggle # Toggle it here.
  case @toggle
  when true
    set_start(i)
  when false
    set_end(i)
  end
end

#we_may_quitObject

#

we_may_quit

#


1270
1271
1272
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1270

def we_may_quit
  @may_we_exit = true
end

#work_on_this_file?Boolean Also known as: main_file?, work_on_which_file?, file?, input_file?

#

work_on_this_file? (file tag)

#

Returns:

  • (Boolean)


1691
1692
1693
# File 'lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb', line 1691

def work_on_this_file?
  @work_on_this_file
end