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