multimedia_paradise 1.1.314

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of multimedia_paradise might be problematic. Click here for more details.

Files changed (417) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +2340 -0
  3. data/bin/audio_player +12 -0
  4. data/bin/auto_title +7 -0
  5. data/bin/convert_audio_to_mp4video_with_image +7 -0
  6. data/bin/cut_audio +7 -0
  7. data/bin/cut_multimedia +7 -0
  8. data/bin/extract_audio +7 -0
  9. data/bin/ffmpeg_merge +7 -0
  10. data/bin/file_duration +7 -0
  11. data/bin/gtk_radio +7 -0
  12. data/bin/loop_this_video +7 -0
  13. data/bin/merge_avi_files +7 -0
  14. data/bin/merge_mp3 +7 -0
  15. data/bin/missing_video_files +7 -0
  16. data/bin/movie_searcher +7 -0
  17. data/bin/mp3_to_opus +7 -0
  18. data/bin/mplayer_wrapper +7 -0
  19. data/bin/multimedia_information +11 -0
  20. data/bin/multimedia_paradise +9 -0
  21. data/bin/multimedia_paradise_sinatra +7 -0
  22. data/bin/play_random_simpsons_video +7 -0
  23. data/bin/playlist +7 -0
  24. data/bin/random_video +7 -0
  25. data/bin/remove_audio +9 -0
  26. data/bin/remove_last_second +7 -0
  27. data/bin/remove_subtitles +7 -0
  28. data/bin/tag_mp3_files +7 -0
  29. data/bin/to_aiff +10 -0
  30. data/bin/to_mp4 +7 -0
  31. data/bin/verbose_analyse_this_mp3_file_for_id3_tags +9 -0
  32. data/bin/video_codec +7 -0
  33. data/bin/video_information +8 -0
  34. data/bin/video_player +11 -0
  35. data/bin/video_to_images +7 -0
  36. data/bin/vp9 +9 -0
  37. data/bin/waveform +73 -0
  38. data/doc/CHANGELOG.md +44 -0
  39. data/doc/LINKS.md +6 -0
  40. data/doc/MOTIVATION_FOR_THIS_PROJECT.md +22 -0
  41. data/doc/MergingVideoLectures.md +12 -0
  42. data/doc/README.gen +2300 -0
  43. data/doc/Readme_for_the_cut_audio_component.md +168 -0
  44. data/doc/todo/todo_for_the_GUIs.md +0 -0
  45. data/doc/todo/todo_for_the_multimedia_paradise_project.md +111 -0
  46. data/lib/multimedia_paradise/audio/audio_player/audio_player.rb +83 -0
  47. data/lib/multimedia_paradise/audio/audio_player/constants.rb +136 -0
  48. data/lib/multimedia_paradise/audio/audio_player/menu.rb +164 -0
  49. data/lib/multimedia_paradise/audio/audio_player/misc.rb +718 -0
  50. data/lib/multimedia_paradise/audio/audio_player/reset.rb +77 -0
  51. data/lib/multimedia_paradise/audio/audio_player/tab.rb +35 -0
  52. data/lib/multimedia_paradise/audio/audio_tag_reader/README.md +7 -0
  53. data/lib/multimedia_paradise/audio/audio_tag_reader/audio_tag_reader.rb +503 -0
  54. data/lib/multimedia_paradise/audio/base.rb +67 -0
  55. data/lib/multimedia_paradise/audio/compress.rb +97 -0
  56. data/lib/multimedia_paradise/audio/create_m3u_playlist.rb +245 -0
  57. data/lib/multimedia_paradise/audio/extract_audio/constants.rb +37 -0
  58. data/lib/multimedia_paradise/audio/extract_audio/extract_audio.rb +417 -0
  59. data/lib/multimedia_paradise/audio/file_duration/constants.rb +53 -0
  60. data/lib/multimedia_paradise/audio/file_duration/file_duration.rb +602 -0
  61. data/lib/multimedia_paradise/audio/genres/boogie.rb +35 -0
  62. data/lib/multimedia_paradise/audio/genres/concerts.rb +35 -0
  63. data/lib/multimedia_paradise/audio/genres/constants.rb +53 -0
  64. data/lib/multimedia_paradise/audio/genres/eurodance.rb +35 -0
  65. data/lib/multimedia_paradise/audio/genres/genre.rb +696 -0
  66. data/lib/multimedia_paradise/audio/genres/hip_hop.rb +35 -0
  67. data/lib/multimedia_paradise/audio/genres/italian_songs.rb +35 -0
  68. data/lib/multimedia_paradise/audio/genres/the_1980s.rb +35 -0
  69. data/lib/multimedia_paradise/audio/genres/trance.rb +35 -0
  70. data/lib/multimedia_paradise/audio/lyrics_fetcher.rb +238 -0
  71. data/lib/multimedia_paradise/audio/merge_audio_files.rb +136 -0
  72. data/lib/multimedia_paradise/audio/modify_year_of_audio_file.rb +151 -0
  73. data/lib/multimedia_paradise/audio/n_audio_songs.rb +216 -0
  74. data/lib/multimedia_paradise/audio/play_all_audio_files.rb +122 -0
  75. data/lib/multimedia_paradise/audio/playlist/playlist.rb +1559 -0
  76. data/lib/multimedia_paradise/audio/remove_audio.rb +98 -0
  77. data/lib/multimedia_paradise/audio/remove_last_second.rb +83 -0
  78. data/lib/multimedia_paradise/audio/report_missing_id.rb +139 -0
  79. data/lib/multimedia_paradise/audio/streamripper/constants.rb +51 -0
  80. data/lib/multimedia_paradise/audio/streamripper/streamripper_wrapper.rb +279 -0
  81. data/lib/multimedia_paradise/audio/to_mp3.rb +138 -0
  82. data/lib/multimedia_paradise/audio/to_ogg.rb +104 -0
  83. data/lib/multimedia_paradise/audio/wav_to_mp3.rb +87 -0
  84. data/lib/multimedia_paradise/audio/waveform/class.rb +341 -0
  85. data/lib/multimedia_paradise/audio/waveform/constants.rb +38 -0
  86. data/lib/multimedia_paradise/audio/waveform/log.rb +101 -0
  87. data/lib/multimedia_paradise/autoinclude.rb +3 -0
  88. data/lib/multimedia_paradise/autoinclude_remove_audio.rb +6 -0
  89. data/lib/multimedia_paradise/base/base.rb +34 -0
  90. data/lib/multimedia_paradise/base/colours.rb +354 -0
  91. data/lib/multimedia_paradise/base/commandline_arguments.rb +52 -0
  92. data/lib/multimedia_paradise/base/constants.rb +19 -0
  93. data/lib/multimedia_paradise/base/encoding.rb +31 -0
  94. data/lib/multimedia_paradise/base/misc.rb +618 -0
  95. data/lib/multimedia_paradise/base/namespace.rb +36 -0
  96. data/lib/multimedia_paradise/base/time.rb +25 -0
  97. data/lib/multimedia_paradise/colours/colours.rb +82 -0
  98. data/lib/multimedia_paradise/commandline/menu.rb +498 -0
  99. data/lib/multimedia_paradise/configuration/play_zoomed.yml +1 -0
  100. data/lib/multimedia_paradise/constants/constants.rb +23 -0
  101. data/lib/multimedia_paradise/constants/conversions.rb +62 -0
  102. data/lib/multimedia_paradise/constants/directory_constants.rb +133 -0
  103. data/lib/multimedia_paradise/constants/encodings.rb +26 -0
  104. data/lib/multimedia_paradise/constants/file_constants.rb +171 -0
  105. data/lib/multimedia_paradise/constants/misc.rb +80 -0
  106. data/lib/multimedia_paradise/constants/my_video_directory.rb +30 -0
  107. data/lib/multimedia_paradise/constants/namespace.rb +14 -0
  108. data/lib/multimedia_paradise/constants/newline.rb +14 -0
  109. data/lib/multimedia_paradise/constants/video_filetypes.rb +27 -0
  110. data/lib/multimedia_paradise/constants/web_constants.rb +150 -0
  111. data/lib/multimedia_paradise/conversions/README.md +2 -0
  112. data/lib/multimedia_paradise/conversions/conversions.rb +930 -0
  113. data/lib/multimedia_paradise/css/project.css +15 -0
  114. data/lib/multimedia_paradise/data/asoundrc +12 -0
  115. data/lib/multimedia_paradise/ffmpeg/README.md +2 -0
  116. data/lib/multimedia_paradise/ffmpeg/ffmpeg.rb +620 -0
  117. data/lib/multimedia_paradise/gui/fox/play_from_radio_station.rb +75 -0
  118. data/lib/multimedia_paradise/gui/gosu/video_player/video_player.rb +109 -0
  119. data/lib/multimedia_paradise/gui/gtk2/lyrics/lyrics.rb +33 -0
  120. data/lib/multimedia_paradise/gui/gtk2/multimedia_converter/multimedia_converter.rb +33 -0
  121. data/lib/multimedia_paradise/gui/gtk2/notebook.rb +144 -0
  122. data/lib/multimedia_paradise/gui/gtk2/play_video_from_my_collection/play_video_from_my_collection.rb +43 -0
  123. data/lib/multimedia_paradise/gui/gtk2/simple_play_widget/README.md +12 -0
  124. data/lib/multimedia_paradise/gui/gtk2/simple_play_widget/simple_play_widget.rb +40 -0
  125. data/lib/multimedia_paradise/gui/gtk2/video_collection/video_collection.rb +56 -0
  126. data/lib/multimedia_paradise/gui/gtk2/widget_increase_or_decrease_audio/widget_increase_or_decrease_audio.rb +42 -0
  127. data/lib/multimedia_paradise/gui/gtk2/youtube_downloader/youtube_downloader.rb +32 -0
  128. data/lib/multimedia_paradise/gui/gtk3/change_metadata_widget/README.md +3 -0
  129. data/lib/multimedia_paradise/gui/gtk3/change_metadata_widget/change_metadata_widget.rb +150 -0
  130. data/lib/multimedia_paradise/gui/gtk3/cut_multimedia/cut_multimedia.rb +321 -0
  131. data/lib/multimedia_paradise/gui/gtk3/information_about_a_mp3_file/information_about_a_mp3_file.rb +421 -0
  132. data/lib/multimedia_paradise/gui/gtk3/lyrics/lyrics.rb +33 -0
  133. data/lib/multimedia_paradise/gui/gtk3/multimedia_converter/multimedia_converter.rb +34 -0
  134. data/lib/multimedia_paradise/gui/gtk3/multimedia_notebook/multimedia_notebook.rb +34 -0
  135. data/lib/multimedia_paradise/gui/gtk3/play_video_from_my_collection/play_video_from_my_collection.rb +34 -0
  136. data/lib/multimedia_paradise/gui/gtk3/playlist/playlist.rb +34 -0
  137. data/lib/multimedia_paradise/gui/gtk3/radio/misc.rb +487 -0
  138. data/lib/multimedia_paradise/gui/gtk3/radio/radio.rb +698 -0
  139. data/lib/multimedia_paradise/gui/gtk3/simple_play_widget/simple_play_widget.rb +38 -0
  140. data/lib/multimedia_paradise/gui/gtk3/sound_effect_widget/sound_effect_widget.rb +34 -0
  141. data/lib/multimedia_paradise/gui/gtk3/tag_mp3_files/connect_skeleton.rb +61 -0
  142. data/lib/multimedia_paradise/gui/gtk3/tag_mp3_files/create.rb +405 -0
  143. data/lib/multimedia_paradise/gui/gtk3/tag_mp3_files/misc.rb +1820 -0
  144. data/lib/multimedia_paradise/gui/gtk3/tag_mp3_files/tag_mp3_files.config +6 -0
  145. data/lib/multimedia_paradise/gui/gtk3/tag_mp3_files/tag_mp3_files.rb +66 -0
  146. data/lib/multimedia_paradise/gui/gtk3/video_collection/video_collection.rb +43 -0
  147. data/lib/multimedia_paradise/gui/gtk3/video_editor/video_editor.rb +34 -0
  148. data/lib/multimedia_paradise/gui/gtk3/video_player/video_player.rb +34 -0
  149. data/lib/multimedia_paradise/gui/gtk3/webcam_widget/webcam_widget.rb +425 -0
  150. data/lib/multimedia_paradise/gui/gtk3/widget_increase_or_decrease_audio/widget_increase_or_decrease_audio.rb +36 -0
  151. data/lib/multimedia_paradise/gui/gtk3/youtube_channels/youtube_channels.rb +210 -0
  152. data/lib/multimedia_paradise/gui/gtk3/youtube_downloader/youtube_downloader.rb +32 -0
  153. data/lib/multimedia_paradise/gui/gui_base.rb +92 -0
  154. data/lib/multimedia_paradise/gui/libui/change_metadata_widget/change_metadata_widget.rb +115 -0
  155. data/lib/multimedia_paradise/gui/libui/cut_multimedia/cut_multimedia.rb +119 -0
  156. data/lib/multimedia_paradise/gui/libui/lyrics/lyrics.rb +67 -0
  157. data/lib/multimedia_paradise/gui/libui/simple_play_widget/simple_play_widget.rb +119 -0
  158. data/lib/multimedia_paradise/gui/libui/tag_mp3_files/tag_mp3_files.rb +268 -0
  159. data/lib/multimedia_paradise/gui/libui/video_player/video_player.rb +81 -0
  160. data/lib/multimedia_paradise/gui/libui/widget_increase_or_decrease_audio/widget_increase_or_decrease_audio.rb +126 -0
  161. data/lib/multimedia_paradise/gui/libui/youtube_channels/youtube_channels.rb +116 -0
  162. data/lib/multimedia_paradise/gui/libui/youtube_downloader/youtube_downloader.rb +107 -0
  163. data/lib/multimedia_paradise/gui/shared_code/change_metadata_widget/change_metadata_widget_module.rb +538 -0
  164. data/lib/multimedia_paradise/gui/shared_code/cut_multimedia/cut_multimedia_module.rb +268 -0
  165. data/lib/multimedia_paradise/gui/shared_code/information_about_a_mp3_file/information_about_a_mp3_file_module.rb +120 -0
  166. data/lib/multimedia_paradise/gui/shared_code/lyrics/lyrics_module.rb +141 -0
  167. data/lib/multimedia_paradise/gui/shared_code/multimedia_converter/multimedia_converter_module.rb +478 -0
  168. data/lib/multimedia_paradise/gui/shared_code/multimedia_notebook/multimedia_notebook_module.rb +171 -0
  169. data/lib/multimedia_paradise/gui/shared_code/play_video_from_my_collection/play_video_from_my_collection_module.rb +464 -0
  170. data/lib/multimedia_paradise/gui/shared_code/playlist/playlist_module.rb +151 -0
  171. data/lib/multimedia_paradise/gui/shared_code/simple_play_widget/simple_play_widget_module.rb +257 -0
  172. data/lib/multimedia_paradise/gui/shared_code/sound_effect_widget/sound_effect_widget_module.rb +173 -0
  173. data/lib/multimedia_paradise/gui/shared_code/tag_mp3_files/tag_mp3_files_module.rb +73 -0
  174. data/lib/multimedia_paradise/gui/shared_code/video_editor/video_editor_module.rb +287 -0
  175. data/lib/multimedia_paradise/gui/shared_code/video_player/video_player_module.rb +185 -0
  176. data/lib/multimedia_paradise/gui/shared_code/widget_increase_or_decrease_audio/widget_increase_or_decrease_audio_module.rb +310 -0
  177. data/lib/multimedia_paradise/gui/shared_code/youtube_downloader/youtube_downloader_module.rb +339 -0
  178. data/lib/multimedia_paradise/gui/tk/tk_multimedia_wrapper.rb +60 -0
  179. data/lib/multimedia_paradise/help/help.rb +75 -0
  180. data/lib/multimedia_paradise/images/MULTIMEDIA.jpg +0 -0
  181. data/lib/multimedia_paradise/images/MULTIMEDIA_PARADISE_ID_TAG_GUI_IN_RUBY_GTK3.png +0 -0
  182. data/lib/multimedia_paradise/images/MULTIMEDIA_PARADISE_LOGO.png +0 -0
  183. data/lib/multimedia_paradise/images/UK_flag.png +0 -0
  184. data/lib/multimedia_paradise/images/US_flag.png +0 -0
  185. data/lib/multimedia_paradise/images/austrian_flag.png +0 -0
  186. data/lib/multimedia_paradise/images/french_flag.png +0 -0
  187. data/lib/multimedia_paradise/images/german_flag.png +0 -0
  188. data/lib/multimedia_paradise/images/radio_image.png +0 -0
  189. data/lib/multimedia_paradise/images/trance.png +0 -0
  190. data/lib/multimedia_paradise/java/AudioPlayer.class +0 -0
  191. data/lib/multimedia_paradise/java/AudioPlayer.java +103 -0
  192. data/lib/multimedia_paradise/java/README.md +3 -0
  193. data/lib/multimedia_paradise/misc/long_format_to_milliseconds_converter.rb +182 -0
  194. data/lib/multimedia_paradise/misc/milliseconds_to_long_format_converter.rb +186 -0
  195. data/lib/multimedia_paradise/multimedia/analyse_multimedia_file.rb +180 -0
  196. data/lib/multimedia_paradise/multimedia/avisynth/README.md +4 -0
  197. data/lib/multimedia_paradise/multimedia/avisynth/avisynth_code.avs +471 -0
  198. data/lib/multimedia_paradise/multimedia/base.rb +60 -0
  199. data/lib/multimedia_paradise/multimedia/chord.rb +174 -0
  200. data/lib/multimedia_paradise/multimedia/convert_audio_to_video_with_image.rb +171 -0
  201. data/lib/multimedia_paradise/multimedia/cut_multimedia/10_minutes_chop.rb +29 -0
  202. data/lib/multimedia_paradise/multimedia/cut_multimedia/15_minutes_chop.rb +29 -0
  203. data/lib/multimedia_paradise/multimedia/cut_multimedia/30_minutes_chop.rb +29 -0
  204. data/lib/multimedia_paradise/multimedia/cut_multimedia/5_minutes_chop.rb +29 -0
  205. data/lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb +2017 -0
  206. data/lib/multimedia_paradise/multimedia/cut_multimedia/evaluate_from_this_file.rb +79 -0
  207. data/lib/multimedia_paradise/multimedia/cut_multimedia/interactive_menu.rb +514 -0
  208. data/lib/multimedia_paradise/multimedia/interactive_shell.rb +84 -0
  209. data/lib/multimedia_paradise/multimedia/merge_multimedia.rb +125 -0
  210. data/lib/multimedia_paradise/multimedia/note.rb +500 -0
  211. data/lib/multimedia_paradise/multimedia/play_from_this_list.rb +163 -0
  212. data/lib/multimedia_paradise/multimedia/read_meta_tags.rb +173 -0
  213. data/lib/multimedia_paradise/multimedia/simulate_youtube_playlist.rb +209 -0
  214. data/lib/multimedia_paradise/multimedia/start_length_duration.rb +205 -0
  215. data/lib/multimedia_paradise/multimedia/video_downloader/video_downloader.rb +143 -0
  216. data/lib/multimedia_paradise/project/project.rb +47 -0
  217. data/lib/multimedia_paradise/requires/require_audio_files.rb +74 -0
  218. data/lib/multimedia_paradise/requires/require_cut_multimedia.rb +7 -0
  219. data/lib/multimedia_paradise/requires/require_extract_audio.rb +7 -0
  220. data/lib/multimedia_paradise/requires/require_file_duration.rb +7 -0
  221. data/lib/multimedia_paradise/requires/require_streamripper.rb +7 -0
  222. data/lib/multimedia_paradise/requires/require_the_audio_player.rb +7 -0
  223. data/lib/multimedia_paradise/requires/require_the_multimedia_paradise_project.rb +38 -0
  224. data/lib/multimedia_paradise/requires/require_the_sinatra_components.rb +7 -0
  225. data/lib/multimedia_paradise/requires/require_toplevel_methods_files.rb +25 -0
  226. data/lib/multimedia_paradise/requires/require_video_files.rb +25 -0
  227. data/lib/multimedia_paradise/requires/require_video_player.rb +7 -0
  228. data/lib/multimedia_paradise/sinatra/app.rb +311 -0
  229. data/lib/multimedia_paradise/sinatra/embeddable_interface.rb +379 -0
  230. data/lib/multimedia_paradise/sound_effects/README.md +12 -0
  231. data/lib/multimedia_paradise/sound_effects/cat_meow.mp3 +0 -0
  232. data/lib/multimedia_paradise/sound_effects/channel_opened.mp3 +0 -0
  233. data/lib/multimedia_paradise/sound_effects/phone_ring.mp3 +0 -0
  234. data/lib/multimedia_paradise/statistics/README.md +5 -0
  235. data/lib/multimedia_paradise/statistics/video.rb +84 -0
  236. data/lib/multimedia_paradise/toplevel_cut_audio.rb +16 -0
  237. data/lib/multimedia_paradise/toplevel_methods/analyze_audio_stream.rb +31 -0
  238. data/lib/multimedia_paradise/toplevel_methods/chop_into_segments_of_n_seconds_size.rb +32 -0
  239. data/lib/multimedia_paradise/toplevel_methods/chop_off_first_five_minutes.rb +22 -0
  240. data/lib/multimedia_paradise/toplevel_methods/chop_off_first_n_seconds.rb +92 -0
  241. data/lib/multimedia_paradise/toplevel_methods/chop_off_first_ten_minutes.rb +22 -0
  242. data/lib/multimedia_paradise/toplevel_methods/chop_off_first_two_minutes.rb +24 -0
  243. data/lib/multimedia_paradise/toplevel_methods/codecs.rb +50 -0
  244. data/lib/multimedia_paradise/toplevel_methods/copy_and_merge_this_video_n_times.rb +51 -0
  245. data/lib/multimedia_paradise/toplevel_methods/copy_file.rb +18 -0
  246. data/lib/multimedia_paradise/toplevel_methods/create_video_from_this_audio.rb +65 -0
  247. data/lib/multimedia_paradise/toplevel_methods/cut_from_to.rb +156 -0
  248. data/lib/multimedia_paradise/toplevel_methods/delay_audio.rb +31 -0
  249. data/lib/multimedia_paradise/toplevel_methods/denoise.rb +90 -0
  250. data/lib/multimedia_paradise/toplevel_methods/deshake.rb +43 -0
  251. data/lib/multimedia_paradise/toplevel_methods/e.rb +16 -0
  252. data/lib/multimedia_paradise/toplevel_methods/encode_this_video.rb +49 -0
  253. data/lib/multimedia_paradise/toplevel_methods/ensure_that_the_output_directory_exists.rb +27 -0
  254. data/lib/multimedia_paradise/toplevel_methods/esystem.rb +43 -0
  255. data/lib/multimedia_paradise/toplevel_methods/files_and_directories.rb +90 -0
  256. data/lib/multimedia_paradise/toplevel_methods/flip_and_rotate.rb +58 -0
  257. data/lib/multimedia_paradise/toplevel_methods/increase_volume_of_this_audio_file.rb +61 -0
  258. data/lib/multimedia_paradise/toplevel_methods/is_a_multimedia_file.rb +27 -0
  259. data/lib/multimedia_paradise/toplevel_methods/is_audio_file.rb +27 -0
  260. data/lib/multimedia_paradise/toplevel_methods/is_image_file.rb +31 -0
  261. data/lib/multimedia_paradise/toplevel_methods/is_on_roebe.rb +17 -0
  262. data/lib/multimedia_paradise/toplevel_methods/is_video_file.rb +62 -0
  263. data/lib/multimedia_paradise/toplevel_methods/merge_multimedia_file.rb +327 -0
  264. data/lib/multimedia_paradise/toplevel_methods/merge_these_videos.rb +105 -0
  265. data/lib/multimedia_paradise/toplevel_methods/misc.rb +885 -0
  266. data/lib/multimedia_paradise/toplevel_methods/n_local_videos.rb +56 -0
  267. data/lib/multimedia_paradise/toplevel_methods/opn.rb +24 -0
  268. data/lib/multimedia_paradise/toplevel_methods/output_directory.rb +59 -0
  269. data/lib/multimedia_paradise/toplevel_methods/player_in_use.rb +80 -0
  270. data/lib/multimedia_paradise/toplevel_methods/query_the_audio_codec_of_this_file.rb +24 -0
  271. data/lib/multimedia_paradise/toplevel_methods/radio.rb +360 -0
  272. data/lib/multimedia_paradise/toplevel_methods/rds.rb +24 -0
  273. data/lib/multimedia_paradise/toplevel_methods/return_all_video_files.rb +64 -0
  274. data/lib/multimedia_paradise/toplevel_methods/return_data_from_video_collection_file_for_this_entry.rb +38 -0
  275. data/lib/multimedia_paradise/toplevel_methods/return_duration_of_this_multimedia_file.rb +27 -0
  276. data/lib/multimedia_paradise/toplevel_methods/return_full_name_for_video_at_this_position.rb +54 -0
  277. data/lib/multimedia_paradise/toplevel_methods/return_path_to_random_simpsons_video_file.rb +43 -0
  278. data/lib/multimedia_paradise/toplevel_methods/return_random_video_file_from_the_video_collection.rb +73 -0
  279. data/lib/multimedia_paradise/toplevel_methods/return_screen_resolution.rb +24 -0
  280. data/lib/multimedia_paradise/toplevel_methods/run_sys_command.rb +30 -0
  281. data/lib/multimedia_paradise/toplevel_methods/scale_video.rb +27 -0
  282. data/lib/multimedia_paradise/toplevel_methods/set_title_of.rb +65 -0
  283. data/lib/multimedia_paradise/toplevel_methods/slow_down_this_video_file.rb +33 -0
  284. data/lib/multimedia_paradise/toplevel_methods/start_screencast.rb +70 -0
  285. data/lib/multimedia_paradise/toplevel_methods/subtitles.rb +59 -0
  286. data/lib/multimedia_paradise/toplevel_methods/to_flac.rb +30 -0
  287. data/lib/multimedia_paradise/toplevel_methods/to_mp4.rb +24 -0
  288. data/lib/multimedia_paradise/toplevel_methods/total_duration.rb +35 -0
  289. data/lib/multimedia_paradise/toplevel_methods/use_lame_codec.rb +32 -0
  290. data/lib/multimedia_paradise/toplevel_methods/video_dataset.rb +76 -0
  291. data/lib/multimedia_paradise/version/version.rb +28 -0
  292. data/lib/multimedia_paradise/video/all_videos.rb +101 -0
  293. data/lib/multimedia_paradise/video/capture_screen.rb +285 -0
  294. data/lib/multimedia_paradise/video/check_numbers.rb +215 -0
  295. data/lib/multimedia_paradise/video/columbo/columbo.rb +139 -0
  296. data/lib/multimedia_paradise/video/copy_missing_video_files.rb +293 -0
  297. data/lib/multimedia_paradise/video/copy_random_video.rb +98 -0
  298. data/lib/multimedia_paradise/video/correct_video_numbers.rb +278 -0
  299. data/lib/multimedia_paradise/video/create_dvd.rb +50 -0
  300. data/lib/multimedia_paradise/video/encode_video.rb +81 -0
  301. data/lib/multimedia_paradise/video/ffmpeg_options.rb +156 -0
  302. data/lib/multimedia_paradise/video/find_video/constants.rb +23 -0
  303. data/lib/multimedia_paradise/video/find_video/find_video.rb +493 -0
  304. data/lib/multimedia_paradise/video/fix_married_with_children_videos.rb +70 -0
  305. data/lib/multimedia_paradise/video/guess_video_name.rb +189 -0
  306. data/lib/multimedia_paradise/video/imdb_rating/imdb_rating.rb +141 -0
  307. data/lib/multimedia_paradise/video/mike_hammer/mike_hammer.rb +74 -0
  308. data/lib/multimedia_paradise/video/missing_video_files/missing_video_files.rb +286 -0
  309. data/lib/multimedia_paradise/video/movie_searcher.rb +281 -0
  310. data/lib/multimedia_paradise/video/mplayer_wrapper.rb +504 -0
  311. data/lib/multimedia_paradise/video/play_random_file.rb +91 -0
  312. data/lib/multimedia_paradise/video/play_random_realvideo.rb +87 -0
  313. data/lib/multimedia_paradise/video/prepare_video_lecture.rb +272 -0
  314. data/lib/multimedia_paradise/video/random_video.rb +310 -0
  315. data/lib/multimedia_paradise/video/registered_video_file.rb +131 -0
  316. data/lib/multimedia_paradise/video/remove_metadata.rb +52 -0
  317. data/lib/multimedia_paradise/video/rename_video_file.rb +149 -0
  318. data/lib/multimedia_paradise/video/report_local_videos.rb +106 -0
  319. data/lib/multimedia_paradise/video/report_missing_videos_in_the_yaml_file.rb +107 -0
  320. data/lib/multimedia_paradise/video/resolution.rb +159 -0
  321. data/lib/multimedia_paradise/video/simpsons.rb +129 -0
  322. data/lib/multimedia_paradise/video/speed_up_video.rb +135 -0
  323. data/lib/multimedia_paradise/video/split_this_video.rb +126 -0
  324. data/lib/multimedia_paradise/video/srt_regex.rb +211 -0
  325. data/lib/multimedia_paradise/video/store_available_video_files.rb +138 -0
  326. data/lib/multimedia_paradise/video/the_simpsons/README.md +9 -0
  327. data/lib/multimedia_paradise/video/the_simpsons/good_the_simpsons_episodes.rb +107 -0
  328. data/lib/multimedia_paradise/video/the_simpsons/the_simpsons.rb +82 -0
  329. data/lib/multimedia_paradise/video/video.rb +14 -0
  330. data/lib/multimedia_paradise/video/video_encoding_settings.rb +57 -0
  331. data/lib/multimedia_paradise/video/video_genres.rb +337 -0
  332. data/lib/multimedia_paradise/video/video_information.rb +443 -0
  333. data/lib/multimedia_paradise/video/video_metadata.rb +132 -0
  334. data/lib/multimedia_paradise/video/video_player.rb +581 -0
  335. data/lib/multimedia_paradise/video/video_renamer.rb +160 -0
  336. data/lib/multimedia_paradise/video/watermark.rb +290 -0
  337. data/lib/multimedia_paradise/video/youtube/youtube.rb +17 -0
  338. data/lib/multimedia_paradise/video/youtube_embedder.rb +235 -0
  339. data/lib/multimedia_paradise/www/GIS/GIS.cgi +147 -0
  340. data/lib/multimedia_paradise/www/HDMI/HDMI.cgi +34 -0
  341. data/lib/multimedia_paradise/www/TALES_FROM_THE_CRYPT.html +71 -0
  342. data/lib/multimedia_paradise/www/alsa/alsa.cgi +7 -0
  343. data/lib/multimedia_paradise/www/alsa/alsa.rb +309 -0
  344. data/lib/multimedia_paradise/www/alsa/alsa.sinatra +56 -0
  345. data/lib/multimedia_paradise/www/audacity.cgi +30 -0
  346. data/lib/multimedia_paradise/www/audio/audio.cgi +9 -0
  347. data/lib/multimedia_paradise/www/audio/audio.rb +2739 -0
  348. data/lib/multimedia_paradise/www/audio/audio.sinatra +56 -0
  349. data/lib/multimedia_paradise/www/avisynth/avisynth.cgi +172 -0
  350. data/lib/multimedia_paradise/www/best_voices/best_voices.cgi +60 -0
  351. data/lib/multimedia_paradise/www/cassette/cassette.cgi +723 -0
  352. data/lib/multimedia_paradise/www/codecs/codecs.cgi +95 -0
  353. data/lib/multimedia_paradise/www/componists/vivaldi.cgi +218 -0
  354. data/lib/multimedia_paradise/www/decibel.cgi +79 -0
  355. data/lib/multimedia_paradise/www/ffmpeg/ffmpeg.cgi +439 -0
  356. data/lib/multimedia_paradise/www/lame/lame.cgi +7 -0
  357. data/lib/multimedia_paradise/www/lame/lame.rb +101 -0
  358. data/lib/multimedia_paradise/www/lame/lame.sinatra +56 -0
  359. data/lib/multimedia_paradise/www/lilypond.cgi +96 -0
  360. data/lib/multimedia_paradise/www/lyrics/lyrics.cgi +49 -0
  361. data/lib/multimedia_paradise/www/midi/al_adagi.mid +0 -0
  362. data/lib/multimedia_paradise/www/play_songs.cgi +102 -0
  363. data/lib/multimedia_paradise/www/play_this_video_file.cgi +100 -0
  364. data/lib/multimedia_paradise/www/pulseaudio/pulseaudio.cgi +7 -0
  365. data/lib/multimedia_paradise/www/pulseaudio/pulseaudio.rb +168 -0
  366. data/lib/multimedia_paradise/www/pulseaudio/pulseaudio.sinatra +56 -0
  367. data/lib/multimedia_paradise/www/rhythmbox/rhythmbox.cgi +120 -0
  368. data/lib/multimedia_paradise/www/sound_theory.cgi +163 -0
  369. data/lib/multimedia_paradise/www/tv/tv.cgi +182 -0
  370. data/lib/multimedia_paradise/www/video/video.cgi +7 -0
  371. data/lib/multimedia_paradise/www/video/video.rb +7709 -0
  372. data/lib/multimedia_paradise/www/video/video.sinatra +52 -0
  373. data/lib/multimedia_paradise/www/web_streams.cgi +58 -0
  374. data/lib/multimedia_paradise/yaml/audio_formats.yml +14 -0
  375. data/lib/multimedia_paradise/yaml/best_songs_in_an_era/eurodance/top20.yml +28 -0
  376. data/lib/multimedia_paradise/yaml/game_shows/ruck_zuck/ruck_zuck.yml +25 -0
  377. data/lib/multimedia_paradise/yaml/genres/1980s.yml +198 -0
  378. data/lib/multimedia_paradise/yaml/genres/README.md +5 -0
  379. data/lib/multimedia_paradise/yaml/genres/boogie.yml +68 -0
  380. data/lib/multimedia_paradise/yaml/genres/concerts.yml +29 -0
  381. data/lib/multimedia_paradise/yaml/genres/eurodance.yml +456 -0
  382. data/lib/multimedia_paradise/yaml/genres/hip_hop.yml +49 -0
  383. data/lib/multimedia_paradise/yaml/genres/italian_songs.yml +53 -0
  384. data/lib/multimedia_paradise/yaml/genres/trance.yml +167 -0
  385. data/lib/multimedia_paradise/yaml/good_horror_movies/good_horror_movies.yml +12 -0
  386. data/lib/multimedia_paradise/yaml/good_movie_actors/good_movie_actors.yml +6 -0
  387. data/lib/multimedia_paradise/yaml/image_formats.yml +8 -0
  388. data/lib/multimedia_paradise/yaml/internal/README.md +2 -0
  389. data/lib/multimedia_paradise/yaml/internal/installed_binaries.yml +31 -0
  390. data/lib/multimedia_paradise/yaml/lyrics.yml +6275 -0
  391. data/lib/multimedia_paradise/yaml/movie_reviews/the_hateful_eight_september_2016.md +305 -0
  392. data/lib/multimedia_paradise/yaml/music_genres.yml +51 -0
  393. data/lib/multimedia_paradise/yaml/playlist.yml +127 -0
  394. data/lib/multimedia_paradise/yaml/radio/README.md +5 -0
  395. data/lib/multimedia_paradise/yaml/radio/radio_stations.yml +359 -0
  396. data/lib/multimedia_paradise/yaml/song_tags.yml +815 -0
  397. data/lib/multimedia_paradise/yaml/tales_from_the_crypt/tales_from_the_crypt.yml +418 -0
  398. data/lib/multimedia_paradise/yaml/tom_and_jerry/README.md +2 -0
  399. data/lib/multimedia_paradise/yaml/tom_and_jerry/tom_and_jerry_episodes.yml +27 -0
  400. data/lib/multimedia_paradise/yaml/tv_channels/tv_channels.yml +46 -0
  401. data/lib/multimedia_paradise/yaml/use_this_video_player.yml +1 -0
  402. data/lib/multimedia_paradise/yaml/video/video.yml +26 -0
  403. data/lib/multimedia_paradise/yaml/video_collection/video_collection.yml +1933 -0
  404. data/lib/multimedia_paradise/yaml/video_encoding_settings.yml +62 -0
  405. data/lib/multimedia_paradise/yaml/video_filter_aliases.yml +221 -0
  406. data/lib/multimedia_paradise/yaml/youtube/alltagsgeschichte/alltagsgeschichte.yml +172 -0
  407. data/lib/multimedia_paradise/yaml/youtube/songs/README.md +3 -0
  408. data/lib/multimedia_paradise/yaml/youtube/songs/songs.yml +6 -0
  409. data/lib/multimedia_paradise/yaml/youtube_playlist/youtube_playlist.yml +6 -0
  410. data/lib/multimedia_paradise.rb +5 -0
  411. data/multimedia_paradise.gemspec +76 -0
  412. data/test/testing_audio_player.rb +15 -0
  413. data/test/testing_ffmpeg_options.rb +14 -0
  414. data/test/testing_file_duration.rb +17 -0
  415. data/test/testing_modify_year_of_audio_file.rb +14 -0
  416. data/test/testing_multimedia_paradise_project.rb +151 -0
  417. metadata +581 -0
