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.
- checksums.yaml +7 -0
- data/README.md +2340 -0
- data/bin/audio_player +12 -0
- data/bin/auto_title +7 -0
- data/bin/convert_audio_to_mp4video_with_image +7 -0
- data/bin/cut_audio +7 -0
- data/bin/cut_multimedia +7 -0
- data/bin/extract_audio +7 -0
- data/bin/ffmpeg_merge +7 -0
- data/bin/file_duration +7 -0
- data/bin/gtk_radio +7 -0
- data/bin/loop_this_video +7 -0
- data/bin/merge_avi_files +7 -0
- data/bin/merge_mp3 +7 -0
- data/bin/missing_video_files +7 -0
- data/bin/movie_searcher +7 -0
- data/bin/mp3_to_opus +7 -0
- data/bin/mplayer_wrapper +7 -0
- data/bin/multimedia_information +11 -0
- data/bin/multimedia_paradise +9 -0
- data/bin/multimedia_paradise_sinatra +7 -0
- data/bin/play_random_simpsons_video +7 -0
- data/bin/playlist +7 -0
- data/bin/random_video +7 -0
- data/bin/remove_audio +9 -0
- data/bin/remove_last_second +7 -0
- data/bin/remove_subtitles +7 -0
- data/bin/tag_mp3_files +7 -0
- data/bin/to_aiff +10 -0
- data/bin/to_mp4 +7 -0
- data/bin/verbose_analyse_this_mp3_file_for_id3_tags +9 -0
- data/bin/video_codec +7 -0
- data/bin/video_information +8 -0
- data/bin/video_player +11 -0
- data/bin/video_to_images +7 -0
- data/bin/vp9 +9 -0
- data/bin/waveform +73 -0
- data/doc/CHANGELOG.md +44 -0
- data/doc/LINKS.md +6 -0
- data/doc/MOTIVATION_FOR_THIS_PROJECT.md +22 -0
- data/doc/MergingVideoLectures.md +12 -0
- data/doc/README.gen +2300 -0
- data/doc/Readme_for_the_cut_audio_component.md +168 -0
- data/doc/todo/todo_for_the_GUIs.md +0 -0
- data/doc/todo/todo_for_the_multimedia_paradise_project.md +111 -0
- data/lib/multimedia_paradise/audio/audio_player/audio_player.rb +83 -0
- data/lib/multimedia_paradise/audio/audio_player/constants.rb +136 -0
- data/lib/multimedia_paradise/audio/audio_player/menu.rb +164 -0
- data/lib/multimedia_paradise/audio/audio_player/misc.rb +718 -0
- data/lib/multimedia_paradise/audio/audio_player/reset.rb +77 -0
- data/lib/multimedia_paradise/audio/audio_player/tab.rb +35 -0
- data/lib/multimedia_paradise/audio/audio_tag_reader/README.md +7 -0
- data/lib/multimedia_paradise/audio/audio_tag_reader/audio_tag_reader.rb +503 -0
- data/lib/multimedia_paradise/audio/base.rb +67 -0
- data/lib/multimedia_paradise/audio/compress.rb +97 -0
- data/lib/multimedia_paradise/audio/create_m3u_playlist.rb +245 -0
- data/lib/multimedia_paradise/audio/extract_audio/constants.rb +37 -0
- data/lib/multimedia_paradise/audio/extract_audio/extract_audio.rb +417 -0
- data/lib/multimedia_paradise/audio/file_duration/constants.rb +53 -0
- data/lib/multimedia_paradise/audio/file_duration/file_duration.rb +602 -0
- data/lib/multimedia_paradise/audio/genres/boogie.rb +35 -0
- data/lib/multimedia_paradise/audio/genres/concerts.rb +35 -0
- data/lib/multimedia_paradise/audio/genres/constants.rb +53 -0
- data/lib/multimedia_paradise/audio/genres/eurodance.rb +35 -0
- data/lib/multimedia_paradise/audio/genres/genre.rb +696 -0
- data/lib/multimedia_paradise/audio/genres/hip_hop.rb +35 -0
- data/lib/multimedia_paradise/audio/genres/italian_songs.rb +35 -0
- data/lib/multimedia_paradise/audio/genres/the_1980s.rb +35 -0
- data/lib/multimedia_paradise/audio/genres/trance.rb +35 -0
- data/lib/multimedia_paradise/audio/lyrics_fetcher.rb +238 -0
- data/lib/multimedia_paradise/audio/merge_audio_files.rb +136 -0
- data/lib/multimedia_paradise/audio/modify_year_of_audio_file.rb +151 -0
- data/lib/multimedia_paradise/audio/n_audio_songs.rb +216 -0
- data/lib/multimedia_paradise/audio/play_all_audio_files.rb +122 -0
- data/lib/multimedia_paradise/audio/playlist/playlist.rb +1559 -0
- data/lib/multimedia_paradise/audio/remove_audio.rb +98 -0
- data/lib/multimedia_paradise/audio/remove_last_second.rb +83 -0
- data/lib/multimedia_paradise/audio/report_missing_id.rb +139 -0
- data/lib/multimedia_paradise/audio/streamripper/constants.rb +51 -0
- data/lib/multimedia_paradise/audio/streamripper/streamripper_wrapper.rb +279 -0
- data/lib/multimedia_paradise/audio/to_mp3.rb +138 -0
- data/lib/multimedia_paradise/audio/to_ogg.rb +104 -0
- data/lib/multimedia_paradise/audio/wav_to_mp3.rb +87 -0
- data/lib/multimedia_paradise/audio/waveform/class.rb +341 -0
- data/lib/multimedia_paradise/audio/waveform/constants.rb +38 -0
- data/lib/multimedia_paradise/audio/waveform/log.rb +101 -0
- data/lib/multimedia_paradise/autoinclude.rb +3 -0
- data/lib/multimedia_paradise/autoinclude_remove_audio.rb +6 -0
- data/lib/multimedia_paradise/base/base.rb +34 -0
- data/lib/multimedia_paradise/base/colours.rb +354 -0
- data/lib/multimedia_paradise/base/commandline_arguments.rb +52 -0
- data/lib/multimedia_paradise/base/constants.rb +19 -0
- data/lib/multimedia_paradise/base/encoding.rb +31 -0
- data/lib/multimedia_paradise/base/misc.rb +618 -0
- data/lib/multimedia_paradise/base/namespace.rb +36 -0
- data/lib/multimedia_paradise/base/time.rb +25 -0
- data/lib/multimedia_paradise/colours/colours.rb +82 -0
- data/lib/multimedia_paradise/commandline/menu.rb +498 -0
- data/lib/multimedia_paradise/configuration/play_zoomed.yml +1 -0
- data/lib/multimedia_paradise/constants/constants.rb +23 -0
- data/lib/multimedia_paradise/constants/conversions.rb +62 -0
- data/lib/multimedia_paradise/constants/directory_constants.rb +133 -0
- data/lib/multimedia_paradise/constants/encodings.rb +26 -0
- data/lib/multimedia_paradise/constants/file_constants.rb +171 -0
- data/lib/multimedia_paradise/constants/misc.rb +80 -0
- data/lib/multimedia_paradise/constants/my_video_directory.rb +30 -0
- data/lib/multimedia_paradise/constants/namespace.rb +14 -0
- data/lib/multimedia_paradise/constants/newline.rb +14 -0
- data/lib/multimedia_paradise/constants/video_filetypes.rb +27 -0
- data/lib/multimedia_paradise/constants/web_constants.rb +150 -0
- data/lib/multimedia_paradise/conversions/README.md +2 -0
- data/lib/multimedia_paradise/conversions/conversions.rb +930 -0
- data/lib/multimedia_paradise/css/project.css +15 -0
- data/lib/multimedia_paradise/data/asoundrc +12 -0
- data/lib/multimedia_paradise/ffmpeg/README.md +2 -0
- data/lib/multimedia_paradise/ffmpeg/ffmpeg.rb +620 -0
- data/lib/multimedia_paradise/gui/fox/play_from_radio_station.rb +75 -0
- data/lib/multimedia_paradise/gui/gosu/video_player/video_player.rb +109 -0
- data/lib/multimedia_paradise/gui/gtk2/lyrics/lyrics.rb +33 -0
- data/lib/multimedia_paradise/gui/gtk2/multimedia_converter/multimedia_converter.rb +33 -0
- data/lib/multimedia_paradise/gui/gtk2/notebook.rb +144 -0
- data/lib/multimedia_paradise/gui/gtk2/play_video_from_my_collection/play_video_from_my_collection.rb +43 -0
- data/lib/multimedia_paradise/gui/gtk2/simple_play_widget/README.md +12 -0
- data/lib/multimedia_paradise/gui/gtk2/simple_play_widget/simple_play_widget.rb +40 -0
- data/lib/multimedia_paradise/gui/gtk2/video_collection/video_collection.rb +56 -0
- data/lib/multimedia_paradise/gui/gtk2/widget_increase_or_decrease_audio/widget_increase_or_decrease_audio.rb +42 -0
- data/lib/multimedia_paradise/gui/gtk2/youtube_downloader/youtube_downloader.rb +32 -0
- data/lib/multimedia_paradise/gui/gtk3/change_metadata_widget/README.md +3 -0
- data/lib/multimedia_paradise/gui/gtk3/change_metadata_widget/change_metadata_widget.rb +150 -0
- data/lib/multimedia_paradise/gui/gtk3/cut_multimedia/cut_multimedia.rb +321 -0
- data/lib/multimedia_paradise/gui/gtk3/information_about_a_mp3_file/information_about_a_mp3_file.rb +421 -0
- data/lib/multimedia_paradise/gui/gtk3/lyrics/lyrics.rb +33 -0
- data/lib/multimedia_paradise/gui/gtk3/multimedia_converter/multimedia_converter.rb +34 -0
- data/lib/multimedia_paradise/gui/gtk3/multimedia_notebook/multimedia_notebook.rb +34 -0
- data/lib/multimedia_paradise/gui/gtk3/play_video_from_my_collection/play_video_from_my_collection.rb +34 -0
- data/lib/multimedia_paradise/gui/gtk3/playlist/playlist.rb +34 -0
- data/lib/multimedia_paradise/gui/gtk3/radio/misc.rb +487 -0
- data/lib/multimedia_paradise/gui/gtk3/radio/radio.rb +698 -0
- data/lib/multimedia_paradise/gui/gtk3/simple_play_widget/simple_play_widget.rb +38 -0
- data/lib/multimedia_paradise/gui/gtk3/sound_effect_widget/sound_effect_widget.rb +34 -0
- data/lib/multimedia_paradise/gui/gtk3/tag_mp3_files/connect_skeleton.rb +61 -0
- data/lib/multimedia_paradise/gui/gtk3/tag_mp3_files/create.rb +405 -0
- data/lib/multimedia_paradise/gui/gtk3/tag_mp3_files/misc.rb +1820 -0
- data/lib/multimedia_paradise/gui/gtk3/tag_mp3_files/tag_mp3_files.config +6 -0
- data/lib/multimedia_paradise/gui/gtk3/tag_mp3_files/tag_mp3_files.rb +66 -0
- data/lib/multimedia_paradise/gui/gtk3/video_collection/video_collection.rb +43 -0
- data/lib/multimedia_paradise/gui/gtk3/video_editor/video_editor.rb +34 -0
- data/lib/multimedia_paradise/gui/gtk3/video_player/video_player.rb +34 -0
- data/lib/multimedia_paradise/gui/gtk3/webcam_widget/webcam_widget.rb +425 -0
- data/lib/multimedia_paradise/gui/gtk3/widget_increase_or_decrease_audio/widget_increase_or_decrease_audio.rb +36 -0
- data/lib/multimedia_paradise/gui/gtk3/youtube_channels/youtube_channels.rb +210 -0
- data/lib/multimedia_paradise/gui/gtk3/youtube_downloader/youtube_downloader.rb +32 -0
- data/lib/multimedia_paradise/gui/gui_base.rb +92 -0
- data/lib/multimedia_paradise/gui/libui/change_metadata_widget/change_metadata_widget.rb +115 -0
- data/lib/multimedia_paradise/gui/libui/cut_multimedia/cut_multimedia.rb +119 -0
- data/lib/multimedia_paradise/gui/libui/lyrics/lyrics.rb +67 -0
- data/lib/multimedia_paradise/gui/libui/simple_play_widget/simple_play_widget.rb +119 -0
- data/lib/multimedia_paradise/gui/libui/tag_mp3_files/tag_mp3_files.rb +268 -0
- data/lib/multimedia_paradise/gui/libui/video_player/video_player.rb +81 -0
- data/lib/multimedia_paradise/gui/libui/widget_increase_or_decrease_audio/widget_increase_or_decrease_audio.rb +126 -0
- data/lib/multimedia_paradise/gui/libui/youtube_channels/youtube_channels.rb +116 -0
- data/lib/multimedia_paradise/gui/libui/youtube_downloader/youtube_downloader.rb +107 -0
- data/lib/multimedia_paradise/gui/shared_code/change_metadata_widget/change_metadata_widget_module.rb +538 -0
- data/lib/multimedia_paradise/gui/shared_code/cut_multimedia/cut_multimedia_module.rb +268 -0
- data/lib/multimedia_paradise/gui/shared_code/information_about_a_mp3_file/information_about_a_mp3_file_module.rb +120 -0
- data/lib/multimedia_paradise/gui/shared_code/lyrics/lyrics_module.rb +141 -0
- data/lib/multimedia_paradise/gui/shared_code/multimedia_converter/multimedia_converter_module.rb +478 -0
- data/lib/multimedia_paradise/gui/shared_code/multimedia_notebook/multimedia_notebook_module.rb +171 -0
- data/lib/multimedia_paradise/gui/shared_code/play_video_from_my_collection/play_video_from_my_collection_module.rb +464 -0
- data/lib/multimedia_paradise/gui/shared_code/playlist/playlist_module.rb +151 -0
- data/lib/multimedia_paradise/gui/shared_code/simple_play_widget/simple_play_widget_module.rb +257 -0
- data/lib/multimedia_paradise/gui/shared_code/sound_effect_widget/sound_effect_widget_module.rb +173 -0
- data/lib/multimedia_paradise/gui/shared_code/tag_mp3_files/tag_mp3_files_module.rb +73 -0
- data/lib/multimedia_paradise/gui/shared_code/video_editor/video_editor_module.rb +287 -0
- data/lib/multimedia_paradise/gui/shared_code/video_player/video_player_module.rb +185 -0
- data/lib/multimedia_paradise/gui/shared_code/widget_increase_or_decrease_audio/widget_increase_or_decrease_audio_module.rb +310 -0
- data/lib/multimedia_paradise/gui/shared_code/youtube_downloader/youtube_downloader_module.rb +339 -0
- data/lib/multimedia_paradise/gui/tk/tk_multimedia_wrapper.rb +60 -0
- data/lib/multimedia_paradise/help/help.rb +75 -0
- data/lib/multimedia_paradise/images/MULTIMEDIA.jpg +0 -0
- data/lib/multimedia_paradise/images/MULTIMEDIA_PARADISE_ID_TAG_GUI_IN_RUBY_GTK3.png +0 -0
- data/lib/multimedia_paradise/images/MULTIMEDIA_PARADISE_LOGO.png +0 -0
- data/lib/multimedia_paradise/images/UK_flag.png +0 -0
- data/lib/multimedia_paradise/images/US_flag.png +0 -0
- data/lib/multimedia_paradise/images/austrian_flag.png +0 -0
- data/lib/multimedia_paradise/images/french_flag.png +0 -0
- data/lib/multimedia_paradise/images/german_flag.png +0 -0
- data/lib/multimedia_paradise/images/radio_image.png +0 -0
- data/lib/multimedia_paradise/images/trance.png +0 -0
- data/lib/multimedia_paradise/java/AudioPlayer.class +0 -0
- data/lib/multimedia_paradise/java/AudioPlayer.java +103 -0
- data/lib/multimedia_paradise/java/README.md +3 -0
- data/lib/multimedia_paradise/misc/long_format_to_milliseconds_converter.rb +182 -0
- data/lib/multimedia_paradise/misc/milliseconds_to_long_format_converter.rb +186 -0
- data/lib/multimedia_paradise/multimedia/analyse_multimedia_file.rb +180 -0
- data/lib/multimedia_paradise/multimedia/avisynth/README.md +4 -0
- data/lib/multimedia_paradise/multimedia/avisynth/avisynth_code.avs +471 -0
- data/lib/multimedia_paradise/multimedia/base.rb +60 -0
- data/lib/multimedia_paradise/multimedia/chord.rb +174 -0
- data/lib/multimedia_paradise/multimedia/convert_audio_to_video_with_image.rb +171 -0
- data/lib/multimedia_paradise/multimedia/cut_multimedia/10_minutes_chop.rb +29 -0
- data/lib/multimedia_paradise/multimedia/cut_multimedia/15_minutes_chop.rb +29 -0
- data/lib/multimedia_paradise/multimedia/cut_multimedia/30_minutes_chop.rb +29 -0
- data/lib/multimedia_paradise/multimedia/cut_multimedia/5_minutes_chop.rb +29 -0
- data/lib/multimedia_paradise/multimedia/cut_multimedia/cut_multimedia.rb +2017 -0
- data/lib/multimedia_paradise/multimedia/cut_multimedia/evaluate_from_this_file.rb +79 -0
- data/lib/multimedia_paradise/multimedia/cut_multimedia/interactive_menu.rb +514 -0
- data/lib/multimedia_paradise/multimedia/interactive_shell.rb +84 -0
- data/lib/multimedia_paradise/multimedia/merge_multimedia.rb +125 -0
- data/lib/multimedia_paradise/multimedia/note.rb +500 -0
- data/lib/multimedia_paradise/multimedia/play_from_this_list.rb +163 -0
- data/lib/multimedia_paradise/multimedia/read_meta_tags.rb +173 -0
- data/lib/multimedia_paradise/multimedia/simulate_youtube_playlist.rb +209 -0
- data/lib/multimedia_paradise/multimedia/start_length_duration.rb +205 -0
- data/lib/multimedia_paradise/multimedia/video_downloader/video_downloader.rb +143 -0
- data/lib/multimedia_paradise/project/project.rb +47 -0
- data/lib/multimedia_paradise/requires/require_audio_files.rb +74 -0
- data/lib/multimedia_paradise/requires/require_cut_multimedia.rb +7 -0
- data/lib/multimedia_paradise/requires/require_extract_audio.rb +7 -0
- data/lib/multimedia_paradise/requires/require_file_duration.rb +7 -0
- data/lib/multimedia_paradise/requires/require_streamripper.rb +7 -0
- data/lib/multimedia_paradise/requires/require_the_audio_player.rb +7 -0
- data/lib/multimedia_paradise/requires/require_the_multimedia_paradise_project.rb +38 -0
- data/lib/multimedia_paradise/requires/require_the_sinatra_components.rb +7 -0
- data/lib/multimedia_paradise/requires/require_toplevel_methods_files.rb +25 -0
- data/lib/multimedia_paradise/requires/require_video_files.rb +25 -0
- data/lib/multimedia_paradise/requires/require_video_player.rb +7 -0
- data/lib/multimedia_paradise/sinatra/app.rb +311 -0
- data/lib/multimedia_paradise/sinatra/embeddable_interface.rb +379 -0
- data/lib/multimedia_paradise/sound_effects/README.md +12 -0
- data/lib/multimedia_paradise/sound_effects/cat_meow.mp3 +0 -0
- data/lib/multimedia_paradise/sound_effects/channel_opened.mp3 +0 -0
- data/lib/multimedia_paradise/sound_effects/phone_ring.mp3 +0 -0
- data/lib/multimedia_paradise/statistics/README.md +5 -0
- data/lib/multimedia_paradise/statistics/video.rb +84 -0
- data/lib/multimedia_paradise/toplevel_cut_audio.rb +16 -0
- data/lib/multimedia_paradise/toplevel_methods/analyze_audio_stream.rb +31 -0
- data/lib/multimedia_paradise/toplevel_methods/chop_into_segments_of_n_seconds_size.rb +32 -0
- data/lib/multimedia_paradise/toplevel_methods/chop_off_first_five_minutes.rb +22 -0
- data/lib/multimedia_paradise/toplevel_methods/chop_off_first_n_seconds.rb +92 -0
- data/lib/multimedia_paradise/toplevel_methods/chop_off_first_ten_minutes.rb +22 -0
- data/lib/multimedia_paradise/toplevel_methods/chop_off_first_two_minutes.rb +24 -0
- data/lib/multimedia_paradise/toplevel_methods/codecs.rb +50 -0
- data/lib/multimedia_paradise/toplevel_methods/copy_and_merge_this_video_n_times.rb +51 -0
- data/lib/multimedia_paradise/toplevel_methods/copy_file.rb +18 -0
- data/lib/multimedia_paradise/toplevel_methods/create_video_from_this_audio.rb +65 -0
- data/lib/multimedia_paradise/toplevel_methods/cut_from_to.rb +156 -0
- data/lib/multimedia_paradise/toplevel_methods/delay_audio.rb +31 -0
- data/lib/multimedia_paradise/toplevel_methods/denoise.rb +90 -0
- data/lib/multimedia_paradise/toplevel_methods/deshake.rb +43 -0
- data/lib/multimedia_paradise/toplevel_methods/e.rb +16 -0
- data/lib/multimedia_paradise/toplevel_methods/encode_this_video.rb +49 -0
- data/lib/multimedia_paradise/toplevel_methods/ensure_that_the_output_directory_exists.rb +27 -0
- data/lib/multimedia_paradise/toplevel_methods/esystem.rb +43 -0
- data/lib/multimedia_paradise/toplevel_methods/files_and_directories.rb +90 -0
- data/lib/multimedia_paradise/toplevel_methods/flip_and_rotate.rb +58 -0
- data/lib/multimedia_paradise/toplevel_methods/increase_volume_of_this_audio_file.rb +61 -0
- data/lib/multimedia_paradise/toplevel_methods/is_a_multimedia_file.rb +27 -0
- data/lib/multimedia_paradise/toplevel_methods/is_audio_file.rb +27 -0
- data/lib/multimedia_paradise/toplevel_methods/is_image_file.rb +31 -0
- data/lib/multimedia_paradise/toplevel_methods/is_on_roebe.rb +17 -0
- data/lib/multimedia_paradise/toplevel_methods/is_video_file.rb +62 -0
- data/lib/multimedia_paradise/toplevel_methods/merge_multimedia_file.rb +327 -0
- data/lib/multimedia_paradise/toplevel_methods/merge_these_videos.rb +105 -0
- data/lib/multimedia_paradise/toplevel_methods/misc.rb +885 -0
- data/lib/multimedia_paradise/toplevel_methods/n_local_videos.rb +56 -0
- data/lib/multimedia_paradise/toplevel_methods/opn.rb +24 -0
- data/lib/multimedia_paradise/toplevel_methods/output_directory.rb +59 -0
- data/lib/multimedia_paradise/toplevel_methods/player_in_use.rb +80 -0
- data/lib/multimedia_paradise/toplevel_methods/query_the_audio_codec_of_this_file.rb +24 -0
- data/lib/multimedia_paradise/toplevel_methods/radio.rb +360 -0
- data/lib/multimedia_paradise/toplevel_methods/rds.rb +24 -0
- data/lib/multimedia_paradise/toplevel_methods/return_all_video_files.rb +64 -0
- data/lib/multimedia_paradise/toplevel_methods/return_data_from_video_collection_file_for_this_entry.rb +38 -0
- data/lib/multimedia_paradise/toplevel_methods/return_duration_of_this_multimedia_file.rb +27 -0
- data/lib/multimedia_paradise/toplevel_methods/return_full_name_for_video_at_this_position.rb +54 -0
- data/lib/multimedia_paradise/toplevel_methods/return_path_to_random_simpsons_video_file.rb +43 -0
- data/lib/multimedia_paradise/toplevel_methods/return_random_video_file_from_the_video_collection.rb +73 -0
- data/lib/multimedia_paradise/toplevel_methods/return_screen_resolution.rb +24 -0
- data/lib/multimedia_paradise/toplevel_methods/run_sys_command.rb +30 -0
- data/lib/multimedia_paradise/toplevel_methods/scale_video.rb +27 -0
- data/lib/multimedia_paradise/toplevel_methods/set_title_of.rb +65 -0
- data/lib/multimedia_paradise/toplevel_methods/slow_down_this_video_file.rb +33 -0
- data/lib/multimedia_paradise/toplevel_methods/start_screencast.rb +70 -0
- data/lib/multimedia_paradise/toplevel_methods/subtitles.rb +59 -0
- data/lib/multimedia_paradise/toplevel_methods/to_flac.rb +30 -0
- data/lib/multimedia_paradise/toplevel_methods/to_mp4.rb +24 -0
- data/lib/multimedia_paradise/toplevel_methods/total_duration.rb +35 -0
- data/lib/multimedia_paradise/toplevel_methods/use_lame_codec.rb +32 -0
- data/lib/multimedia_paradise/toplevel_methods/video_dataset.rb +76 -0
- data/lib/multimedia_paradise/version/version.rb +28 -0
- data/lib/multimedia_paradise/video/all_videos.rb +101 -0
- data/lib/multimedia_paradise/video/capture_screen.rb +285 -0
- data/lib/multimedia_paradise/video/check_numbers.rb +215 -0
- data/lib/multimedia_paradise/video/columbo/columbo.rb +139 -0
- data/lib/multimedia_paradise/video/copy_missing_video_files.rb +293 -0
- data/lib/multimedia_paradise/video/copy_random_video.rb +98 -0
- data/lib/multimedia_paradise/video/correct_video_numbers.rb +278 -0
- data/lib/multimedia_paradise/video/create_dvd.rb +50 -0
- data/lib/multimedia_paradise/video/encode_video.rb +81 -0
- data/lib/multimedia_paradise/video/ffmpeg_options.rb +156 -0
- data/lib/multimedia_paradise/video/find_video/constants.rb +23 -0
- data/lib/multimedia_paradise/video/find_video/find_video.rb +493 -0
- data/lib/multimedia_paradise/video/fix_married_with_children_videos.rb +70 -0
- data/lib/multimedia_paradise/video/guess_video_name.rb +189 -0
- data/lib/multimedia_paradise/video/imdb_rating/imdb_rating.rb +141 -0
- data/lib/multimedia_paradise/video/mike_hammer/mike_hammer.rb +74 -0
- data/lib/multimedia_paradise/video/missing_video_files/missing_video_files.rb +286 -0
- data/lib/multimedia_paradise/video/movie_searcher.rb +281 -0
- data/lib/multimedia_paradise/video/mplayer_wrapper.rb +504 -0
- data/lib/multimedia_paradise/video/play_random_file.rb +91 -0
- data/lib/multimedia_paradise/video/play_random_realvideo.rb +87 -0
- data/lib/multimedia_paradise/video/prepare_video_lecture.rb +272 -0
- data/lib/multimedia_paradise/video/random_video.rb +310 -0
- data/lib/multimedia_paradise/video/registered_video_file.rb +131 -0
- data/lib/multimedia_paradise/video/remove_metadata.rb +52 -0
- data/lib/multimedia_paradise/video/rename_video_file.rb +149 -0
- data/lib/multimedia_paradise/video/report_local_videos.rb +106 -0
- data/lib/multimedia_paradise/video/report_missing_videos_in_the_yaml_file.rb +107 -0
- data/lib/multimedia_paradise/video/resolution.rb +159 -0
- data/lib/multimedia_paradise/video/simpsons.rb +129 -0
- data/lib/multimedia_paradise/video/speed_up_video.rb +135 -0
- data/lib/multimedia_paradise/video/split_this_video.rb +126 -0
- data/lib/multimedia_paradise/video/srt_regex.rb +211 -0
- data/lib/multimedia_paradise/video/store_available_video_files.rb +138 -0
- data/lib/multimedia_paradise/video/the_simpsons/README.md +9 -0
- data/lib/multimedia_paradise/video/the_simpsons/good_the_simpsons_episodes.rb +107 -0
- data/lib/multimedia_paradise/video/the_simpsons/the_simpsons.rb +82 -0
- data/lib/multimedia_paradise/video/video.rb +14 -0
- data/lib/multimedia_paradise/video/video_encoding_settings.rb +57 -0
- data/lib/multimedia_paradise/video/video_genres.rb +337 -0
- data/lib/multimedia_paradise/video/video_information.rb +443 -0
- data/lib/multimedia_paradise/video/video_metadata.rb +132 -0
- data/lib/multimedia_paradise/video/video_player.rb +581 -0
- data/lib/multimedia_paradise/video/video_renamer.rb +160 -0
- data/lib/multimedia_paradise/video/watermark.rb +290 -0
- data/lib/multimedia_paradise/video/youtube/youtube.rb +17 -0
- data/lib/multimedia_paradise/video/youtube_embedder.rb +235 -0
- data/lib/multimedia_paradise/www/GIS/GIS.cgi +147 -0
- data/lib/multimedia_paradise/www/HDMI/HDMI.cgi +34 -0
- data/lib/multimedia_paradise/www/TALES_FROM_THE_CRYPT.html +71 -0
- data/lib/multimedia_paradise/www/alsa/alsa.cgi +7 -0
- data/lib/multimedia_paradise/www/alsa/alsa.rb +309 -0
- data/lib/multimedia_paradise/www/alsa/alsa.sinatra +56 -0
- data/lib/multimedia_paradise/www/audacity.cgi +30 -0
- data/lib/multimedia_paradise/www/audio/audio.cgi +9 -0
- data/lib/multimedia_paradise/www/audio/audio.rb +2739 -0
- data/lib/multimedia_paradise/www/audio/audio.sinatra +56 -0
- data/lib/multimedia_paradise/www/avisynth/avisynth.cgi +172 -0
- data/lib/multimedia_paradise/www/best_voices/best_voices.cgi +60 -0
- data/lib/multimedia_paradise/www/cassette/cassette.cgi +723 -0
- data/lib/multimedia_paradise/www/codecs/codecs.cgi +95 -0
- data/lib/multimedia_paradise/www/componists/vivaldi.cgi +218 -0
- data/lib/multimedia_paradise/www/decibel.cgi +79 -0
- data/lib/multimedia_paradise/www/ffmpeg/ffmpeg.cgi +439 -0
- data/lib/multimedia_paradise/www/lame/lame.cgi +7 -0
- data/lib/multimedia_paradise/www/lame/lame.rb +101 -0
- data/lib/multimedia_paradise/www/lame/lame.sinatra +56 -0
- data/lib/multimedia_paradise/www/lilypond.cgi +96 -0
- data/lib/multimedia_paradise/www/lyrics/lyrics.cgi +49 -0
- data/lib/multimedia_paradise/www/midi/al_adagi.mid +0 -0
- data/lib/multimedia_paradise/www/play_songs.cgi +102 -0
- data/lib/multimedia_paradise/www/play_this_video_file.cgi +100 -0
- data/lib/multimedia_paradise/www/pulseaudio/pulseaudio.cgi +7 -0
- data/lib/multimedia_paradise/www/pulseaudio/pulseaudio.rb +168 -0
- data/lib/multimedia_paradise/www/pulseaudio/pulseaudio.sinatra +56 -0
- data/lib/multimedia_paradise/www/rhythmbox/rhythmbox.cgi +120 -0
- data/lib/multimedia_paradise/www/sound_theory.cgi +163 -0
- data/lib/multimedia_paradise/www/tv/tv.cgi +182 -0
- data/lib/multimedia_paradise/www/video/video.cgi +7 -0
- data/lib/multimedia_paradise/www/video/video.rb +7709 -0
- data/lib/multimedia_paradise/www/video/video.sinatra +52 -0
- data/lib/multimedia_paradise/www/web_streams.cgi +58 -0
- data/lib/multimedia_paradise/yaml/audio_formats.yml +14 -0
- data/lib/multimedia_paradise/yaml/best_songs_in_an_era/eurodance/top20.yml +28 -0
- data/lib/multimedia_paradise/yaml/game_shows/ruck_zuck/ruck_zuck.yml +25 -0
- data/lib/multimedia_paradise/yaml/genres/1980s.yml +198 -0
- data/lib/multimedia_paradise/yaml/genres/README.md +5 -0
- data/lib/multimedia_paradise/yaml/genres/boogie.yml +68 -0
- data/lib/multimedia_paradise/yaml/genres/concerts.yml +29 -0
- data/lib/multimedia_paradise/yaml/genres/eurodance.yml +456 -0
- data/lib/multimedia_paradise/yaml/genres/hip_hop.yml +49 -0
- data/lib/multimedia_paradise/yaml/genres/italian_songs.yml +53 -0
- data/lib/multimedia_paradise/yaml/genres/trance.yml +167 -0
- data/lib/multimedia_paradise/yaml/good_horror_movies/good_horror_movies.yml +12 -0
- data/lib/multimedia_paradise/yaml/good_movie_actors/good_movie_actors.yml +6 -0
- data/lib/multimedia_paradise/yaml/image_formats.yml +8 -0
- data/lib/multimedia_paradise/yaml/internal/README.md +2 -0
- data/lib/multimedia_paradise/yaml/internal/installed_binaries.yml +31 -0
- data/lib/multimedia_paradise/yaml/lyrics.yml +6275 -0
- data/lib/multimedia_paradise/yaml/movie_reviews/the_hateful_eight_september_2016.md +305 -0
- data/lib/multimedia_paradise/yaml/music_genres.yml +51 -0
- data/lib/multimedia_paradise/yaml/playlist.yml +127 -0
- data/lib/multimedia_paradise/yaml/radio/README.md +5 -0
- data/lib/multimedia_paradise/yaml/radio/radio_stations.yml +359 -0
- data/lib/multimedia_paradise/yaml/song_tags.yml +815 -0
- data/lib/multimedia_paradise/yaml/tales_from_the_crypt/tales_from_the_crypt.yml +418 -0
- data/lib/multimedia_paradise/yaml/tom_and_jerry/README.md +2 -0
- data/lib/multimedia_paradise/yaml/tom_and_jerry/tom_and_jerry_episodes.yml +27 -0
- data/lib/multimedia_paradise/yaml/tv_channels/tv_channels.yml +46 -0
- data/lib/multimedia_paradise/yaml/use_this_video_player.yml +1 -0
- data/lib/multimedia_paradise/yaml/video/video.yml +26 -0
- data/lib/multimedia_paradise/yaml/video_collection/video_collection.yml +1933 -0
- data/lib/multimedia_paradise/yaml/video_encoding_settings.yml +62 -0
- data/lib/multimedia_paradise/yaml/video_filter_aliases.yml +221 -0
- data/lib/multimedia_paradise/yaml/youtube/alltagsgeschichte/alltagsgeschichte.yml +172 -0
- data/lib/multimedia_paradise/yaml/youtube/songs/README.md +3 -0
- data/lib/multimedia_paradise/yaml/youtube/songs/songs.yml +6 -0
- data/lib/multimedia_paradise/yaml/youtube_playlist/youtube_playlist.yml +6 -0
- data/lib/multimedia_paradise.rb +5 -0
- data/multimedia_paradise.gemspec +76 -0
- data/test/testing_audio_player.rb +15 -0
- data/test/testing_ffmpeg_options.rb +14 -0
- data/test/testing_file_duration.rb +17 -0
- data/test/testing_modify_year_of_audio_file.rb +14 -0
- data/test/testing_multimedia_paradise_project.rb +151 -0
- 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
|