data/README.md ADDED
@@ -0,0 +1,2340 @@
1
+ [![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg)](https://www.gobolinux.org/)
2
+ [![forthebadge](https://forthebadge.com/images/badges/made-with-ruby.svg)](https://www.ruby-lang.org/en/)
3
+ [![Gem Version](https://badge.fury.io/rb/multimedia_paradise.svg)](https://badge.fury.io/rb/multimedia_paradise)
4
+
5
+ This gem was <b>last updated</b> on the <span style="color: darkblue; font-weight: bold">21.02.2023</span> (dd.mm.yyyy notation), at <span style="color: steelblue; font-weight: bold">08:44:32</span> o'clock.
6
+
7
+ # MultimediaParadise - a toolset project for audio and video related data
8
+
9
+ <img src="https://i.imgur.com/Qh4Fve1.png" style="margin: 1em; margin-left: 2.5em">
10
+
11
+ The **multimedia paradise** project bundles together code that can be
12
+ used for "multimedia data" - in particular for **audio** and **video** files.
13
+
14
+ Most of the functionality found within the **multimedia paradise**
15
+ projects depends on <b>ffmpeg</b>, but in principle the code in the
16
+ main module called **MultimediaParadise** should work with other
17
+ toolkits as well, if a toolkit supports certain actions (such as
18
+ <b>sox</b>). As is often the case, support for other toolkits depends
19
+ on time investment - and time availability - of the main author of
20
+ this project, but in principle support for other toolkits can be
21
+ added as-is, at any moment in time. It is just that **ffmpeg** is
22
+ really good, so other toolkits will have a hard time competing
23
+ against it.
24
+
25
+ For multimedia-related purposes, **ffmpeg** is a really excellent
26
+ project. Thus, the MultimediaParadise gem will focus on **ffmpeg**
27
+ by default.
28
+
29
+ You can obtain a copy of ffmpeg from the following URL:
30
+
31
+ https://www.ffmpeg.org/download.html
32
+
33
+ ## Installation of the MultimediaParadise project
34
+
35
+ There are several ways how to install this project, including using
36
+ oldschool **setup.rb** - but I recommend the following way, for
37
+ simplicity, on any modern system:
38
+
39
+ gem install multimedia_paradise --user-install
40
+
41
+ The reason as to why I recommend the **--user-install** option is to be
42
+ used is because the various files under the **bin/** subdirectory that
43
+ are part of this gem will be made available in your home directory
44
+ (under e. g. ~/.gem/ruby/2.5.0/bin or whatever your local ruby
45
+ version is). That way you can easily add that directory to $PATH
46
+ or not, and make use of these files if you want to - and if not,
47
+ just ignore the bin/ subdirectory of this gem altogether.
48
+
49
+ You can find out the paths used by **gem** via:
50
+
51
+ gem environment
52
+
53
+ Note that even if you can not find such a bin/ subdirectory on your
54
+ system, these files are distributed within the **multimedia_paradise**
55
+ gem itself as such, so just extract the gem, then copy the bin/ files
56
+ to wherever you want to. There is more than one way to do
57
+ things! If you still have a hard time doing so, you can use a
58
+ toplevel method that will copy all bin/ files into the current
59
+ working directory. So, for instance, create a directory at:
60
+
61
+ mkdir /tmp/multimedia_paradise # just an example
62
+
63
+ Then start **irb** and issue:
64
+
65
+ require 'multimedia_paradise'
66
+ MultimediaParadise.copy_bin_directory
67
+
68
+ This will create a directory called **bin/** and then proceed
69
+ to copy all bin/ files into that directory. This is just a
70
+ convenience workaround if --user-dir does not work on your
71
+ system, for whatever the reason. (Note that this assumes
72
+ that these bin/ entries are in your HOME directory under
73
+ bin/ which may not always be the case; I have no idea why
74
+ this does not work anymore. It used to work in the past.
75
+ Ask the rubygems maintainers what they broke over the
76
+ years if this does not work for you. :P But, even in that
77
+ case, you can just download the .gem file from rubygems.org
78
+ and extract it on your own, and then you will 100% have
79
+ the bin/ hierarchy there.)
80
+
81
+ It is recommended to install **ffmpeg** and have it made
82
+ available on your system - ffmpeg really is a great project,
83
+ and the multimedia_paradise gem taps into the functionality
84
+ made available by ffmpeg. In many ways the multimedia_paradise
85
+ gem is a convenient wrapper over **some** of ffmpeg's
86
+ functionality.
87
+
88
+ In the next subsections on this webpage, several different
89
+ examples will be shown that may be usable (and useful) by
90
+ a user, to <b>benefit</b> from the code made available via
91
+ the MultimediaParadise project. Keep in mind that this
92
+ project tries to be a <b>helpful toolset</b> project,
93
+ not necessarily a professional-grade software suite.
94
+
95
+ ## Removing the audio from a local video file
96
+
97
+ Let us begin with a fairly simply use case here: say that you
98
+ want to **remove the audio from a local video file**.
99
+
100
+ So if you have such a use case that requires of you to
101
+ **remove audio from a local video file**, use the
102
+ following **API**:
103
+
104
+ require 'multimedia_paradise/audio/remove_audio.rb'
105
+ MultimediaParadise.remove_audio(path_to_the_file_goes_in_here)
106
+
107
+ Specific example for this:
108
+
109
+ MultimediaParadise.remove_audio('/tmp/foo.avi')
110
+ MultimediaParadise.remove_audio('foobar.mp4')
111
+
112
+ This functionality depends on an installed **ffmpeg**, as
113
+ previously pointed out. If anyone happens to know of a
114
+ pure ruby variant only, let me know - I may add this to
115
+ the method, as an alternative.
116
+
117
+ The above method essentially does this:
118
+
119
+ ffmpeg -i foobar.mp4 -an -vcodec copy /Depot/jj/output_foobar.mp4
120
+
121
+ So only the video stream is copied.
122
+
123
+ Note that the ruby-gtk3 bindings of **video_editor.rb**, distributed
124
+ within this project, makes use of this functionality as well.
125
+
126
+ ## Streamripper support
127
+
128
+ There is code support for <b>streamripper</b>, just a tiny wrapper.
129
+
130
+ This can be invoked like so:
131
+
132
+ MultimediaParadise.streamripper
133
+
134
+ This depends on the file <b>streamripper_wrapper.rb</b> which
135
+ is just a tiny, pure-ruby "wrapper" over streamripper. (It
136
+ really only directly calls the streampripper binary, so
137
+ nothing fancy.)
138
+
139
+ ## Modifying the timestamps of .srt files
140
+
141
+ The file <b>srt_regex.rb</b> - situated
142
+ at **multimedia_paradise/video/srt_regex.rb** - can be used if
143
+ you need to batch-modify .srt files, when they have the wrong
144
+ timestamp, for instance.
145
+
146
+ This was exactly the reason why I wrote that class a long
147
+ time ago - some .srt files may have a wrong offset, and
148
+ so we need to correct them.
149
+
150
+ Note that this class is quite old and the code quality is not
151
+ as high as other classes since I wrote it a long time ago. I may
152
+ improve on it eventually, but for the time being, assume that
153
+ it isn't one of the best classes in this project. I did
154
+ not have a use case for .srt files for many years - most
155
+ of the time I listen to english these days and then I don't
156
+ even need .srt files. I have had a few videos in chinese
157
+ (mandarin), and for these .srt files are useful - but even
158
+ that usage declined, so out of 1000 video files only 3-4
159
+ may still be in chinese, so I rarely need to use this
160
+ class anymore. As a consequence I did not invest much
161
+ timeo into improving it lateron.
162
+
163
+ ## Increasing the volume of an audio file
164
+
165
+ You can use the toplevel-level method for increasing the volume
166
+ of an audio file:
167
+
168
+ MultimediaParadise.increase_volume_of_this_audio_file()
169
+
170
+ The **first argument** to this method should be the name of the file
171
+ that you wish to modify or the name of the files. This is usually
172
+ a file such as foobar.mp3 or similar.
173
+
174
+ The **second argument** is the modified percentage value that is
175
+ given to -v (and to **sox**). For example, if you pass in 2.0,
176
+ then the volume of the audio file at hand will be **increased
177
+ twofold**. If it is 3.0, then it will be increased threefold,
178
+ and so on.
179
+
180
+ Since the name of the method is "increase_volume", that particular
181
+ method can not be used to decrease the volume (via negative
182
+ floats such as -2.0).
183
+
184
+ ## Extracting audio from any given video file
185
+
186
+ You can extract audio from any given video file, by making
187
+ use of <b>class MultimediaParadise::ExtractAudio</b>. This
188
+ presently depends on <b>ffmpeg</b>, so you must have
189
+ ffmpeg available.
190
+
191
+ A specific usage example follows, including the require line
192
+ that could be used:
193
+
194
+ require 'multimedia_paradise/audio/extract_audio/extract_audio.rb'
195
+ MultimediaParadise::ExtractAudio.new('foobar.avi')
196
+
197
+ This assumes that a video file called **foobar.avi** exists.
198
+
199
+ A **toplevel method** exists for this functionality as well:
200
+
201
+ MultimediaParadise.extract_audio(target_file_here)
202
+ MultimediaParadise.extract_audio('/tmp/foobar.avi')
203
+ MultimediaParadise.extract_audio('/home/lala.mp4')
204
+
205
+ Perhaps you may find the latter variant to be easier to read and
206
+ use than the variant that uses explicit **::** scoping for the
207
+ instantiation of **class ExtractAudio**. Under the hood, both
208
+ variants do the same of course.
209
+
210
+ ## Screen capture
211
+
212
+ If you want to capture the screen, that is, to record what
213
+ is happening, have a look at the class called
214
+ <b>MultimediaParadise::CaptureScreen</b>, in the file
215
+ **multimedia_paradise/video/capture_screen.rb**.
216
+
217
+ ## Autoinclude the main namespace
218
+
219
+ Since April 2014 you can autoinclude this project's main
220
+ namespace (toplevel **MultimediaParadise constant**)
221
+ by using the following ruby code:
222
+
223
+ require 'multimedia_paradise/autoinclude'
224
+
225
+ ## Using the executable bin/mpa
226
+
227
+ **mpa** is a small wrapper over mpv (or mplayer).
228
+
229
+ It is tailored to my own local videoset, which I store in
230
+ a yaml file. I am not sure how to best have other people
231
+ use mpa without the .yml file, but at the worst, it
232
+ is possible to just use bin/multimedia_paradise to play
233
+ an existing local video or audio file.
234
+
235
+ ## Guessing video names
236
+
237
+ I use a **.yml** file to keep track of registered video files.
238
+
239
+ I also needed a class that tells me the most likely name of a
240
+ video file, e. g. if the input is "Ninja", then this class
241
+ should report all Ninja video files, properly sorted, according
242
+ to the information contained in that .yml file. (This of course
243
+ requires that this genre is registered in that .yml file.)
244
+
245
+ **class MultimediaParadise::GuessVideoName** does precisely
246
+ that. Input the given search term at hand, such as **horror**
247
+ for horror movies, and it should hopefully report some information
248
+ that may be useful in order to find/name the video file at hand.
249
+
250
+ Note that this depends on a properly formatted .yml file; and
251
+ ideally you would create your own .yml file, with your own
252
+ tags, videos and so forth.
253
+
254
+ The **format** of the .yml file should be like this:
255
+
256
+ a) The number of the video file at hand, as an **Integer** value, such as 1, 2, 3 and so forth.
257
+ b) A **hash** that describes at the least the 'title', but may also contain entries such as <b>imdb:</b> and so forth.
258
+
259
+ ## Finding local videos
260
+
261
+ The file <b>find_video.rb</b> can be of help here as it will
262
+ try to locate local videos.
263
+
264
+ This is optimized towards my own dataset compiled about
265
+ videos; in the future, I will most likely provide a way
266
+ so that other people can also use their own dataset.
267
+ (The dataset I use is a simple yaml file storing all
268
+ information about the local videos.)
269
+
270
+ ## Delaying the audio of a video-file
271
+
272
+ FFmpeg allows you to easily delay the audio of a video file.
273
+
274
+ MultimediaParadise has this included as well, via:
275
+
276
+ MultimediaParadise.delay_audio()
277
+
278
+ The first argument to this should be the name of the file
279
+ that you wish to manipulate, such as <b>foobar.mp4</b>.
280
+
281
+ The second argument is the amount of seconds for the delay,
282
+ such as 5.53 seconds.
283
+
284
+ A new video-file will be generated as a consequence, if all
285
+ goes well.
286
+
287
+ ## Denoising audio/video
288
+
289
+ This subsection is about <b>removing noise from a multimedia file</b>.
290
+
291
+ **Noise** in this context refers to **unwanted audio**, such as
292
+ scratching on a blackboard during a university lecture, and similar
293
+ unwanted noises.
294
+
295
+ First, this functionality was needed because I inherited **audio recordings**
296
+ that were made via a cheap mp3-recorder from like **+10 years ago** or so,
297
+ say, the year 2009 - something like that.
298
+
299
+ The human voice has a **frequency range** between **300Hz** - **3000Hz**.
300
+
301
+ The **noise** in these files was extremey disturbing and distracting, and
302
+ I wanted to get rid of it, in order to more easily hear the voice of the
303
+ speaker. This also included increasing the volume as well, but that is
304
+ for another subsection.
305
+
306
+ The subsection here will additionally report some of my findings from back
307
+ then - as a **memo**.
308
+
309
+ A simple **filter-strategy** is to **first apply highpass**, and then
310
+ **lowpass**, via **ffmpeg**, such as in this way:
311
+
312
+ ffmpeg -i foobar.mp3 -af "lowpass=f=3000, highpass=f=200" output.mp3
313
+
314
+ Your local file comes first, such as the file <b>foobar.mp3</b>. This
315
+ should remove some of the noise that you may find in a recording, but
316
+ you may have to tweak the values a little in order to get the most
317
+ out of it.
318
+
319
+ Note that you can use **ffplay** to see the effect of this:
320
+
321
+ ffplay INPUT_FILE -af lowpass=3000,highpass=200
322
+ ffplay foobar.mp3 -af lowpass=4000,highpass=200
323
+ ffplay foobar.mp3 -af lowpass=2000,highpass=200
324
+
325
+ I integrated this functionality into **MultimediaParadise**, via the
326
+ following simple API:
327
+
328
+ MultimediaParadise.denoise('foobar.mp3')
329
+
330
+ This is the default use case, by just supplying the name/path to the
331
+ audio file in question.
332
+
333
+ The second argument to this method is the **lowpass value**; the
334
+ third argument is for the **highpass value**:
335
+
336
+ MultimediaParadise.denoise('foobar.mp3', '250', '2000')
337
+
338
+ This, surprisingly enough, worked. But I do not think it is
339
+ the ideal value.
340
+
341
+ For more information, see the following blog entry from 2017:
342
+
343
+ https://manerosss.wordpress.com/2017/07/24/ffmpeg-%C2%B7-apply-a-filter-to-enhance-voice-by-removing-low-and-high-frequency-noises/
344
+
345
+ If you need to find out which values are best, you can use <b>ffplay</b>
346
+ such as in this way:
347
+
348
+ ffplay INPUT -af lowpass=3000,highpass=200
349
+
350
+ ## Creating a screencast with multimedia_paradise and FFMPEG
351
+
352
+ Code in the file **multimedia_paradise/toplevel_methods/screencast.rb** can
353
+ be used to record a screencast (on Linux).
354
+
355
+ The API is as follows:
356
+
357
+ MultimediaParadise.start_screencast
358
+
359
+ The method accepts several parameters - if you need fine tuning then
360
+ have a look at that file.
361
+
362
+ Presently only video without audio can be recorded, but there are
363
+ tutorials out there that enable recording of audio as well. I will
364
+ have a look into this at a later time (<- written in September 2018).
365
+
366
+ ## Query the audio codec of a video file
367
+
368
+ You can use this top-level API to determine the audio codec of a
369
+ video file:
370
+
371
+ MultimediaParadise.query_the_audio_codec_of_this_file()
372
+ MultimediaParadise.query_the_audio_codec()
373
+ MultimediaParadise.audio_codec?()
374
+
375
+ All variants listed above work; the last option is the shortest
376
+ one, apparently.
377
+
378
+ The argument should be the path to a locally existing videofile.
379
+
380
+ Say that your file is at **/Depot/foobar.avi** then the ruby code
381
+ may look like this:
382
+
383
+ require 'multimedia_paradise'
384
+ uses_this_codec = MultimediaParadise.audio_codec?('/Depot/foobar.avi') # => ["aac"]
385
+
386
+ Note that this functionality **depends on ffmpeg** right now, so make
387
+ sure to install **ffmpeg** first.
388
+
389
+ ## Converting into .mp3 format
390
+
391
+ You can use class **MultimediaParadise::Audio::ToMp3** to convert
392
+ e. g. a **.wav** file into a **.mp3** file:
393
+
394
+ MultimediaParadise::Audio::ToMp3.new('path_to_wav.waf')
395
+
396
+ As this may be a bit cumbersome to type, there exists a simpler
397
+ **top-level method** to convert an audio-file into the **.mp3
398
+ format**:
399
+
400
+ MultimediaParadise.to_mp3(*input_files_here)
401
+ MultimediaParadise.to_mp3( %( foo.wav bar.wav ) )
402
+
403
+ ## ffmpeg options
404
+
405
+ This subsection just shows a few options for ffmpeg; I added this mostly
406
+ because I tend to be quite forgetful. That way I can have a quick
407
+ overview on the homepage of this gem here.
408
+
409
+ |Commandline flag | Example | Implementation Status
410
+ |-----------------|------------------------|----------------------------------------------------------------------------------------|
411
+ | **-s** | **-s 500×500** | convert the video into a **width x height** ratio, of 500 x 500 pixel |
412
+ | **-vcodec** | **-vcodec mpeg4** | specify which video-codec is to be used, e. g. for the conversion of a video file |
413
+
414
+ ## Playing several multimedia-files from a list/file
415
+
416
+ You can pass a list of files that the MultimediaParadise project
417
+ should play.
418
+
419
+ The toplevel method is **MultimediaParadise.play_this_list()**,
420
+ so for example:
421
+
422
+ MultimediaParadise.play_this_list '
423
+
424
+ /Users/x/VIDEO/Cartoons/Simpsons-09/Treehouse_Of_Horror_VIII.m4v
425
+ /Users/x/VIDEO/Cartoons/Simpsons-09/The_Joy_Of_Sect.m4v
426
+ /Users/x/VIDEO/Cartoons/Simpsons-08/The_Springfield_Files.m4v
427
+
428
+ '
429
+
430
+ Empty lines will be ignored, so the method will only play these
431
+ entries if they are not empty.
432
+
433
+ The alias **MultimediaParadise.play_from_this_list()** would also
434
+ work, by the way.
435
+
436
+ I needed this functionality because sometimes other classes written
437
+ in ruby may show, on the commandline, such a flat list, via a long
438
+ String broken by newlines.
439
+
440
+ ## Environment variables for the MultimediaParadise project
441
+
442
+ The MultimediaParadise project is tailored to my own needs primarily,
443
+ which means that other people may not necessarily benefit from the
444
+ project as much. Additionally, as of December 2018, there are some
445
+ hardcoded paths, which makes this even worse. I have decided in
446
+ December 2018 that this approach will change in the future.
447
+
448
+ For the time being, you can use certain ENV (environment) flags to
449
+ specify where your audio/video files are kept. This assumes that
450
+ you have **one central directory** for these files; respectively
451
+ up to two, if you keep your audio and video files **separate**.
452
+
453
+ For specifying where your **local video files** reside, you can use the
454
+ constant called **MULTIMEDIA_PARADISE_DEPOT_VIDEO**. Simply
455
+ set this, in your shell, to be the path to the directory where
456
+ your video files may be, such as in:
457
+
458
+ export MULTIMEDIA_PARADISE_DEPOT_VIDEO=/opt/videos
459
+
460
+ A similar constant exists for audio files; simply set
461
+ **MULTIMEDIA_PARADISE_DEPOT_AUDIO**.
462
+
463
+ export MULTIMEDIA_PARADISE_DEPOT_AUDIO=/opt/my_songs
464
+
465
+ ## Genre support of video files
466
+
467
+ If you have a .yml file that keeps your video files
468
+ sorted, then you can also use a <b>genre:</b> tag
469
+ identifier to classify the video at hand.
470
+
471
+ For example, the movie <b>The Blade Runner</b> may have an associated
472
+ genre called <b>Science Fiction</b>. The movie <b>Poltergeist</b> may
473
+ have a genre tag called <b>Horror</b> and so on.
474
+
475
+ Once the genre-tagging has been done, we can search
476
+ for these genres on the commandline, via class
477
+ <b>VideoGenres</b>.
478
+
479
+ See its --help option for commands.
480
+
481
+ video_genres --help
482
+
483
+ If you wish to find out which science fiction movies
484
+ are registered, do:
485
+
486
+ video_genres --genre="Science Fiction"
487
+
488
+ You can also use a shorter variant, via a Pseudo-Regex:
489
+
490
+ video_genres "/Science Fiction/"
491
+
492
+ Or the horror genre:
493
+
494
+ video_genres "/Horror/"
495
+
496
+ The "" can be omitted it seems (tested this on July 2021):
497
+
498
+ video_genres /Horror/
499
+
500
+ Some shortcuts exist if the above is too cumbersome. For example,
501
+ all science fiction movies could also be shown via this way:
502
+
503
+ video_genres --science-fiction
504
+
505
+ To see the available video genres, do this:
506
+
507
+ video_genres --available-video-genres
508
+
509
+ It you want to play a **random** horror movie, provided that you
510
+ have these registered tags, you can do the following:
511
+
512
+ video_genres --play-random-video-from-this-genre=horror
513
+
514
+ Keep in mind that this depends on the information stored
515
+ in the file **video_collection.yml**. This is catering to
516
+ my own use case, so you may want to populate this with your
517
+ own dataset.
518
+
519
+ ## Copying and merging the same video
520
+
521
+ If you sort of wish to "duplicate" a video, but append this
522
+ onto an existing one, then you can use this method:
523
+
524
+ MultimediaParadise.copy_and_merge_this_video_n_times
525
+
526
+ The first argument should be the existing video file; the
527
+ second argument should be how many times it should be
528
+ "repeated", which should be a number. For example, the
529
+ number 5 means that the video will be merged onto itself
530
+ 4 times, thus creating a video that is 5x the length (all
531
+ with the same content).
532
+
533
+ There are alternatives to this, such as looping the same
534
+ video; but I wanted to really be able to have the same
535
+ video be played over and over again, even though this
536
+ made the size larger.
537
+
538
+ ## MultimediaParadise::AnalyseMultimediaFile
539
+
540
+ class **MultimediaParadise::AnalyseMultimediaFile** can be used
541
+ to analyse multimedia files (e. g. audio and video files),
542
+ on the commandline.
543
+
544
+ I needed this because **ffmpeg -i** alone was tiresome to
545
+ read.
546
+
547
+
548
+
549
+ ## Flipping and rotating video files
550
+
551
+ FFMpeg can easily flip video files. MultimediaParadise supports this
552
+ functionality too, through the file
553
+ <b>multimedia_paradise/toplevel_methods/flip_and_rotate.rb</b>.
554
+
555
+ Horizontal and vertical flipping is supported through these
556
+ two **toplevel APIs**:
557
+
558
+ MultimediaParadise.horizontal_flip()
559
+ MultimediaParadise.vertical_flip()
560
+
561
+ The latter variant also has a simpler, more intuitive API:
562
+
563
+ MultimediaParadise.flip_upside_down()
564
+
565
+ So essentially, you picture a video, and then simply flip
566
+ the top to the bottom, and the bottom to the top. Easy-peasy.
567
+
568
+ The **first argument** to this method should be the name/path
569
+ to an existing video file.
570
+
571
+ You can also rotate a video file by 90° via this API:
572
+
573
+ MultimediaParadise.rotate_this_video_file_by_90_degrees('foo.mpg')
574
+
575
+ Since as of March 2019, two more methods were added to flip a video
576
+ (rotate a video) clockwise and counter-clockwise, by 90° each:
577
+
578
+ MultimediaParadise.flip_video_to_the_right
579
+ MultimediaParadise.flip_video_to_the_left
580
+
581
+ So the older method **MultimediaParadise.rotate_this_video_file_by_90_degrees()**
582
+ is essentially the same as the newer method **MultimediaParadise.flip_video_to_the_right**.
583
+
584
+ ## Merging audio files together
585
+
586
+ **class MultimediaParadise::MergeAudioFiles** can be used to merge different
587
+ audio files together. If no specific input argument is provided then this
588
+ class will scan for all audio files in the current working directory and all
589
+ subdirectories, then merge these together into a new file called **output.mp3**.
590
+
591
+ I needed this functionality so that I could put lectures together into a single
592
+ file - made it easier to listen to a single file, rather than find them all
593
+ spread out.
594
+
595
+ ## Toplevel cutting multimedia files
596
+
597
+ This subsection deals with cutting multimedia files, that is,
598
+ to chop a longer file into one (or several) smaller files.
599
+
600
+ The primary method for this is called **MultimediaParadise.cut_from_to()**,
601
+ but you can also use a few aliases to this method, such as
602
+ **MultimediaParadise.cut()**.
603
+
604
+ The API is flexible.
605
+
606
+ Let's first show a few examples:
607
+
608
+ MultimediaParadise.cut_from_to('00:00:01-00:25:10', this_file: 'Tales_from_the_crypt_S05E10_Came_the_Dawn_1993.mp4')
609
+ MultimediaParadise.cut_from_to('00:02:23 / 00:28:04', this_file: 'Tales_from_the_crypt_S05E10_Came_the_Dawn_1993.mp4')
610
+ MultimediaParadise.cut(to: '00:22:50', this_file: 'TALES_FROM_THE_CRYPT/Tales_from_the_crypt_S06E11_Surprise_Party.mkv')
611
+
612
+ These are somewhat equivalent.
613
+
614
+ The simplest way may be to pass, as **first argument**, a String to
615
+ the method, denoting the start position and the end position, in
616
+ HH:MM:SS format. But you can also decide to use a Hash instead,
617
+ such as the third example shows.
618
+
619
+ Do note that if you decide to use a String, you can either use
620
+ the '-' variant or a ' / ' variant. The latter is the default
621
+ display format for the mpv video/audio player, so I added support
622
+ for it since copy/pasting may be a bit simpler that way.
623
+
624
+ The special key called **:this_file** should be the file that you
625
+ wish to cut. The absolute path should be given here; for my home
626
+ system I also use some fake-macros, such as TALES_FROM_THE_CRYPT/
627
+ to denote where tales from the crypt may reside (and other files).
628
+ This allows me to more easily make use of my local file system.
629
+
630
+ The key **:to** refers to the end position, that is, when to make
631
+ the cut.
632
+
633
+ The ideal scenario for this method is to simply cut from a start
634
+ position to an end position - in other words, to make an existing
635
+ video file shorter.
636
+
637
+ Do note that another class, called CutAudio, also exists as part of
638
+ the multimedia_paradise project. This is partially due to legacy
639
+ reasons; and partially due to CutAudio being primarily used for
640
+ .mp3 files, and for interactive use. One day the functionality
641
+ may be re-used, but for the time being I will keep it separate (less
642
+ work for now).
643
+
644
+ If you rather want a simple API, where you input only two Strings
645
+ usually (as parameters), then you could use:
646
+
647
+ MultimediaParadise.video_duration(of_this_file, '00:30:00-00:35:00')
648
+
649
+ The first argument would be the file that you wish to cut; and
650
+ the second is the duration, so two Strings in total. Interally this
651
+ will be passed to the method **MultimediaParadise.cut_from_to()**
652
+ anyway, so you could even use a Hash instead - but the primary use
653
+ case for that method is to allow for a simpler API. Use whatever
654
+ you prefer.
655
+
656
+ ## Resizing a video
657
+
658
+ **ffmpeg** makes it easy to resize a video.
659
+
660
+ For example, say that you wish to re-scale an existing video
661
+ to the same ratio, but with fewer pixels, like 640. You could
662
+ use the following commandline invocation, with the **-vf**
663
+ flag, for this task:
664
+
665
+ ffmpeg -i input.mp4 -vf scale=640:-1 output.mp4
666
+
667
+ In this case, output.mp4 will have 640 pixels in width.
668
+
669
+ The strange -1 is simply a way to tell ffmpeg that the
670
+ same aspect ratio should be kept. That way ffmpeg will
671
+ calculate which ratio value should be used, in order
672
+ to retain the original width:height relation. You can
673
+ sometimes see that people use the wrong aspect ratio,
674
+ and then their video may look distorted.
675
+
676
+ MultimediaParadise also supports this via:
677
+
678
+ MultimediaParadise.scale_this_video()
679
+ MultimediaParadise.resize_this_vide()
680
+
681
+ The first argument is the path to the local input-file,
682
+ such as **input.mp4*.
683
+
684
+ After that a Hash can be used, where **height** and **width**
685
+ can be given.
686
+
687
+ MultimediaParadise.scale_this_video('input.mp4', height: 320, width: 220)
688
+
689
+ The argument for :width can be omitted, in which case -1 will be used
690
+ as default:
691
+
692
+ MultimediaParadise.scale_this_video('input.mp4', height: 320)
693
+
694
+ Would be the same as:
695
+
696
+ MultimediaParadise.scale_this_video('input.mp4', height: 320, height: -1)
697
+
698
+ The value for height: can be ignored too, in which case it will default
699
+ to 640 - but this default value may change one day in the future, so it
700
+ may be better to specify at the least one value here. But, ultimately,
701
+ if you don't care, this could also work:
702
+
703
+ MultimediaParadise.scale_this_video('input.mp4')
704
+
705
+ We may even omit the first argument in the future, one day, if we
706
+ assign a default file on the toplevel - but for the time being
707
+ (**September 2019**), the API is how it is and requires **at the
708
+ least one argument**.
709
+
710
+ ## Creating a video out of an audio file, such as a .mp3 file
711
+
712
+ Via the API **MultimediaParadise.create_video_from_this_audio()**
713
+ you can "create" a video, from an audio file, such as a .mp3 file.
714
+
715
+ This requires a static image, which is the **second argument** to
716
+ that method.
717
+
718
+ Why did I add this method? I needed a way to upload .mp3 files
719
+ to a remote website but they had a **filter** removing .mp3 files;
720
+ they allowed for .mp4 files, so I converted it into a .mp4
721
+ file and that works. That is strange, since you can always
722
+ use **ffmpeg** to extract the .mp3 audio again - so I dont
723
+ understand the filter that prevents .mp3 upload but allows
724
+ .mp4 upload ...
725
+
726
+ Quite odd if you ask me.
727
+
728
+ **:\\**
729
+
730
+ **:/**
731
+
732
+ Anyway - here an example for the official API for this,
733
+ from within ruby:
734
+
735
+ this_audio_file = 'foobar.mp3'
736
+ this_image_file = '/FORENSIC_CAT.jpg'
737
+ MultimediaParadise.create_video_from_this_audio(this_audio_file, this_image_file)
738
+
739
+ ## MovieSearcher
740
+
741
+ class MovieSearcher can be used to look up information about a
742
+ movie from http://www.omdbapi.com, if you have an API key.
743
+
744
+ The code written for this class is not great, but if all you
745
+ need is some quick commandline information then this class
746
+ could be used. It can be found at
747
+ **multimedia_paradise/video/movie_searcher.rb**.
748
+
749
+ Since as of 02.01.2020, an executable is now distributed
750
+ as well, called **movie_searcher** (under the **bin** subdirectory
751
+ of this gem).
752
+
753
+ I have aliased this executable to **videorating**, and then simply
754
+ do this on the commandline:
755
+
756
+ videorating tremors
757
+
758
+ You may need an API key called **OMDBAPI_API_KEY**. I recommend
759
+ you to set this; class MovieSearch will then try to pick it up
760
+ when it was set (see the ruby code for this).
761
+
762
+ ## Deshaking videos
763
+
764
+ Ffmpeg has support for deshaking videos through a filter:
765
+
766
+ https://ffmpeg.org/ffmpeg-filters.html#deshake
767
+
768
+ The deshake-filter from ffmpeg helps remove camera shake from
769
+ hand-holding a camera.
770
+
771
+ The API for multimedia_paradise is the following:
772
+
773
+ MultimediaParadise.deshake(input_files_go_here)
774
+ MultimediaParadise.deshake('foobar.mp4')
775
+
776
+ ## Missing video files
777
+
778
+ Via:
779
+
780
+ mpa --missing-videos?
781
+
782
+ I can determine which video files are missing locally.
783
+
784
+ This is evidently catered to my own use case, and a big .yml
785
+ file that I maintain. You may have to create your own .yml
786
+ file here if you wish to make use of this functionality.
787
+
788
+ ## class ConvertAudioToVideoWithImage
789
+
790
+ **class ConvertAudioToVideoWithImage** allows you to "attach"
791
+ a static image file to an audio file, such as a <b>.mp3</b>
792
+ file.
793
+
794
+ This functionality depends on **ffmpeg**, so you need to
795
+ have ffmpeg available in order to make use of this class.
796
+
797
+ Two arguments are necessary to class ConvertAudioToVideoWithImage:
798
+
799
+ (1) first, the audio-file
800
+ (2) second, the image file that you wish to use
801
+
802
+ You can also use the following toplevel-method:
803
+
804
+ MultimediaParadise.to_avi_with_this_image()
805
+
806
+ with the same parameter pattern.
807
+
808
+ To give you a specific example - say that you have your .mp3
809
+ file at:
810
+
811
+ /Depot/j/foobar.mp3
812
+
813
+ And your image at:
814
+
815
+ /Depot/Images/foobar.png
816
+
817
+ Then the proper way to use the **toplevel-method** would be:
818
+
819
+ MultimediaParadise.to_avi_with_this_image('/Depot/j/foobar.mp3','/Depot/Images/foobar.png')
820
+
821
+ It does not have to be an **.avi** file though. You can also
822
+ use a .mp4 file via:
823
+
824
+ MultimediaParadise.to_mp4_with_this_image('foo.mp3','bar.png')
825
+
826
+ The latter method can also be used from the commandline via:
827
+
828
+ convert_audio_to_mp4video_with_image a.mp3 b.png
829
+
830
+ Remember that the audio file comes first, and the image file
831
+ comes last.
832
+
833
+ ## Removing the last second of an audio file
834
+
835
+ If you just need to quickly chop off the last 1 second from
836
+ an audio file then you can use this API:
837
+
838
+ MultimediaParadise::RemoveLastSecond.new(ARGV)
839
+ MultimediaParadise::RemoveLastSecond.new('foobar.mp3')
840
+
841
+ ## Encoding a video via MultimediaParadise
842
+
843
+ You can use the toplevel method called **MultimediaParadise.encode_this_video()**
844
+ to encode a video.
845
+
846
+ By default CRF will be used, which is the **Constant Rate Factor**.
847
+
848
+ Support for two-pass encoding has not been added to MultimediParadise,
849
+ but you can read up on ffmpeg how to do this:
850
+
851
+ https://trac.ffmpeg.org/wiki/Encode/H.264
852
+
853
+ Example:
854
+
855
+ require 'multimedia_paradise/toplevel_methods/encode_this_video.rb'
856
+ MultimediaParadise.encode_this_video('foobar.avi')
857
+
858
+ The default output for this will be .mkv, which is the matroska container.
859
+ (Currently that method in MultimediaParadise does not allow for
860
+ another output format, in **June 2020**; but this may be changed in the
861
+ future in another release of this project.)
862
+
863
+ ## MultimediaParadise.set_player_in_use()
864
+
865
+ The toplevel method **MultimediaParadise.set_player_in_use()** can
866
+ be used to set the main multimedia player (audio + video) in use
867
+ for the MultimediaProject. Normally I set this to **mplayer** or
868
+ **mpv**, but **vlc** or any other player could also be used here.
869
+
870
+ You can also quickly set to use **mpv** since as of the 30th
871
+ June 2020.
872
+
873
+ Usage example for permanently setting this:
874
+
875
+ multimedia_paradise --use-mpv
876
+
877
+ This will modify the content of a .yml file.
878
+
879
+ ## The file video_collection.yml
880
+
881
+ The file video_collection.yml, which is distributed by this
882
+ project, can be used to denote different videos files.
883
+
884
+ This is catered to my own use case, but you can adapt this
885
+ file to your own use case.
886
+
887
+ I use the file to automatically handle local videos, such as batch-renaming
888
+ or ensuring that everything is correct, and so on.
889
+
890
+ To determine the default (assumed) location, try this
891
+ method:
892
+
893
+ MultimediaParadise.file_video_collection
894
+
895
+ ## Working with subtitles
896
+
897
+ You can embed subtitles into a video directly. This subsection
898
+ explains how this can be done.
899
+
900
+ Embedding subtitles (text files such as .srt files) into a video
901
+ file is trivial with ffmpeg. The multimedia_paradise project
902
+ supports this as well, via the following toplevel API:
903
+
904
+ require 'multimedia_paradise/toplevel_methods/subtitles.rb'
905
+ MultimediaParadise.embed_this_subtitle_onto_that_video('foo.srt','bar.avi')
906
+
907
+ If you wish to remove a subtitle from a video file, try this:
908
+
909
+ MultimediaParadise.remove_subtitles_from_this_video_file('foobar.mp4')
910
+
911
+ Since as of October 2020, a file called **bin/remove_subtitles**
912
+ is made available as well, for commandline usage.
913
+
914
+ ## Additional documentation and information
915
+
916
+ In **October 2020** I decided to publish all my collected local video
917
+ and audio related content, which is made available through
918
+ oldschool .cgi files. To make this even more complicated, most
919
+ of these files are written in german so these have only a limited
920
+ use for most people. Still, I think some of the information
921
+ contained therein may be useful for other people, which is why
922
+ I will publish this slowly over the coming months. Furthermore,
923
+ some yaml-files are part of this, and publishing yaml files is
924
+ useful, as it is decoupled from the programming language
925
+ (in this case **ruby**).
926
+
927
+ ## Changing the audio codec of a video file via FFMpeg
928
+
929
+ If you want to change the audio codec in a given video file, say,
930
+ **foobar.avi**, then you can use this API:
931
+
932
+ MultimediaParadise.use_lame_codec('foobar.avi')
933
+
934
+ This essentially just combines **-vcodec copy -acodec libmp3lame**
935
+ but I wanted to have a simpler **top-level API** in ruby for this
936
+ too, so this method was added.
937
+
938
+ ## Playing a random (video or audio) file
939
+
940
+ <b>class MultimediaParadise::PlayRandomFile</b> can play a
941
+ random multimedia file. Since this will select a file
942
+ randomly, you can only pass in a directory for now - although
943
+ passing in an Array may also make sense, so perhaps this
944
+ class will be extended at a later time.
945
+
946
+ ## Copying a random video file
947
+
948
+ If you ever need to copy a random video file to the current
949
+ working directory then the following class may be of help
950
+ here:
951
+
952
+ require 'multimedia_paradise/video/copy_random_video.rb'
953
+ MultimediaParadise::CopyRandomVideo.new(ARGV)
954
+
955
+ Unfortunately this is currently hardcoded to my own home
956
+ setup. In the future (past January 2021) I may make this
957
+ more flexible, but it was mostly a "throwaway" script,
958
+ so I just moved on after having written it.
959
+
960
+ ## Bugs in the MultimediaParadise project
961
+
962
+ Bugs are annoying - let's get rid of them!
963
+
964
+ If you run into a bug, or a usability problem, feel
965
+ free to report it. Email should suffice for now; at
966
+ some point I will add github issue trackers again,
967
+ but I am not really using git, so this makes this
968
+ a bit awkward. :)
969
+
970
+ If you can, please provide information how to reproduce
971
+ a given bug. The easier it is to reproduce it, the
972
+ easier it should be to fix it.
973
+
974
+ ## Autogenerate music
975
+
976
+ I will expand this subsection in the coming months and years. The goal
977
+ is to be able to autogenerate at the least some music. I am not
978
+ interested in perfect concertos, but some simple beats that could
979
+ be combined.
980
+
981
+ ## Setting the title metadata of a .mp3 file or any other multimedia-related file
982
+
983
+ Thanks to ffmpeg we can easily modify the metadata entry of a .mp3
984
+ file.
985
+
986
+ MultimediaParadise supports this too, via the following API:
987
+
988
+ MultimediaParadise.set_title_of(this_audio_file, this_title)
989
+
990
+ So, the first argument should be **the local path to the multimedia
991
+ file, such as a .mp3 file**; and the second argument should be the
992
+ title that this file should have. I use this for batch-setting
993
+ the title - and a file called **bin/auto_title** exists that
994
+ does this from the commandline as well.
995
+
996
+ In plain ffmpeg command, it would look like this:
997
+
998
+ ffmpeg -i input.mp4 -metadata title="The video title" -c copy output.mp4
999
+
1000
+ The title comes into the title="" entry there.
1001
+
1002
+ For .mp4 files, but possibly also .mp4 files, you could use the following
1003
+ meta-data tags:
1004
+
1005
+ - title
1006
+ - author
1007
+ - album_artist
1008
+ - album
1009
+ - grouping
1010
+ - composer
1011
+ - year
1012
+ - track
1013
+ - comment
1014
+ - genre
1015
+ - copyright
1016
+ - description
1017
+ - synopsis
1018
+ - show
1019
+ - episode_id
1020
+ - network
1021
+ - lyrics
1022
+
1023
+ ## Obtaining an image from a video file via ffmpeg
1024
+
1025
+ You can use this commandline variant to obtain one image from
1026
+ a video file. Via **-ss** you can specify the start position.
1027
+
1028
+ Usage example:
1029
+
1030
+ ffmpeg -i input.mp4 -vframes 1 -an -s 320x180 -y -ss 12 output.jpg
1031
+
1032
+ The multimedia_paradise gem makes this possible via this API:
1033
+
1034
+ MultimediaParadise.return_image_from_this_video_file(
1035
+ 'input.mp4',
1036
+ starting_position = 12, # in n seconds
1037
+ width_and_height_for_the_image = '480x270'
1038
+ )
1039
+
1040
+ The path to the local video file should come as the first argument
1041
+ to this method.
1042
+
1043
+ ## The sinatra interface of the MultimediaParadise project
1044
+
1045
+ First install sinatra:
1046
+
1047
+ gem install sinatra # or use --user-install
1048
+
1049
+ Next you should be able to start it, either via **MultimediaParadise.start_sinatra**
1050
+ or from the commandline via:
1051
+
1052
+ multimedia_paradise --sinatra
1053
+
1054
+ You should then be presented with the sinatra-interface.
1055
+
1056
+ For example, to determine how many local videos are available, use
1057
+ n_local_videos, as in:
1058
+
1059
+ http://localhost:5580/n_local_videos
1060
+
1061
+ This is also available via the index, so you just have to click on
1062
+ it via the mouse button.
1063
+
1064
+ You can view all registered video files, aka their respective
1065
+ names, via:
1066
+
1067
+ http://localhost:5580/available_video_files
1068
+
1069
+ You can also directly play video files, if they are available (at
1070
+ the least on my home setup) via:
1071
+
1072
+ http://localhost:5580/027
1073
+
1074
+ Or just the name. This requires that the base directory where
1075
+ the video file resides, is added to the sinatra application.
1076
+ And, of course, that the video file also exists at that path.
1077
+ If it does not work on your system, make sure that the
1078
+ correct directory is passed in, and that the video file
1079
+ exists locally; have a look at the sinatra-specific
1080
+ code in **multimedia_paradise/sinatra/**. The default is
1081
+ for my home system so you may have to change a very few
1082
+ lines.
1083
+
1084
+ You can also pass the name of the video file directly and if it
1085
+ exists in the specified directory it will be played.
1086
+
1087
+ I tested this on windows as well, and it works there - at the
1088
+ least for .mp4 files. I could not get .avi files to work yet,
1089
+ neither on windows nor on linux. I am not entirely certain
1090
+ as to why, but perhaps it may be time to ditch .avi files
1091
+ altogether, in favour of .mp4.
1092
+
1093
+ I also intend to add a play/ API just to keep this a bit
1094
+ separate and visually nicer.
1095
+
1096
+ Unfortunately I have been hitting some problems with sinatra,
1097
+ namely that I have no idea what is going on "behind the scenes".
1098
+ I'll have to re-evaluate this at a later time - mostly trying to
1099
+ find a replacement that is more debug-friendly than sinatra,
1100
+ without being as bloated as ruby on rails.
1101
+
1102
+ In June 2022 I tested this on windows, such as via an URL
1103
+ to a local video file like:
1104
+
1105
+ http://localhost:5580/035_Back_to_the_Future.mp4
1106
+
1107
+ And it worked! \o/
1108
+
1109
+ The .mp4 file was playing in the browser. I guess this will
1110
+ favour the .mp4 file format versus .mkv or .avi, simply
1111
+ because it gives us one more option to play video files.
1112
+ I did get .mkv to work in the browser, though, so perhaps
1113
+ only .avi is the one that will have to be deprecated.
1114
+
1115
+ It goes slower than on Linux, though, so Linux is really
1116
+ the better operating system, in my opinion.
1117
+
1118
+ ## Lyrics of songs
1119
+
1120
+ This subsection is just a little reminder for myself.
1121
+
1122
+ I searched for translations of different lyrics on the www. However
1123
+ had, many of the translations are clearly wrong, where the words are
1124
+ incorrect. In theory this may be because whoever made the translation
1125
+ manually simply misheard the word(s) - but often the words are so
1126
+ different that this can not be explained by a genuine mistake,
1127
+ in my opinion. I think many of these translations are **deliberately**
1128
+ incorrect, simply because the words are too different. This problem
1129
+ is then amplified by different websites copy/pasting the same
1130
+ error.
1131
+
1132
+ I give you a specific example.
1133
+
1134
+ During the eurodance era, there was one interesting rapper
1135
+ in the group **Sonic Surfers**, with the song called
1136
+ **Don't give it up**.
1137
+
1138
+ One passage is 'officially' this:
1139
+
1140
+ Tap into my brain and just channelin'
1141
+ Let's get high on bass and trebelin'
1142
+
1143
+ However had, I listened to this part about ten times now and
1144
+ in my opinion the text is the following:
1145
+
1146
+ Tap into my brain and just channelin'
1147
+ Let's get high on base and adrenaline
1148
+
1149
+ I am almost 100% certain that he said "base" and "adrenaline".
1150
+ It also makes more sense - adrenaline is more logical than
1151
+ trebeling, whatever that should even be. So why was the translation
1152
+ that is available on the www different? Yes, it may be a sloppy
1153
+ mistake, I understand that, but ... to mistake two words that
1154
+ are quite clearly different? And that is not the only example.
1155
+
1156
+ In the same text of the song you have this passage:
1157
+
1158
+ If anybody should be trippin' as you do
1159
+ Dance into the trance on my little kavoodoo
1160
+
1161
+ But my own translation is this:
1162
+
1163
+ If anybody should be trippin' as you do
1164
+ Dance into the trance on my lyrical voodoo
1165
+
1166
+ Again - I could be wrong, but ... not sure. Lyrical
1167
+ voodoo makes more sense than does "little kavoodoo" too.
1168
+
1169
+ Anyway. You can find many similar examples in different songs. I
1170
+ do not think these are ALL accidents; I think the translations are,
1171
+ at the least to some extent, deliberately incorrect. You could
1172
+ reason - or assume - that this came automated by scripts/robots,
1173
+ but the errors seem so subtly incorrect that I have a hard time
1174
+ imagining this did not come by some random underpaid person in
1175
+ India or what not, working for a low wage ... so there may be a
1176
+ non-deliberate accident explanation, but still. It is **clearly
1177
+ not correct either way how you look at it**, for whatever the
1178
+ underlying reason for this may be.
1179
+
1180
+ Evidently this is fairly pointless for other people to know, but since
1181
+ I actually want to understand the lyrics of good songs I thought
1182
+ I should note this down, for future reference. My larger theory is
1183
+ that many - or most - of these translations were created not by
1184
+ human beings but by a script (perhaps not the above example, but
1185
+ many others). And that script was, possibly, altered to include
1186
+ deliberately incorrect words near the end. That would explain the
1187
+ pattern I could see above, where the first sentence is correct, the
1188
+ second sentence becomes incorrect towards the end. It could just
1189
+ be a human too, though - not possible to distinguish this.
1190
+
1191
+ (Of course a human being could also do this, e. g. if paid to
1192
+ do this and then consistently apply that pattern, or indeed
1193
+ doing genuine mistakes. It's not possible to easily distinguish
1194
+ between a script, or human beings that work consistently in
1195
+ doing incorrect translations. But a script runs for virtually
1196
+ free, whereas human beings cost money, so I assume the more
1197
+ likely explanation is that this is done by one, or several,
1198
+ script(s). Would be interesting to find out WHO is doing these
1199
+ translations on different websites. Some evidently only
1200
+ copy/paste, because you can find the exact same error in
1201
+ the "translated" websites as well.)
1202
+
1203
+ I do not have enough statistical data to verify either way, but I
1204
+ am quite suspicious about what is presented to me nowadays via
1205
+ Google in general - I happily admit that I no longer trust Google, so
1206
+ I will simply assume that many of these translations (but not all)
1207
+ did not come from human beings, but from software instead. You
1208
+ can also find websites that aggregate other resources, and the
1209
+ randomly munch it together in ways that makes no real sense. So
1210
+ much fake stuff going on these days ...
1211
+
1212
+ ## Adding silence to an audio file
1213
+
1214
+ If you want to append 5 seconds of **silence** to a song, you can
1215
+ do so via **sox**, and the following API in the MultimediaParadise
1216
+ toplevel namespace:
1217
+
1218
+ MultimediaParadise.append_silence_to_this_song(5, 'ack.mp3')
1219
+
1220
+ (The file size of the new song will be fairly large, though. I
1221
+ am not certain as to why that is the case. Seems awkward that
1222
+ silence leads to a massively increased file size ... anyone knows
1223
+ how to do that via ffmpeg?)
1224
+
1225
+ ## CutMultimedia - a merger of CutAudio and CutVideo
1226
+
1227
+ Many years ago I had a class called **CutAudio**. I even received
1228
+ an email concerning this class (which was made available as a
1229
+ standalone .gem on rubygems.org, back then), from a user who reported
1230
+ several bugs with it - and a lack of documentation. All of which was
1231
+ correct back then. :-)
1232
+
1233
+ In **February 2021** I finally started to rewrite the important
1234
+ parts of the old class called **CutAudio** into **CutMultimedia**,
1235
+ while also adding **more documentation** to it. This is presently
1236
+ still an ongoing endeavour, so ... stay-tuned in this regard!
1237
+
1238
+ Another goal for this rewrite was to add **ruby-gtk3 bindings** to
1239
+ it from the get go. That way users who do not like the commandline
1240
+ are able to use this class as well, if they have ruby-gtk3
1241
+ available. The primary focus, nonetheless, is on the commandline
1242
+ use, though, and not everything that is available on the commandline
1243
+ is available via the GUI. The GUI mostly only captures the
1244
+ essential parts, whereas the commandline exposes more functionality
1245
+ that is less commonly required.
1246
+
1247
+ The idea behind class **CutMultimedia** is that no matter whether you use
1248
+ a video file or an audio file as input to this class, to allow you to
1249
+ easily and quickly <b>cut</b> this audio file (or video file), and
1250
+ **re-join** these new audio files easily as well into a single file.
1251
+ So it is not only cutting alone; it also means to make use of
1252
+ re-joining. The end product is then a new file, such as a new .mp3
1253
+ file. The interactive part that is made available via the menu()
1254
+ method exists primarily to facilitate that goal: to cut an
1255
+ existing .mp3 file and rejoin the desired segments into a new
1256
+ .mp3 file.
1257
+
1258
+ The name for the class is now **CutMultimedia**, but a backwards
1259
+ alias exists, called **CutAudio**. For consistency reasons, **CutVideo**
1260
+ also exists. I recommend to use the name **CutMultimedia** directly,
1261
+ though - that name should be more 'durable' than the other two
1262
+ names.
1263
+
1264
+ You can find the code for this class here, in the following
1265
+ subdirectory:
1266
+
1267
+ require 'multimedia_paradise/multimedia/cut_multimedia/*.rb'
1268
+
1269
+ The class can be invoked by either of the following executables,
1270
+ residing under the <b>bin/</b> hierarchy:
1271
+
1272
+ bin/cut_audio
1273
+ bin/cut_video
1274
+ bin/cut_multimedia # this one is probably the best variant
1275
+
1276
+ Simply have a look at the file content if you have a hard
1277
+ time finding it on your file system; something changed in
1278
+ rubygems so I don't know where files are placed anymore,
1279
+ but these bin/ files are part of the .gem, so simply
1280
+ extract the gem and have a look around.
1281
+
1282
+ As **first argument** to this class you should <b<provide the
1283
+ path to the audio or video file</b> that you wish to modify.
1284
+
1285
+ For example, if you have a file available at the location
1286
+ **/tmp/foobar.mp3** then you could invoke **cut_audio**
1287
+ like so:
1288
+
1289
+ bin/cut_audio /tmp/foobar.mp3
1290
+ cut_audio /tmp/foobar.mp3
1291
+ caudio /tmp/foobar.mp3 # I actually use an alias called 'caudio'; faster and easier for me to type.
1292
+
1293
+ Or use **cut_multimedia** as a name instead - that is equivalent
1294
+ since as of **February 2021**.
1295
+
1296
+ You can avoid the leading bin/ part if the file at hand is
1297
+ in your PATH variable. Or if you set an alias, anyway.
1298
+
1299
+ (As said Ialiased it to "caudio", as that is my mnemonic
1300
+ for "cut-audio".)
1301
+
1302
+ When you apply the above command, on the commandline, you will
1303
+ enter the **interactive menu** interface (if that file was
1304
+ found). This interface allows you to do certain actions that
1305
+ can be helpful in regards to cutting audio or video files.
1306
+
1307
+ For example, specifying start and end position of the
1308
+ **cutting job**, which is one of the most commonly commands
1309
+ I use. See some examples for this a bit below.
1310
+
1311
+ You can also ask for "help" via:
1312
+
1313
+ help
1314
+
1315
+ while you are in the interactive mode.
1316
+
1317
+ You can use the ruby-gtk3 interface, which is under
1318
+ **multimedia_paradise/gui/gtk3/cut_multimedia/**.
1319
+
1320
+ You can designate **start** and **stop** positions when in
1321
+ **interactive mode** of class CutMultimedia. You can do so
1322
+ via prefixing "s" and suffixing "e", such as in the
1323
+ following way:
1324
+
1325
+ s10 # start at 10 seconds
1326
+ e20 # end at 20 seconds
1327
+
1328
+ This would mean to "start at 10 seconds" and "end at 20 seconds".
1329
+ So we will here **cut out the intermediate 10 seconds**
1330
+ between these two points.
1331
+
1332
+ If you want the commands to be more verbose, try these longer
1333
+ variants instead:
1334
+
1335
+ start10
1336
+ end20
1337
+
1338
+ But I prefer "s" and "e" - less to type.
1339
+
1340
+ There is some support for specifying both start and end positions
1341
+ in one go. For example, the above commands shown so far require
1342
+ two lines to be used, e. g. first s10 and then e20. You can
1343
+ simplify this to the following one-liner instead:
1344
+
1345
+ 10-20
1346
+ 10 - 20 # this is also possible, if you want it more spaced out
1347
+
1348
+ That way you can skip using the "s" and "e" altogether and it
1349
+ should work just fine. If it does not, it is most likely a
1350
+ bug - feel free to send an email to point out a bug, or
1351
+ something missing in regards to the documentation and it
1352
+ will be addressed eventually.
1353
+
1354
+ Via "play" you can play the audio file at hand; I recommend having
1355
+ installed **mplayer** or **mpv** for this task. That way you can
1356
+ find out **where** you may wish to cut in the first place. I use
1357
+ this quickly to determine the exact positions, on the commandline,
1358
+ and then continue to define start and end positions.
1359
+
1360
+ Once you have all your start and end positions defined, you can
1361
+ run the following command to **commit**:
1362
+
1363
+ cut
1364
+
1365
+ This will cut out the selected subsection; in this case the part
1366
+ from 10 seconds to 20 seconds. You will then have a new .mp3
1367
+ file that should be about 10 seconds long (ffmpeg does not
1368
+ seem to cut at 100% precision all the time; recently it created
1369
+ a file with a duration of 10.03 seconds rather than 10.00
1370
+ seconds. I do not know why, so I can not explain this
1371
+ behaviour.)
1372
+
1373
+ The **number** in use there specifies how many seconds are to be used.
1374
+ This can sometimes be a bit difficult to calculate in your head
1375
+ e. g. how many seconds do **83 minutes** entail to. How many of
1376
+ you can quickly calculate this accurately in your head? I
1377
+ struggle there.
1378
+
1379
+ So, a 'pseudo-calculator' can be used and queried from within
1380
+ class **CutMultimedia**.
1381
+
1382
+ For example, if you input the following:
1383
+
1384
+ 6*60
1385
+
1386
+ Then this would quickly show you that the result of this is
1387
+ 360 seconds (the input meant **6 minutes**, if you think about
1388
+ it - aka 6 * 60 seconds, as one minute has 60 seconds).
1389
+
1390
+ There are many more options available, so have a look at the
1391
+ "help" section there. Keep in mind that <b>CutMultimedia</b> is
1392
+ a bit complicated to use sometimes, and also has had a very
1393
+ few bugs as well. On the other hand, if you focus on the three
1394
+ main actions (start, end, cut) then this is really quite simply
1395
+ to use. You'll get the hang of it quickly.
1396
+
1397
+ Take note that the **ruby-gtk3 bindings** to class CutMultimedia
1398
+ are not perfect, and they are not complete, either. I may improve
1399
+ on them in the future, but for now they have to suffice. (My
1400
+ main goal is to actually clone the functionality of
1401
+ **mp3directcut**, but I don't know how to run a visualize-function
1402
+ so ... that's on my todo list.)
1403
+
1404
+ Note that you can start the ruby-gtk3 bindings from the
1405
+ interactive menu via:
1406
+
1407
+ gui
1408
+
1409
+ In **October 2021** code was added to use this in a scripted
1410
+ fashion. So, rather than define the start and end positions
1411
+ interactively, you can now input them into a text file
1412
+ instead.
1413
+
1414
+ The format of this text file should look like this:
1415
+
1416
+ start 2
1417
+ end 4
1418
+ start 6
1419
+ end 8
1420
+
1421
+ s 10.5
1422
+ e 12.5
1423
+
1424
+ So, alternating between start_position and end_position.
1425
+ That's it.
1426
+
1427
+ You can use "start" or "s", or "end" or "e", respectively.
1428
+ But either of which is mandatory; omitting both s and e
1429
+ is not possible.
1430
+
1431
+ Furthermore you need to use a "clean" workspace, aka only
1432
+ the file that you wish to modify, such as **foobar.mp3**
1433
+ in the given directory.
1434
+
1435
+ The code for this functionality is available in the
1436
+ following API:
1437
+
1438
+ MultimediaParadise::CutMultimedia.evaluate_from_this_file()
1439
+
1440
+ Pass, as <b>argument to it</b>, the file that contains these
1441
+ short and end positions, e. g. the text file that you will
1442
+ use. The code will then <b>automatically</b> pick up the
1443
+ first .mp3 file that it can find in the current directory,
1444
+ so again, use a clean workspace for this step.
1445
+
1446
+ Then it will do the specified actions and merge the newly
1447
+ created files back in. (There is also an additional step to
1448
+ convert to .wav and back to .mp3. The reason for this is that
1449
+ somehow ffmpeg's concat feature does not fix the broken
1450
+ headers. I don't know how else to fix this other than
1451
+ re-encoding. If someone else has a better solution I
1452
+ will be happy to hear it.)
1453
+
1454
+ If the file was generated (aka merged) then all other files
1455
+ used in the process will be removed. So if all goes well,
1456
+ you will have +1 file in that directory: the cutted file.
1457
+
1458
+ Note that while CutMultimedia, originally called CutAudio,
1459
+ was started to cut .mp3 files, you can also modify other
1460
+ files with it too, such as merging/cutting .waf files,
1461
+ .ogg files, .aac files, .aiff files and so forth. The only
1462
+ requirement is that ffmpeg can handle these files.
1463
+
1464
+ ## Overlaying two audio songs
1465
+
1466
+ Use:
1467
+
1468
+ MultimediaParadise.overlay_two_audio_files()
1469
+ MultimediaParadise.overlay_two_audio_files('foo.mp3','bar.mp3')
1470
+
1471
+ This depends on **sox**. It is possible to do so via ffmpeg but the
1472
+ syntax is very complex, so I opted for sox for now. In the future
1473
+ this may be improved, but for now this has to suffice.
1474
+
1475
+ ## mp3 tags
1476
+
1477
+ This short subsection contains just a bit of information concerning
1478
+ mp3 ID tags. I needed this because I added a ruby-gtk3 based
1479
+ mp3-id-tagger some time ago.
1480
+
1481
+ **ID3v1 tags** have a 30-character limit. Thus, it is better to
1482
+ avoid ID3v1 and just use ID3v2.
1483
+
1484
+ Software such as **Mp3tag** can show whether the .mp3 file uses
1485
+ ID3v1 or ID3v2.
1486
+
1487
+ **ID3v2 tags** are also limited (nothing is infinite here), but
1488
+ the limit is at either 255, 32000, or 64000 some such. Even
1489
+ 255 already is more than enough for most text, in my opinion.
1490
+
1491
+ ## MultimediaParadise::ImdbRating
1492
+
1493
+ class **MultimediaParadise::ImdbRating** can be used to display
1494
+ the rating for a movie on the commandline, if it is registered
1495
+ as part of IMDB.
1496
+
1497
+ ## MultimediaParadise::Multimedia::VideoDownloader
1498
+
1499
+ class **MultimediaParadise::Multimedia::VideoDownloader** was
1500
+ added in December 2021. The idea is that whenever we want to
1501
+ download some remote video, this class should do that task
1502
+ for us. It has been designed to be re-usable from the get
1503
+ go.
1504
+
1505
+ Downloaded video files go into a directory such as this:
1506
+
1507
+ /home/Temp/multimedia_paradise/downloaded_videos/
1508
+
1509
+ This may be different on your system. Furthermore, old
1510
+ videos are NOT deleted, so this directory may become
1511
+ very big. Other classes that may merge all video files
1512
+ into one video file will simply pick up whatever is
1513
+ in that directory, so make sure to keep that directory
1514
+ clean before calling other classes. At a future point
1515
+ in time this behaviour may change, and become more
1516
+ user-friendly - but for now, this is documented here
1517
+ so that people are aware of it, until that behaviour
1518
+ is changed (simplified in particular).
1519
+
1520
+ ## AudioPlayer
1521
+
1522
+ This class is just a thin "wrapper" over **mplayer** or
1523
+ **mpv** really. It has been created in **early June 2014**.
1524
+
1525
+ The file can be found at
1526
+ **multimedia_paradise/audio/audio_player/audio_player.rb**.
1527
+
1528
+ It was originally created because I needed to play, via
1529
+ the commandline, audio songs in a <b>loop</b> - like a
1530
+ **juke box**. I wanted it to be very simple too, so no
1531
+ ncurses interface to it.
1532
+
1533
+ I also use it to perform wake-up calls in the morning, like
1534
+ an alarm clock.
1535
+
1536
+ There is an **executable** for this, at **bin/audio_player**,
1537
+ which acts as entry point to the code behind it, for
1538
+ <b>class MultimediaParadise::AudioPlayer</b>.
1539
+
1540
+ If you want to **play in a loop**, you can pass the argument
1541
+ "loop" or just "l".
1542
+
1543
+ Since as of the **24th February 2018**, it can also act as a
1544
+ "timer", together with class <b>Roebe::At</b>, which is part
1545
+ of the **roebe** gem. For example, if you want to play
1546
+ random songs at the time **21:35:00**, you can do:
1547
+
1548
+ rsong 21:35:00
1549
+
1550
+ Note that <b>rsong</b> is simply an alias that I use towards
1551
+ <b>bin/audio_player</b>. Without an alias, the above becomes:
1552
+
1553
+ audio_player 21:35:00
1554
+
1555
+ Usually I tend to use <b>mpv</b>, but sometimes I do use
1556
+ mplayer, e. g. when mpv has some problem due to recent
1557
+ API changes. In this case, one can specify to use mplayer
1558
+ on the commandline, via:
1559
+
1560
+ rsong 10:00:00 --use-mplayer
1561
+
1562
+ As already mentioned, mpv or mplayer are the two main
1563
+ audio players (binaries). But there are more alternatives
1564
+ available. For example, the program called **sox**
1565
+ has a binary called **play**. I have had a use case
1566
+ in February 2022 where neither mpv nor mplayer worked,
1567
+ due to a dependent library being broken (a temporary
1568
+ problem). As I was fixing this, I wanted to listen
1569
+ to music still, and added ad-hoc support for sox.
1570
+
1571
+ This can be triggered via:
1572
+
1573
+ rsong --use-sox
1574
+
1575
+ The binary **play** will be used as a result of this
1576
+ commandline flag.
1577
+
1578
+ ## Download videos from Google (actually Youtube)
1579
+
1580
+ The file google_video_downloader.rb can be used to download
1581
+ videos from Google - but we may have to use youtube-dl for
1582
+ this, which is python. This is not ideal since we use ruby :)
1583
+ but I am too lazy to clone the functionality of <b>youtube-dl</b>
1584
+ for now, so this just has to be glue code really. (Glue code
1585
+ is for lazy people and I am lazy.)
1586
+
1587
+ For anyone who would like to give a replacement in ruby -
1588
+ you probably don't need to replace all of youtube-dl,
1589
+ only the part where we can obtain an URL. The rest can
1590
+ be solved by wget or curl, supposedly; or just ruby.
1591
+
1592
+ ## Embedding Youtube Videos
1593
+
1594
+ "Embedding" Youtube Videos is also possible. Note the quotes.
1595
+
1596
+ The code is in the file **multimedia_paradise/video/youtube_embedder.rb**.
1597
+
1598
+ ## Playlists
1599
+
1600
+ The **MultimediaParadise** project can generate **.m3u** files, as
1601
+ long as they are simple, e. g. one entry per line. For the purpose
1602
+ of the document here, we will call such **.m3u** files
1603
+ **playlists**.
1604
+
1605
+ The class responsible for the creation of **.m3u** files - that is
1606
+ **playlist files** - is class <b>MultimediaParadise::CreateM3uPlaylist</b>,
1607
+ residing at the location <b>multimedia_paradise/audio/create_m3u_playlist.rb</b>
1608
+ within the **MultimediaParadise** project.
1609
+
1610
+ The primary objective of this class is to generate that
1611
+ **.m3u** text file. Of course you can do so easily without the
1612
+ project - just do a "ls" and pipe the output it into a file, more
1613
+ or less - but I wanted this functionality specifically within the
1614
+ multimedia_paradise project, so that I can automate the creation
1615
+ of playlists, including batch-uploading to other websites at a
1616
+ later time, such as for youtube and similar remote websites. Thus
1617
+ I wanted to tie the functionality into the multimedia_paradise
1618
+ gem.
1619
+
1620
+ I myself use that class to generate playlists for various different
1621
+ **song types** - be these **eurodance songs**, **trance songs**,
1622
+ **pop songs** and so forth. Once such a .m3u file has been
1623
+ (auto)generated, it could then be used for uploading this file
1624
+ to an external website, as mentioned, such as to **youtube** or
1625
+ other websites that support playlists like that. Of course in order
1626
+ for this to work you may need to provide valid URLs to these
1627
+ individual remote entries somehow. The primary use case for
1628
+ class <b>MultimediaParadise::CreateM3uPlaylist</b> is for
1629
+ **local audio files**, though.
1630
+
1631
+ So, how to use class <b>MultimediaParadise::CreateM3uPlaylist</b>?
1632
+
1633
+ The input to class <b>MultimediaParadise::CreateM3uPlaylist</b>
1634
+ should ideally be a **yaml file** describing your songs (at the
1635
+ least **the path to these songs**), but you could also use the **API**
1636
+ from within Ruby, naturally and thus use a **ruby array** directly
1637
+ that is to be passed to the class; just pass this Array to
1638
+ **.new()**.
1639
+
1640
+ Let's show a simple example for this:
1641
+
1642
+ MultimediaParadise::CreateM3uPlaylist.new(%( /foo/bar.mp3 /bar/foo.mp3 /tmp/dah.mp ))
1643
+
1644
+ You can also use this simpler **toplevel method**, in ruby instead:
1645
+
1646
+ MultimediaParadise.create_m3u_playlist()
1647
+
1648
+ The **first argument** to this method should contain the **dataset**
1649
+ that you will use for the .m3u file that is to be autogenerated.
1650
+ This should be a simple Array.
1651
+
1652
+ You can, naturally, rename the .m3u file after it has been created,
1653
+ since a default name will be used - the <b>generic name</b> used for
1654
+ generation of the file will be <b style="color: royalblue">playlist.m3u</b>.
1655
+
1656
+ For my own custom dataset, e. g. to generate a playlist with decent
1657
+ **tales-from-the-crypt** videos, I can just do:
1658
+
1659
+ playlist --tales-from-the-crypt
1660
+
1661
+ The **MultimediaParadise project** also comes with another class,
1662
+ called **class Playlist**, which has a different task. That
1663
+ **class Playlist** will handle audio-playlists, primarily. For
1664
+ example, it can play audio files at certain positions in
1665
+ the playlist.
1666
+
1667
+ Usage example from the commandline for this:
1668
+
1669
+ playlist 33,44,55
1670
+
1671
+ Would play the songs at position 33, then 44 and then 55. It
1672
+ is thus a very primitive sort of **jukebox**. See
1673
+ **playlist --help** for help options.
1674
+
1675
+ You can change positions in that playlist. To exchange position
1676
+ 95 with position 94, you could use input like this:
1677
+
1678
+ playlist "95 -> 94"
1679
+
1680
+ This would mean to take the song at position 95 and move it
1681
+ to position 94. Conversely the song at position 94 will be
1682
+ moved to 95; this is thus ***an exchange operation***.
1683
+
1684
+ To show the entries of a playlist do:
1685
+
1686
+ playlist --show
1687
+
1688
+ (You can also omit this commandline flag since as of December
1689
+ 2020. This will default to show all entries in the playlist
1690
+ then.)
1691
+
1692
+ Note that by default this is adjusted to my own dataset, which
1693
+ is most likely totally useless to other people. You have to
1694
+ use your own playlist (a .yml file, called **playlist.yml**).
1695
+
1696
+ To see the available music-genres, try:
1697
+
1698
+ playlist --genres
1699
+
1700
+ In February 2022 a new class was added, called
1701
+ **MultimediaParadise::SimulateYoutubePlaylist**. The goal
1702
+ for this class is to "simulate" a playlist that could be
1703
+ used for youtube. It can also automatically create a
1704
+ .m3u list.
1705
+
1706
+ The idea here is that you can build up a playlist without
1707
+ depending on google necessarily. So you can add a bunch
1708
+ of remote URLs to youtube videos into a yaml file and
1709
+ have these work. They will be opened via the browser
1710
+ one after the other. Note that for this to work you
1711
+ have to install the 'open' gem, via "gem install open".
1712
+
1713
+ Note that as of February 2022 the class it not yet finished.
1714
+ It can batch-download the videos from the remote URLs
1715
+ given, but it is not really user-friendly yet. Stay
1716
+ tuned in this regard.
1717
+
1718
+ ## Watermarking videos
1719
+
1720
+ A <b>watermark</b> is a specific tag to a video. This can be a
1721
+ <b>logo</b> but it can also be used as some kind of (annoying)
1722
+ filter.
1723
+
1724
+ Whatever your use case may be, ffmpeg supports watermarking
1725
+ videos - and multimedia_paradise taps right into that
1726
+ functionality.
1727
+
1728
+ Adding a watermark to a video is possible and quite simple.
1729
+
1730
+ The class that does so, in regards to the MultimediaParadise
1731
+ project, is aptly called <b>Watermark</b> and it allows you
1732
+ to use FFMPEG to embed a watermark video, using the
1733
+ simple <b>MultimediaParadise.watermark()</b> method.
1734
+
1735
+ I rarely need to use this method so it may not be as
1736
+ polished as other parts of the project, though.
1737
+
1738
+ The default use case is to simply call that .rb file and
1739
+ pass a video file to it, such as shown in the following
1740
+ example:
1741
+
1742
+ vwatermark /Depot/Temp/MultimediaProject/foobar.mp4
1743
+
1744
+ (vwatermark is an alias on my system to simplify
1745
+ this. It will call the .rb file directly)
1746
+
1747
+ If you want to use your own image, then you have to pass an
1748
+ additional argument to the method, which should be the path
1749
+ to the image at hand.
1750
+
1751
+ vwatermark /Depot/Temp/MultimediaProject/foobar.mp4 /opt/my_awesome_logo.png
1752
+
1753
+ That's about it!
1754
+
1755
+ ## ffmpeg_merge
1756
+
1757
+ This file, at **bin/ffmpeg_merge**, was added in April 2022
1758
+ to quickly merge multimedia files together, via the
1759
+ commandline.
1760
+
1761
+ ## Shrinking the size of .mp3 files
1762
+
1763
+ If you need a method to process all .mp3 files, via **lame**,
1764
+ then you can use the following method:
1765
+
1766
+ MultimediaParadise.shrink_quality_of_these_mp3_files(Dir['*.mp3'])
1767
+
1768
+ ## Noise in audio files (such as .mp3) and denoising these files (that is remove the noise)
1769
+
1770
+ Say you have some audio recording on the street, and some cars drive
1771
+ by or some birds chirp. This is often not wanted or even distracting.
1772
+
1773
+ So, how about removing that noise part? It is possible, even for
1774
+ simple human beings. One solution is to use **sox** for this
1775
+ task.
1776
+
1777
+ Note that this depends on the quality of the audio and the patterns
1778
+ that can be found in the noise itself, so different audio files
1779
+ will not work equally well. But let's assume a simple audio file
1780
+ and there are repetitive entities (repetitive data) inside of
1781
+ that stream.
1782
+
1783
+ **sox** allows the removal of these repetitive structures via the
1784
+ <b>noiseprof</b> and <b>noisered effects</b> of sox.
1785
+
1786
+ First, work on a test-audio file and let's call it <b>foobar.mp3</b>.
1787
+ Put it into an area where you can work with it.
1788
+
1789
+ Now that this was done, use sox to <b>create a background noise
1790
+ profile</b> from this .mp3 file:
1791
+
1792
+ sox foobar.mp3 -n noiseprof noise.profile
1793
+
1794
+ The next step is to go ahead and <b>remove the noise</b>
1795
+ from the given .mp3 file using this <b>profile</b>:
1796
+
1797
+ sox foobar.mp3 output.mp3 noisered noise.profile 0.21
1798
+
1799
+ These are the commandline instructions. MultimediaParadise
1800
+ has right now (May 2022) the first one built in as a
1801
+ toplevel API. Use it like this:
1802
+
1803
+ MultimediaParadise.create_noise_profile(of_this_mp3_file)
1804
+ MultimediaParadise.create_noise_profile('foobar.mp3') # See the commandline instructions mentioned above.
1805
+
1806
+ ## Deinterlacing a video
1807
+
1808
+ You can deinterlace a video via this API:
1809
+
1810
+ MultimediaParadise.deinterlace_this_video()
1811
+ MultimediaParadise.deinterlace_this_video('foobar.avi')
1812
+
1813
+ ## Converting to the .mp4 format
1814
+
1815
+ In my local video collection I have various <b>.mkv</b> files.
1816
+ These work fine via **mpv**, but if I try to play these on firefox,
1817
+ via the <b>HTML5 tags</b>, then it does not work. One solution is
1818
+ to convert them into .mp4 files; then they may work in the browser
1819
+ as well.
1820
+
1821
+ The multimedia_paradise gem has this enabled via the following
1822
+ toplevel API:
1823
+
1824
+ MultimediaParadise.to_mp4
1825
+ MultimediaParadise.to_mp4('foobar.mkv') # Input the filename here.
1826
+
1827
+ This is essentially the same as issuing the following on the
1828
+ commandline, via <b>ffmpeg</b>:
1829
+
1830
+ ffmpeg -i foobar.mkv -vcodec copy -acodec copy foobar.mp4
1831
+
1832
+ So, not a huge "time saver" as such, as you can just do the above
1833
+ on your own. But I wanted to have this enabled within the
1834
+ multimedia_paradise gem. Furthermore, a file called **bin/to_mp4**
1835
+ exists, to make available this functionality as-is.
1836
+
1837
+ Then the usage example on the commandline would be:
1838
+
1839
+ to_mp4 foobar.mkv
1840
+
1841
+ So this exists mostly out of convenience really.
1842
+
1843
+ In the long run it is planned to add many more conversion
1844
+ methods, such as **MultimediaParadise.to_avi()** and so
1845
+ forth. (The <b>multimedia_paradise gem</b> will attempt to
1846
+ use the most logical parameters here, if parameters are
1847
+ needed. Usually this just means **-vcodec copy** and
1848
+ **-acodec copy**, but this may not always be the case;
1849
+ sometimes re-encoding may occur, such as when dealing
1850
+ with very old video and audio codecs. But right now,
1851
+ it'll default to **copy**, for convenience and
1852
+ simplicity.)
1853
+
1854
+ ## Converting to a .flac file
1855
+
1856
+ You can use the following API to convert a file, such as foobar.mp3,
1857
+ into a .flac file:
1858
+
1859
+ MultimediaParadise.to_flac()
1860
+ MultimediaParadise.to_flac('foobar.mp3')
1861
+
1862
+ This functionality depends on ffmpeg. The method was added mostly
1863
+ for convenience-reasons, as the syntax for ffmpeg itself is
1864
+ fairly simple: <b>ffmpeg -i input.mp3 output.flac</b>
1865
+
1866
+ ## Converting to an .aac file
1867
+
1868
+ The following API can be used to convert an audio file into a
1869
+ .aac file, via ffmpeg and the <b>libvorbis</b> audio codec:
1870
+
1871
+ MultimediaParadise.mp3_to_aac()
1872
+ MultimediaParadise.to_aac() # This variant is shorter.
1873
+
1874
+ ## Conversions that are supported (table)
1875
+
1876
+ This table is mostly an overview of what is specifically supported
1877
+ by the multimedia_paradise gem as of May 2022.
1878
+
1879
+ Conversion | Comment
1880
+ --------------------|------------------------------------
1881
+ to_aac | convert into .aac format
1882
+ to_ogg | convert into .ogg format
1883
+ to_aiff | convert into .aiff format
1884
+ to_wav | convert into .wav format
1885
+ to_webm | convert into .webm format
1886
+ to_mkv | convert into .mkv format
1887
+ to_dv | convert into .dv format (Digital Video)
1888
+
1889
+ ## Converting a video file to the corresponding images
1890
+
1891
+ Via the toplevel method:
1892
+
1893
+ MultimediaParadise.video_to_images
1894
+
1895
+ you can <b>convert a video to its corresponding images</b>.
1896
+
1897
+ The first argument to this method should be the <b>filename</b>
1898
+ of the video-file. Specific example for this:
1899
+
1900
+ MultimediaParadise.video_to_images("foobar.mp4")
1901
+
1902
+ The second argument is the image format to use. You can just pass
1903
+ the Symbol :default here if you don't care about the format;
1904
+ this will then default to the <b>.jpg</b> format.
1905
+
1906
+ The <b>third argument</b> is the framerate, e. g. how many frames
1907
+ to convert into images per second. The default here currently is
1908
+ <b>25</b>. Some videos require more or fewer images per second,
1909
+ so you may want to change this is you feel you get too many or
1910
+ too few images.
1911
+
1912
+ Usage example if you want to do only one image per second:
1913
+
1914
+ MultimediaParadise.video_to_images("foobar.mp4", :default, 1)
1915
+
1916
+ See the file **multimedia_paradise/toplevel_methods/conversion.rb**
1917
+ for more information about that functionality - it is made possible
1918
+ thanks to ffmpeg.
1919
+
1920
+ ## Radio stations and a graphical user interface to it (GUI)
1921
+
1922
+ Since as of **October 2018**, the **MultimediaParadise** project comes
1923
+ with a small **yaml file** called **radio_stations.yml**.
1924
+
1925
+ x = YAML.load_file('radio_stations.yml')
1926
+
1927
+ The idea here is to have a few additional audio-streams (from **radio
1928
+ stations**) that could be loaded up into, for example, **rhythmbox**.
1929
+
1930
+ I also wanted to have a default "template" for testing some ruby code
1931
+ there, such as autogenerating a playlist from this file, or listening
1932
+ to radio stations via mplayer (or mpv) and similar activities.
1933
+
1934
+ The file **radio_stations.yml** is evidently catered to my own use
1935
+ case. If you wish to use your own .yml file then you can do so by
1936
+ setting the environment variable called **MULTIMEDIA_PARADISE_RADIO_STATIONS**
1937
+ to the path of a **local yaml file**. For the necessary format, see the
1938
+ file **radio_stations.yml** that comes distributed with this **.gem**.
1939
+ Or, you can simply modify the .yml file as-is and add/remove any
1940
+ entries; keep a backup just in case perhaps.
1941
+
1942
+ I may listen to local internet radio stations but also to external
1943
+ ones, such as **BBC**. The following example shows how I tap into
1944
+ this functionality via the commandline, first by showing **BBC 1**:
1945
+
1946
+ multimedia_paradise --bbc1
1947
+ multimedia_paradise --bbc2
1948
+ multimedia_paradise --bbc3
1949
+ multimedia_paradise --bbc4
1950
+ multimedia_paradise --fm4
1951
+
1952
+ The above list may be extended in the future, but for now (December
1953
+ 2018) it shall suffice.
1954
+
1955
+ Do note that this functionality depends on a multimedia player,
1956
+ such as **mpv** or **mplayer**. See elsewhere in this document
1957
+ how to set to use such a multimedia player, as far as the
1958
+ multimedia_paradise gem is concerned.
1959
+
1960
+ If you would rather prefer a GUI than have to use the commandline,
1961
+ you could use **gtk_radio**, available under the bin/ directory.
1962
+
1963
+ This **gtk-radio** gtk-widget even has a stop/play/resume button,
1964
+ and an **increase/decrease** in audio volume, **if ALSA is available**.
1965
+ This GUI will list some radio stations, based on a .yml file - you
1966
+ could use the same format and supply your own .yml file there
1967
+ should you wish to use other radio stations, but support for this
1968
+ has not yet been added (need to re-think that part; or you just
1969
+ modify the .yml file as it is, then start the gtk-radio - that
1970
+ should work fine as well if you feel like doing this. After all
1971
+ it is just data stored in yaml, nothing magic about it. I may
1972
+ also add more radio stations if someone sends me a sensible list
1973
+ of these to be included by default via an email, but please include
1974
+ all relevant details about that radio station, most importantly
1975
+ the remote URL in order to tap into the remote stream; right
1976
+ now **mpv** is used for this functionality, so if that information
1977
+ is not available then the stream can not possibly work).
1978
+
1979
+ Evidently LOTS of features are missing that might make sense
1980
+ for any **GUI** about radio-streams, and some bugs may exist as well,
1981
+ so don't use any of these widgets in "production" or for anything
1982
+ serious. I will, however had, try to make the GUI components,
1983
+ including the www-interfaces, more useful over the coming months
1984
+ and years, as time (and motivation) permits.
1985
+
1986
+ Note that for the first 10 buttons, you can **access** them via the
1987
+ **keyboard** too - by pressing ALT+number, such as **ALT+1** for
1988
+ the first button.
1989
+
1990
+ There is also a small bug right now in that mpv will continue
1991
+ to play sometimes, e. g. when the PID was not registered
1992
+ correctly. I have to pkill this from the commandline right now;
1993
+ one day in the future this bug will be squished, but for now
1994
+ it is better to document it as-is.
1995
+
1996
+ Next a few links that may be useful if you have to find out
1997
+ URLs to playlists:
1998
+
1999
+ https://marijanbloggt.at/2021/01/links-zu-streams-der-oesterreichischen-radiosender/120920
2000
+
2001
+ The ruby-gtk3 client currently looks like this (on IceWM):
2002
+
2003
+ <img src="https://i.imgur.com/O3K5XI9.png" style="margin: 1em">
2004
+
2005
+ This is far from perfect, but as a first step it should work
2006
+ somewhat ok-ish, as of <b>May 2022</b>. At a later time this
2007
+ may be improved visually, but for now it is how it is.
2008
+
2009
+ ## Converting a .mp4 or .avi file to an animated .gif
2010
+
2011
+ You can use the following API to convert a video to an
2012
+ animated .gif:
2013
+
2014
+ MultimediaParadise.to_gif('foobar.mp4')
2015
+
2016
+ I have not yet found a way to keep a high quality here,
2017
+ though, so the produced .gif is not really great. Perhaps
2018
+ someone finds out how to keep a higher quality here.
2019
+
2020
+ ## Querying the video codec in use
2021
+
2022
+ If you have ffmpeg installed then you can query the video
2023
+ codec in use via:
2024
+
2025
+ MultimediaParadise.return_video_codec_of_this_file
2026
+ MultimediaParadise.video_codec?
2027
+ MultimediaParadise.return_video_codec_of_this_file('foobar.mp4')
2028
+ MultimediaParadise.video_codec?('foobar.mp4')
2029
+
2030
+ This currently only works if a video has one stream. I do not
2031
+ know of a working syntax for querying all video streams in
2032
+ use, if a file has more than one stream, so keep this in mind.
2033
+ Most video files have only one stream though, so this method
2034
+ should work fine.
2035
+
2036
+ There is also an executable tying that functionality together,
2037
+ at <b>bin/video_codec</b>. It may then return a String on the
2038
+ commandline, such as "mpeg4".
2039
+
2040
+ ## GUI components of the multimedia_paradise project
2041
+
2042
+ ### Thoughts about GUIs in the multimedia_paradise gem
2043
+
2044
+ In December 2022 this subsection was re-arranged, to make
2045
+ it easer to focus on GUIs.
2046
+
2047
+ When we here refer to GUIs, note that web-applications,
2048
+ such as via sinatra, are included into this use case,
2049
+ as well as other languages, such as Java. Nonetheless,
2050
+ an important focus will also be on classical GUI elements,
2051
+ such as via ruby-gtk3 or ruby-libui.
2052
+
2053
+ The following subsections will detail more about the GUI
2054
+ components that are part of this project.
2055
+
2056
+ ### Graphical User Interface (GUI) and the MultimediaParadise project
2057
+
2058
+ A **Graphical User Interface** provides a human user with **a simplified
2059
+ way to interact with a computer**, via software.
2060
+
2061
+ Traditionally this was done primarily via a **desktop-computer**, the
2062
+ **mouse** (the pointer interface), the keyboard and a monitor. Nowadays
2063
+ the **www** is often used as a 'replacement' for these older graphical
2064
+ user interfaces, so some shift has definitely occurred, in particular
2065
+ in favour of 'smart' phones.
2066
+
2067
+ This evidently changed the way how users interact with these devices;
2068
+ typically no large keyboard is available on most of these devices, and
2069
+ an additional obvious constraint is the small screen estate.
2070
+
2071
+ My own primary focus, however had, is still centered around **oldschool
2072
+ classical desktop computers**, and **laptops** similar to such desktop
2073
+ computers, so I am **not** primarily concerned with smaller devices as
2074
+ such when it comes to **GUIs** in general. Perhaps at some later point
2075
+ in time this may change, but not for now. (In ruby-gtk3 this should
2076
+ be easily solvable via the **CSS support** anyway, so we could **use
2077
+ different style sheets**, depending on the interface at hand.)
2078
+
2079
+ How does this relate to the **multimedia_paradise project**?
2080
+
2081
+ The **multimedia_paradise project** tries to make use of GUIs as
2082
+ well.
2083
+
2084
+ Specifically you may be able to find **ruby-gtk** code that is
2085
+ distributed via the MultimediaParadise project that could be useful
2086
+ in this regard. In the past ruby-gtk2 was used for this project, but
2087
+ since as of the year **2021** ruby-gtk3 is the new default for all
2088
+ my projects when it comes to GUIs via gtk - including the MultimediaParadise
2089
+ project. I will not necessarily obsolete the old ruby-gtk2 deliberately
2090
+ so, mind you, but **new code** written will be in ruby-gtk3 most assuredly,
2091
+ and enabling ruby-gtk2 functionality is no longer a priority in this
2092
+ regard - at the least not for this project. Perhaps at one point in the
2093
+ future ruby-gtk2 will be viable again, but since GTK version 4.x
2094
+ is already released upstream, I think it is time to move on and away
2095
+ from GTK+-2.0, even though I still like this older GTK version. I am
2096
+ still using a GTK+-2.0 based editor, for instance.
2097
+
2098
+ The GTK-code made available as part of this project, in turn, depends
2099
+ on the project called **gtk_paradise**, as that project handles
2100
+ gtk-related parts, aside from the official upstream gtk3 gem of
2101
+ course. So make sure to install it as well, via
2102
+ **gem install gtk_paradise**.
2103
+
2104
+ Note that in general a lot of the GUI parts of MultimediaParadise
2105
+ are in an **extremely** **experimental** state, subject to change,
2106
+ and possibly filled with many unknown (and a few known) bugs -
2107
+ but you can have a look at some of the GUIs to see how they fare
2108
+ so far. An example would be the **gtk-radio** GUI component in
2109
+ particular, for ruby-gtk3. That one should work somewhat ok, although I
2110
+ have tested it mostly on non-systemd linux distributions only. On
2111
+ such a system it works quite ok-ish; the process-ID killing of mpv
2112
+ is super-hackish though. On windows with WSL enabled, it does not
2113
+ quite work yet, though; I have to find out how to be able to play
2114
+ sound on windows via WSL. Perhaps WSL2 simplifies this, I don't know
2115
+ yet.
2116
+
2117
+ Since as of **November 2020** a basic GUI has been added that allows
2118
+ the user to **tag .mp3 files with appropriate meta-data**. This is
2119
+ stored in the file called **tag_mp3_files.rb**. (The old name
2120
+ was **id_renamer**, but this was changed in **September 2021**
2121
+ when the application was rewritten.)
2122
+
2123
+ class **MultimediaParadise::GUI::Gtk::TagMp3Files** depends on
2124
+ the external library called **taglib** (**gem install taglib-ruby**),
2125
+ and the ruby bindings to that library, so make sure these are
2126
+ installed.
2127
+
2128
+ In the coming months this gtk-widget may be improved, but don't
2129
+ expect too many more upgrades to it for now - I am just glad to
2130
+ have finished it for now. It is more a 'fancy prototype' then a
2131
+ truly grandesque GUI. :)
2132
+
2133
+ You can also start this widget from the commandline, provided that
2134
+ you have the ruby-gtk bindings installed.
2135
+
2136
+ Example for that, on the commandline:
2137
+
2138
+ multimedia --gtk-tag
2139
+ multimedia --tagger
2140
+
2141
+ In **August 2021** a few things were added and it looks a bit
2142
+ better than it did a year ago. The current iteration looks
2143
+ like this on Linux (icewm) - may look different on GNOME or
2144
+ KDE depending on the theme in use:
2145
+
2146
+ <img src="https://i.imgur.com/9QIPEOn.png" style="margin-left: 2em">
2147
+
2148
+ In **September 2021** this was rewritten slightly and it looks
2149
+ a bit better now, in my opinion although it stayed mostly the
2150
+ same nonetheless. You can compare the two images here:
2151
+
2152
+ <img src="https://i.imgur.com/MnKgSUF.png" style="margin-left: 2em">
2153
+
2154
+ A new button was added as well - the one where you can randomly
2155
+ open a file. This allowed me to more rapidly go through the
2156
+ audio files and tag them appropriately so.
2157
+
2158
+ Since as of **February 2021**, there is also a video-editor prototype
2159
+ available. I will add more functionality to it over the coming months,
2160
+ but this is a slow project, since it is a hobby-based project. The
2161
+ goal here would be to eventually show a per-frame widget of the
2162
+ video, and allow the user to make modifications to it as-is.
2163
+
2164
+ Since as of **2021** I am also adding libui-specific widgets. This
2165
+ will not look as pretty as ruby-gtk3, but the benefit is that this
2166
+ will work on windows, out-of-the-box by default, whereas setting
2167
+ up GTK on windows is much harder.
2168
+
2169
+ I will keep a list of which widgets are implemented (even if it
2170
+ is only partially implemented).
2171
+
2172
+ youtube_downloader.rb # (1)
2173
+ lyrics.rb # (2)
2174
+ video_player.rb # (3)
2175
+ simple_play_widget.rb # (4) missing scrolled-window support in libui, though
2176
+ youtube_channels.rb # (5) quite ok; opening in the browser does not work very well on windows right now, in August 2021, though
2177
+ widget_increase_or_decrease_audio.rb # (6)
2178
+
2179
+ The following widgets still have to be ported:
2180
+
2181
+ cut_multimedia.rb
2182
+ id_renamer.rb
2183
+ multimedia_converter.rb
2184
+ multimedia_notebook.rb
2185
+ playlist.rb
2186
+ play_video_from_my_collection.rb
2187
+ radio.rb
2188
+ sound_effect_widget.rb
2189
+ video_collection.rb
2190
+ video_editor.rb
2191
+
2192
+ If you want to start the simple_play_widget.rb on windows,
2193
+ you can do this:
2194
+
2195
+ multimedia_paradise --simple-play-widget
2196
+
2197
+ ### Usability of the GUI components that are part of the multimedia_paradise gem
2198
+
2199
+ I am experimenting right now, and not all GUI components may
2200
+ be very useful. Nonetheless, if other users are interested
2201
+ in GUIs, let me know what you think about the various ruby-gtk3
2202
+ components that are part of the multimedia_paradise project.
2203
+
2204
+ Many of them are incomplete or buggy, but some parts tend to
2205
+ work somewhat ok-ish. I am curious which parts of the GUI
2206
+ tools should be improved next or extended, and how. For this,
2207
+ feedback would be helpful and appreciated.
2208
+
2209
+ ### Play videos from my collection via ruby-gtk3
2210
+
2211
+ The example file at:
2212
+
2213
+ gui/gtk3/play_video_from_my_collection/play_video_from_my_collection.rb
2214
+
2215
+ Can be used to play video files from a .yml collection. This
2216
+ even has a search widget which can be triggered by hitting:
2217
+
2218
+ Ctrl+F
2219
+
2220
+ As key combination.
2221
+
2222
+ The .yml file is adjusted to my own use case and collection
2223
+ so it may be utterly useless for other people - but it shows
2224
+ you how this works, hence why this is bundled into this project
2225
+ as well. If you want your own dataset, simply arrange them
2226
+ accordingly and change that .yml file.
2227
+
2228
+ The yaml file is normally at:
2229
+
2230
+ multimedia_paradise/yaml/video_collection/video_collection.yml
2231
+
2232
+ ### class MultimediaParadise::GUI::Gtk::ChangeMetadataWidget
2233
+
2234
+ You can use class **MultimediaParadise::GUI::Gtk::ChangeMetadataWidget**
2235
+ to change the meta-data of video files.
2236
+
2237
+ This currently (February of 2021) looks like this via ruby-gtk3:
2238
+
2239
+ <img src="https://i.imgur.com/ZzAUIoP.png" style="margin: 1em">
2240
+
2241
+ Not very pretty, but I only wanted to show the basic functionality
2242
+ around this. Perhaps in the future this may be improved, but
2243
+ since this is mostly just a hobby and "throw-away" script please
2244
+ do not expect this to become really polished. I only wanted to
2245
+ showcase the functionality, then move on.
2246
+
2247
+ ### class MultimediaParadise::GUI::LibUI::CutMultimedia
2248
+
2249
+ This class can be used on windows, if you have ffmpeg installed,
2250
+ to cut audio files. You can download some windows binaries
2251
+ from the internet for this; I put ffmpeg.exe in /usr/bin/ -
2252
+ easier to remember for me, even on windows.
2253
+
2254
+ In <b>December 2022</b> I tested this functionality - and it
2255
+ works, on windows as well. \o/
2256
+
2257
+ This functionality that this GUI offers is not very advanced as
2258
+ of yet. At a later time this may be extended. For now (December
2259
+ 2022) it was more important to simply add this functionality.
2260
+
2261
+ ## Creating looping video files
2262
+
2263
+ ffmpeg allows us to create a <b>video playback loop</b> of a
2264
+ given video. Let's assume we have the file called <b>foobar.webm</b>.
2265
+ How to loop this video file, via ffmpeg?
2266
+
2267
+ ffmpeg -stream_loop 10 -i input_file_goes_here.webm -c copy foobar.webm
2268
+
2269
+ The above commandline example would loop the given video file
2270
+ 10 times. That is as if you were to play it 10 times in a
2271
+ row without delay.
2272
+
2273
+ As the above functionality seemed useful, it was added to the
2274
+ multimedia_paradise gem in January 2023.
2275
+
2276
+ Usage example:
2277
+
2278
+ MultimediaParadise.loop_this_video('input_file.webm', 10)
2279
+ MultimediaParadise.loop_this_video('input_file.webm', '10 times')
2280
+ MultimediaParadise.loop_this_video('input_file.webm', '10x')
2281
+
2282
+ The above is all synonymous, but the first variant is probably the
2283
+ easiest to use.
2284
+
2285
+ ## class MultimediaParadise::Video::SplitThisVideo
2286
+
2287
+ class MultimediaParadise::Video::SplitThisVideo was added in February
2288
+ 2023 to allow us to easily split a video file.
2289
+
2290
+ Usage example:
2291
+
2292
+ require 'multimedia_paradise/video/split_this_video.rb'
2293
+ MultimediaParadise::Video::SplitThisVideo.new(ARGV)
2294
+ MultimediaParadise::Video::SplitThisVideo.new('foobar.avi','00:23')
2295
+
2296
+ You need to pass the time in 24-hour notation for now. At a later time
2297
+ this restriction will be relaxed.
2298
+
2299
+ I aliased this to split_this_video on the commandline. Then I can do
2300
+ this from the commandline:
2301
+
2302
+ splitthisvideo foobar.mpg 00:00-21:39.40
2303
+
2304
+
2305
+ ## Contact information and mandatory 2FA coming up in 2022
2306
+
2307
+ If your creative mind has ideas and specific suggestions to make this gem
2308
+ more useful in general, feel free to drop me an email at any time, via:
2309
+
2310
+ shevy@inbox.lt
2311
+
2312
+ Before that email I used an email account at Google gmail, but in **2021** I
2313
+ decided to slowly abandon gmail, for various reasons. In order to limit the
2314
+ explanation here, allow me to just briefly state that I do not feel as if I
2315
+ want to promote any Google service anymore when the user becomes the
2316
+ product (such as via data collection by upstream services). I feel this is
2317
+ a hugely flawed business model.
2318
+
2319
+ Do keep in mind that responding to emails may take some time, depending on
2320
+ the amount of work I may have at that moment.
2321
+
2322
+ In <b>2022</b> rubygems.org, or rather the corporate overlords who control the
2323
+ rubygems.org infrastructure these days, decided to make 2FA mandatory for every
2324
+ gem owner eventually: see
2325
+ https://blog.rubygems.org/2022/06/13/making-packages-more-secure.html
2326
+
2327
+ Mandatory 2FA will eventually be extended to all rubygems.org developers and
2328
+ maintainers. As I can not use 2FA, for reasons I will skip explaining here,
2329
+ this means that my projects will eventually be taken over by shopify (or,
2330
+ correspondingly, whoever effectively controls the rubygems.org ecosystem).
2331
+ At that point, I no longer have any control what is done to my projects
2332
+ since shopify (respectively those controlling the gems ecosystem) took away
2333
+ control here. Not sure at which point ruby became corporate-controlled -
2334
+ that was not the case several years ago.
2335
+
2336
+ Ruby also only allows 2FA users to participate on the issue tracker these
2337
+ days:
2338
+
2339
+ https://bugs.ruby-lang.org/issues/18800
2340
+