multimedia_paradise 1.1.97
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 +1177 -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 +9 -0
- data/bin/extract_audio +7 -0
- data/bin/file_duration +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/play_random_simpsons_video +7 -0
- data/bin/playlist +20 -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/to_mp4 +7 -0
- data/bin/video_information +8 -0
- data/bin/video_player +11 -0
- data/bin/video_to_images +7 -0
- data/bin/waveform +73 -0
- data/doc/CHANGELOG.md +40 -0
- data/doc/LINKS.md +6 -0
- data/doc/MOTIVATION.md +15 -0
- data/doc/MULTIMEDIA_PARADISE.cgi +65 -0
- data/doc/MergingVideoLectures.md +12 -0
- data/doc/README.gen +1160 -0
- data/doc/Readme_for_the_cut_audio_component.md +168 -0
- data/doc/TODO.md +82 -0
- data/lib/multimedia_paradise.rb +5 -0
- data/lib/multimedia_paradise/audio/audio_player/audio_player.rb +685 -0
- data/lib/multimedia_paradise/audio/audio_player/constants.rb +121 -0
- data/lib/multimedia_paradise/audio/audio_player/menu.rb +138 -0
- data/lib/multimedia_paradise/audio/audio_player/reset.rb +59 -0
- data/lib/multimedia_paradise/audio/audio_player/tab.rb +33 -0
- data/lib/multimedia_paradise/audio/base.rb +66 -0
- data/lib/multimedia_paradise/audio/compress.rb +92 -0
- data/lib/multimedia_paradise/audio/create_m3u_playlist.rb +244 -0
- data/lib/multimedia_paradise/audio/cut_audio/10_minutes_chop.rb +27 -0
- data/lib/multimedia_paradise/audio/cut_audio/15_minutes_chop.rb +27 -0
- data/lib/multimedia_paradise/audio/cut_audio/30_minutes_chop.rb +34 -0
- data/lib/multimedia_paradise/audio/cut_audio/5_minutes_chop.rb +27 -0
- data/lib/multimedia_paradise/audio/cut_audio/chop.rb +100 -0
- data/lib/multimedia_paradise/audio/cut_audio/class.rb +70 -0
- data/lib/multimedia_paradise/audio/cut_audio/class_methods.rb +49 -0
- data/lib/multimedia_paradise/audio/cut_audio/constants.rb +87 -0
- data/lib/multimedia_paradise/audio/cut_audio/help.rb +46 -0
- data/lib/multimedia_paradise/audio/cut_audio/initialize.rb +49 -0
- data/lib/multimedia_paradise/audio/cut_audio/intersect.rb +86 -0
- data/lib/multimedia_paradise/audio/cut_audio/menu.rb +396 -0
- data/lib/multimedia_paradise/audio/cut_audio/misc.rb +1071 -0
- data/lib/multimedia_paradise/audio/cut_audio/report_and_feedback.rb +233 -0
- data/lib/multimedia_paradise/audio/cut_audio/reset.rb +72 -0
- data/lib/multimedia_paradise/audio/cut_audio/run.rb +25 -0
- data/lib/multimedia_paradise/audio/cut_audio/start_position.rb +72 -0
- data/lib/multimedia_paradise/audio/extract_audio/constants.rb +37 -0
- data/lib/multimedia_paradise/audio/extract_audio/extract_audio.rb +379 -0
- data/lib/multimedia_paradise/audio/file_duration/constants.rb +53 -0
- data/lib/multimedia_paradise/audio/file_duration/file_duration.rb +553 -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 +242 -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/add.rb +72 -0
- data/lib/multimedia_paradise/audio/playlist/constants.rb +75 -0
- data/lib/multimedia_paradise/audio/playlist/help.rb +84 -0
- data/lib/multimedia_paradise/audio/playlist/initialize.rb +41 -0
- data/lib/multimedia_paradise/audio/playlist/menu.rb +295 -0
- data/lib/multimedia_paradise/audio/playlist/playlist.rb +837 -0
- data/lib/multimedia_paradise/audio/playlist/reset.rb +36 -0
- data/lib/multimedia_paradise/audio/playlist/show.rb +47 -0
- data/lib/multimedia_paradise/audio/remove_audio.rb +79 -0
- data/lib/multimedia_paradise/audio/remove_last_second.rb +83 -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 +140 -0
- data/lib/multimedia_paradise/audio/to_ogg.rb +104 -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 +291 -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 +492 -0
- data/lib/multimedia_paradise/base/namespace.rb +16 -0
- data/lib/multimedia_paradise/colours/colours.rb +82 -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 +120 -0
- data/lib/multimedia_paradise/constants/encodings.rb +26 -0
- data/lib/multimedia_paradise/constants/file_constants.rb +144 -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 +56 -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 +566 -0
- data/lib/multimedia_paradise/gui/fox/play_from_radio_station.rb +75 -0
- data/lib/multimedia_paradise/gui/gtk/multimedia_converter.rb +390 -0
- data/lib/multimedia_paradise/gui/gtk/notebook.rb +128 -0
- data/lib/multimedia_paradise/gui/gtk/play_video_from_my_collection.rb +302 -0
- data/lib/multimedia_paradise/gui/gtk/radio/buttons.rb +177 -0
- data/lib/multimedia_paradise/gui/gtk/radio/constants.rb +57 -0
- data/lib/multimedia_paradise/gui/gtk/radio/initialize.rb +28 -0
- data/lib/multimedia_paradise/gui/gtk/radio/misc.rb +406 -0
- data/lib/multimedia_paradise/gui/gtk/radio/play_from_radio_station.rb +63 -0
- data/lib/multimedia_paradise/gui/gtk/radio/reset.rb +62 -0
- data/lib/multimedia_paradise/gui/gtk/radio/skeleton.rb +96 -0
- data/lib/multimedia_paradise/gui/gtk/simple_play_widget/README.md +12 -0
- data/lib/multimedia_paradise/gui/gtk/simple_play_widget/simple_play_widget.rb +245 -0
- data/lib/multimedia_paradise/gui/gtk/video_collection.rb +214 -0
- data/lib/multimedia_paradise/gui/gtk/widget_increase_or_decrease_audio.rb +143 -0
- data/lib/multimedia_paradise/gui/gtk/youtube_downloader.rb +265 -0
- data/lib/multimedia_paradise/gui/gui_base.rb +46 -0
- data/lib/multimedia_paradise/gui/tk/tk_multimedia_wrapper.rb +60 -0
- data/lib/multimedia_paradise/help/help.rb +73 -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/menu/menu.rb +365 -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 +176 -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/interactive_shell.rb +84 -0
- data/lib/multimedia_paradise/multimedia/merge_multimedia.rb +119 -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/start_length_duration.rb +205 -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_audio.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 +30 -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 +257 -0
- data/lib/multimedia_paradise/sound_effects/README.md +8 -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/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/conversions.rb +1040 -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 +151 -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 +86 -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 +61 -0
- data/lib/multimedia_paradise/toplevel_methods/merge_multimedia_file.rb +105 -0
- data/lib/multimedia_paradise/toplevel_methods/merge_these_videos.rb +96 -0
- data/lib/multimedia_paradise/toplevel_methods/misc.rb +316 -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 +350 -0
- data/lib/multimedia_paradise/toplevel_methods/rds.rb +24 -0
- data/lib/multimedia_paradise/toplevel_methods/return_all_video_files.rb +63 -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 +62 -0
- data/lib/multimedia_paradise/toplevel_methods/return_screen_resolution.rb +24 -0
- data/lib/multimedia_paradise/toplevel_methods/scale_video.rb +27 -0
- data/lib/multimedia_paradise/toplevel_methods/set_title_of.rb +55 -0
- data/lib/multimedia_paradise/toplevel_methods/slow_down_this_video_file.rb +33 -0
- data/lib/multimedia_paradise/toplevel_methods/start_screencast.rb +61 -0
- data/lib/multimedia_paradise/toplevel_methods/subtitles.rb +59 -0
- data/lib/multimedia_paradise/toplevel_methods/to_mp4.rb +22 -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/copy_missing_video_files.rb +278 -0
- data/lib/multimedia_paradise/video/correct_video_numbers.rb +273 -0
- data/lib/multimedia_paradise/video/create_dvd.rb +50 -0
- data/lib/multimedia_paradise/video/encode_video.rb +79 -0
- data/lib/multimedia_paradise/video/ffmpeg_options.rb +156 -0
- data/lib/multimedia_paradise/video/find_video.rb +431 -0
- data/lib/multimedia_paradise/video/fix_married_with_children_videos.rb +70 -0
- data/lib/multimedia_paradise/video/google_video_downloader.rb +80 -0
- data/lib/multimedia_paradise/video/guess_video_name.rb +189 -0
- data/lib/multimedia_paradise/video/missing_video_files/missing_video_files.rb +286 -0
- data/lib/multimedia_paradise/video/movie_searcher.rb +279 -0
- data/lib/multimedia_paradise/video/mplayer_wrapper.rb +483 -0
- data/lib/multimedia_paradise/video/play_random_file.rb +85 -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 +147 -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 +152 -0
- data/lib/multimedia_paradise/video/simpsons.rb +127 -0
- data/lib/multimedia_paradise/video/speed_up_video.rb +135 -0
- data/lib/multimedia_paradise/video/srt_regex.rb +211 -0
- data/lib/multimedia_paradise/video/store_available_video_files.rb +135 -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 +336 -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 +572 -0
- data/lib/multimedia_paradise/video/video_renamer.rb +166 -0
- data/lib/multimedia_paradise/video/watermark.rb +290 -0
- data/lib/multimedia_paradise/video/youtube_embedder.rb +235 -0
- data/lib/multimedia_paradise/www/alsa.cgi +274 -0
- data/lib/multimedia_paradise/www/audacity.cgi +23 -0
- data/lib/multimedia_paradise/www/audio.cgi +2589 -0
- data/lib/multimedia_paradise/www/best_voices.cgi +57 -0
- data/lib/multimedia_paradise/www/componists/vivaldi.cgi +212 -0
- data/lib/multimedia_paradise/www/decibel.cgi +79 -0
- data/lib/multimedia_paradise/www/lame.cgi +100 -0
- data/lib/multimedia_paradise/www/lilypond.cgi +96 -0
- data/lib/multimedia_paradise/www/lyrics.cgi +48 -0
- data/lib/multimedia_paradise/www/midi/al_adagi.mid +0 -0
- data/lib/multimedia_paradise/www/play_songs.cgi +75 -0
- data/lib/multimedia_paradise/www/pulseaudio.cgi +169 -0
- data/lib/multimedia_paradise/www/rhythmbox.cgi +115 -0
- data/lib/multimedia_paradise/www/sound_theory.cgi +162 -0
- data/lib/multimedia_paradise/yaml/audio_formats.yml +14 -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 +157 -0
- data/lib/multimedia_paradise/yaml/image_formats.yml +8 -0
- data/lib/multimedia_paradise/yaml/lyrics.yml +5543 -0
- data/lib/multimedia_paradise/yaml/playlist.yml +115 -0
- data/lib/multimedia_paradise/yaml/radio/README.md +5 -0
- data/lib/multimedia_paradise/yaml/radio/radio_stations.yml +289 -0
- data/lib/multimedia_paradise/yaml/song_tags.yml +815 -0
- data/lib/multimedia_paradise/yaml/use_this_video_player.yml +1 -0
- data/lib/multimedia_paradise/yaml/video_collection.yml +1818 -0
- data/multimedia_paradise.gemspec +71 -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 +476 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5f79ba1e9612bb765e5d787ed1265564a230141d4cddf6721ff3dcfa5f4ea631
|
4
|
+
data.tar.gz: 8ebdd2e27b93c2abae1d6774bad96589b7035d11784843df27ca88e3bd909a2b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 231be9d038ce39099c5c4ac3dd791b411e9422426e54289c35b294150eee1cb565006cb74b2f13c10ff05dd99b4bf936d76a60852a549f5800d52f4c37657cde
|
7
|
+
data.tar.gz: a9ffc45cf5c81178e38e7aa10403bea94a1f0a5d1916749b0673fea15e66c6449e36fe0f6f34b5e9a5a541941f0dd5fa4475273506b636dbbf101dc8cb78aaa8
|
data/README.md
ADDED
@@ -0,0 +1,1177 @@
|
|
1
|
+
[![forthebadge](http://forthebadge.com/images/badges/built-with-love.svg)](https://www.gobolinux.org/)
|
2
|
+
[![forthebadge](http://forthebadge.com/images/badges/made-with-ruby.svg)](https://www.ruby-lang.org/en/)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/multimedia_paradise.svg)](https://badge.fury.io/rb/multimedia_paradise)
|
4
|
+
|
5
|
+
# MultimediaParadise - Everything about audio and video
|
6
|
+
|
7
|
+
![Logo][logo]
|
8
|
+
[logo]: http://shevy.bplaced.net/MULTIMEDIA_PARADISE_LOGO.png
|
9
|
+
|
10
|
+
The **multimedia paradise** project bundles together code that can be
|
11
|
+
used for "multimedia data" - in particular for **audio** and **video** files.
|
12
|
+
|
13
|
+
Most of the functionality found within the **multimedia paradise**
|
14
|
+
projects depends on <b>ffmpeg</b>, but in principle the code in the
|
15
|
+
main module called **MultimediaParadise** should work with other
|
16
|
+
toolkits as well, if a toolkit supports certain actions (such as
|
17
|
+
<b>sox</b>). As is often the case, support for other toolkits depends
|
18
|
+
on time investment - and time availability - of the main author of
|
19
|
+
this project.
|
20
|
+
|
21
|
+
For all purposes, though, **ffmpeg** is a really excellent project.
|
22
|
+
Thus, the MultimediaParadise gem will focus on **ffmpeg** by
|
23
|
+
default.
|
24
|
+
|
25
|
+
You can obtain a copy of ffmpeg from the following URL:
|
26
|
+
|
27
|
+
https://www.ffmpeg.org/
|
28
|
+
|
29
|
+
## Installation of the MultimediaParadise project
|
30
|
+
|
31
|
+
There are several ways how to install this project, including oldschol
|
32
|
+
**setup.rb** - but I recommend the following way:
|
33
|
+
|
34
|
+
gem install multimedia_paradise --user-install
|
35
|
+
|
36
|
+
The reason as to why I recommend the **--user-install** option is because
|
37
|
+
the various files under the **bin/** subdirectory will be available
|
38
|
+
in your home directory (under e. g. ~/.gem/ruby/2.5.0/bin or whatever
|
39
|
+
your local ruby version is). That way you can easily add that directory
|
40
|
+
to $PATH or not, and make use of these files.
|
41
|
+
|
42
|
+
## Removing audio from a video file
|
43
|
+
|
44
|
+
If you wish to **remove audio from a video file**, use the following
|
45
|
+
**API**:
|
46
|
+
|
47
|
+
MultimediaParadise.remove_audio(path_to_the_file_goes_in_here)
|
48
|
+
|
49
|
+
Specific example:
|
50
|
+
|
51
|
+
MultimediaParadise.remove_audio('/foo.avi')
|
52
|
+
|
53
|
+
This functionality depends on an installed **ffmpeg**. If anyone
|
54
|
+
knows of a pure ruby variant only, let me know.
|
55
|
+
|
56
|
+
## Radio stations
|
57
|
+
|
58
|
+
Since as of **October 2018**, the **MultimediaParadise** project comes
|
59
|
+
with a small **yaml file** called **radio_stations.yml**.
|
60
|
+
|
61
|
+
x = YAML.load_file('radio_stations.yml')
|
62
|
+
|
63
|
+
The idea here is to have a few additional audio-streams (from **radio
|
64
|
+
stations**) that could be loaded up into, for example, **rhythmbox**.
|
65
|
+
|
66
|
+
I also wanted to have a default "template" for testing some ruby code
|
67
|
+
there, such as autogenerating a playlist from this file, or listening
|
68
|
+
to radio stations via mplayer (or mpv) and similar activities.
|
69
|
+
|
70
|
+
The file **radio_stations.yml** is evidently catered to my own use
|
71
|
+
case. If you wish to use your own .yml file then you can do so by
|
72
|
+
setting the environment variable called **MULTIMEDIA_PARADISE_RADIO_STATIONS**
|
73
|
+
to the path of a local yaml file. For the necessary format, see the
|
74
|
+
file **radio_stations.yml** that comes distributed with this **.gem**.
|
75
|
+
|
76
|
+
I may listen to local internet radio stations but also to external
|
77
|
+
ones, such as **BBC**. The following example shows how I tap into
|
78
|
+
this functionality, first by showing BBC 1:
|
79
|
+
|
80
|
+
multimedia_paradise --bbc1
|
81
|
+
multimedia_paradise --bbc2
|
82
|
+
multimedia_paradise --bbc3
|
83
|
+
multimedia_paradise --bbc4
|
84
|
+
multimedia_paradise --fm4
|
85
|
+
|
86
|
+
The above list may be extended in the future, but for now (December
|
87
|
+
2018) it shall suffice.
|
88
|
+
|
89
|
+
Do note that this functionality depends on a multimedia player,
|
90
|
+
such as **mpv** or **mplayer**. See elsewhere in this document
|
91
|
+
how to set to use such a multimedia player.
|
92
|
+
|
93
|
+
## Streamripper support
|
94
|
+
|
95
|
+
There is code support for streamripper, just a tiny wrapper.
|
96
|
+
|
97
|
+
This can be invoked like so:
|
98
|
+
|
99
|
+
MultimediaParadise.streamripper
|
100
|
+
|
101
|
+
This depends on the file <b>streamripper_wrapper.rb</b> which
|
102
|
+
is just a tiny, pure-ruby "wrapper" over streamripper. (It
|
103
|
+
really only directly calls the streampripper binary, so
|
104
|
+
nothing fancy.)
|
105
|
+
|
106
|
+
## Modifying the timestamps of .srt files
|
107
|
+
|
108
|
+
The file <b>srt_regex.rb</b> can be used if you need to batch-modify
|
109
|
+
.srt files, when they have the wrong timestamp, for instance. This
|
110
|
+
was exactly the reason why I wrote that class - some .srt files
|
111
|
+
may have a wrong offset, and so we need to correct them.
|
112
|
+
|
113
|
+
Note that this class is quite old and the code quality is not as
|
114
|
+
high as other classes since I wrote it a long time ago. I may
|
115
|
+
improve on it eventually, but for the time being, assume that
|
116
|
+
it isn't one of the best classes in this project.
|
117
|
+
|
118
|
+
## Watermarking videos
|
119
|
+
|
120
|
+
A <b>watermark</b> is a specific tag to a video. This can be a
|
121
|
+
<b>logo</b> but it can also be used as some kind of (annoying)
|
122
|
+
filter.
|
123
|
+
|
124
|
+
Whatever your use case may be, ffmpeg supports watermarking
|
125
|
+
videos - and multimedia_paradise taps right into that
|
126
|
+
functionality.
|
127
|
+
|
128
|
+
Adding a watermark to a video is possible and quite simple.
|
129
|
+
The class that does so, in regards to the MultimediaParadise
|
130
|
+
project, is aptly called <b>Watermark</b> and it allows you
|
131
|
+
to use FFMPEG to embed a watermark video, using the
|
132
|
+
simple <b>MultimediaParadise.watermark()</b> method.
|
133
|
+
|
134
|
+
I rarely need to use this method so it may not be as
|
135
|
+
polished as other parts of the project, though.
|
136
|
+
|
137
|
+
The default use is to simply call that .rb file and pass a
|
138
|
+
video file to it:
|
139
|
+
|
140
|
+
vwatermark /Depot/Temp/MultimediaProject/foobar.mp4
|
141
|
+
|
142
|
+
(vwatermark is an alias on my system.)
|
143
|
+
|
144
|
+
If you want to use your own image, then you have to pass an
|
145
|
+
additional argument to the method, which should be the path
|
146
|
+
to the image at hand.
|
147
|
+
|
148
|
+
vwatermark /Depot/Temp/MultimediaProject/foobar.mp4 /opt/my_awesome_logo.png
|
149
|
+
|
150
|
+
## Embedding Youtube Videos
|
151
|
+
|
152
|
+
"Embedding" Youtube Videos is also possible. Note the quotes.
|
153
|
+
|
154
|
+
The code is in the file **multimedia_paradise/video/youtube_embedder.rb**.
|
155
|
+
|
156
|
+
## Increasing the volume of an audio file
|
157
|
+
|
158
|
+
You can use the module-level method:
|
159
|
+
|
160
|
+
MultimediaParadise.increase_volume_of_this_audio_file()
|
161
|
+
|
162
|
+
The **first argument** to this method should be the name of the file
|
163
|
+
that you wish to modify or the name of the files. This is usually
|
164
|
+
a file such as foobar.mp3 or similar.
|
165
|
+
|
166
|
+
The **second argument** is the modified percentage value that is
|
167
|
+
given to -v (and to **sox**). For example, if you pass in 2.0,
|
168
|
+
then the volume of the audio file at hand will be **increased
|
169
|
+
twofold**. If it is 3.0, then it will be increased threefold,
|
170
|
+
and so on.
|
171
|
+
|
172
|
+
Since the name of the method is "increase_volume", that particular
|
173
|
+
method can not be used to decrease the volume (via negative
|
174
|
+
floats such as -2.0).
|
175
|
+
|
176
|
+
## Download videos from Google
|
177
|
+
|
178
|
+
The file google_video_downloader.rb can be used to download
|
179
|
+
videos from Google - but we may have to use youtube-dl for
|
180
|
+
this, which is python. This is not ideal since we use ruby :)
|
181
|
+
but I am too lazy to clone the functionality of <b>youtube-dl</b>
|
182
|
+
for now, so this just has to be glue code really. (Glue code
|
183
|
+
is for lazy people and I am lazy.)
|
184
|
+
|
185
|
+
## Extracting audio from any given video file
|
186
|
+
|
187
|
+
You can extract audio from any given video file, by making
|
188
|
+
use of <b>class MultimediaParadise::ExtractAudio</b>. This
|
189
|
+
presently depends on <b>ffmpeg</b>, so you must have
|
190
|
+
ffmpeg available.
|
191
|
+
|
192
|
+
Usage example follows:
|
193
|
+
|
194
|
+
MultimediaParadise::ExtractAudio.new('foobar.avi')
|
195
|
+
|
196
|
+
This assumes that a video file called **foobar.avi** exists.
|
197
|
+
|
198
|
+
A **toplevel method** exists for this functionality as well:
|
199
|
+
|
200
|
+
MultimediaParadise.extract_audio(target_file_here)
|
201
|
+
MultimediaParadise.extract_audio('/tmp/foobar.avi')
|
202
|
+
MultimediaParadise.extract_audio('/home/lala.mp4')
|
203
|
+
|
204
|
+
Perhaps you may find the latter variant to be easier to read and
|
205
|
+
use than the variant that uses explicit **::** scoping for the
|
206
|
+
instantiation of **class ExtractAudio**. Under the hood, both
|
207
|
+
variants do the same of course.
|
208
|
+
|
209
|
+
## Screen capture
|
210
|
+
|
211
|
+
If you want to capture the screen, that is, to record what
|
212
|
+
is happening, have a look at the class called
|
213
|
+
<b>MultimediaParadise::CaptureScreen</b>, in the file
|
214
|
+
**multimedia_paradise/video/capture_screen.rb**.
|
215
|
+
|
216
|
+
## Autoinclude the main namespace
|
217
|
+
|
218
|
+
Since April 2014 you can autoinclude this project's main
|
219
|
+
namespace (toplevel **MultimediaParadise constant**)
|
220
|
+
by using the following ruby code:
|
221
|
+
|
222
|
+
require 'multimedia_paradise/autoinclude'
|
223
|
+
|
224
|
+
## Using the executable bin/mpa
|
225
|
+
|
226
|
+
**mpa** is a small wrapper over mpv (or mplayer).
|
227
|
+
|
228
|
+
It is tailored to my own local videoset, which I store in
|
229
|
+
a yaml file. I am not sure how to best have other people
|
230
|
+
use mpa without the .yml file, but at the worst, it
|
231
|
+
is possible to just use bin/multimedia_paradise to play
|
232
|
+
an existing local video or audio file.
|
233
|
+
|
234
|
+
## Guessing video names
|
235
|
+
|
236
|
+
I use a **.yml** file to keep track of registered video files.
|
237
|
+
|
238
|
+
I also needed a class that tells me the most likely name of a
|
239
|
+
video file, e. g. if the input is "Ninja", then this class
|
240
|
+
should report all Ninja video files, properly sorted, according
|
241
|
+
to the information contained in that .yml file. (This of course
|
242
|
+
requires that this genre is registered in that .yml file.)
|
243
|
+
|
244
|
+
**class MultimediaParadise::GuessVideoName** does precisely
|
245
|
+
that. Input the given search term at hand, such as **horror**
|
246
|
+
for horror movies, and it should hopefully report some information
|
247
|
+
that may be useful in order to find/name the video file at hand.
|
248
|
+
|
249
|
+
Note that this depends on a properly formatted .yml file; and
|
250
|
+
ideally you would create your own .yml file, with your own
|
251
|
+
tags, videos and so forth.
|
252
|
+
|
253
|
+
The **format** of the .yml file should be like this:
|
254
|
+
|
255
|
+
a) The number of the video file at hand, as an **Integer** value,
|
256
|
+
such as 1, 2, 3 and so forth.
|
257
|
+
b) A **hash** that describes at the least the 'title', but
|
258
|
+
may also contain entries such as <b>imdb:</b> and so forth.
|
259
|
+
|
260
|
+
## Finding local videos
|
261
|
+
|
262
|
+
The file <b>find_video.rb</b> can be of help here as it will
|
263
|
+
try to locate local videos.
|
264
|
+
|
265
|
+
This is optimized towards my own dataset compiled about
|
266
|
+
videos; in the future, I will most likely provide a way
|
267
|
+
so that other people can also use their own dataset.
|
268
|
+
(The dataset I use is a simple yaml file storing all
|
269
|
+
information about the local videos.)
|
270
|
+
|
271
|
+
## Playing a random (video or audio) file
|
272
|
+
|
273
|
+
<b>class MultimediaParadise::PlayRandomFile</b> can play a
|
274
|
+
random multimedia file. Since this will select a file
|
275
|
+
randomly, you can only pass in a directory for now - although
|
276
|
+
passing in an Array may also make sense, so perhaps this
|
277
|
+
class will be extended at a later time.
|
278
|
+
|
279
|
+
## AudioPlayer
|
280
|
+
|
281
|
+
This class is just a thin "wrapper" over **mplayer** or
|
282
|
+
**mpv** really. It has been created in **early June 2014**.
|
283
|
+
|
284
|
+
The file can be found at
|
285
|
+
**multimedia_paradise/audio/audio_player/audio_player.rb**.
|
286
|
+
|
287
|
+
It was originally created because I needed to play, via
|
288
|
+
the commandline, audio songs in a <b>loop</b> - like a
|
289
|
+
**juke box**. I wanted it to be very simple too, so no
|
290
|
+
ncurses interface to it.
|
291
|
+
|
292
|
+
I also use it to perform wake-up calls in the morning, like
|
293
|
+
an alarm clock.
|
294
|
+
|
295
|
+
There is an **executable** for this, at **bin/audio_player**,
|
296
|
+
which acts as entry point to the code behind it, for
|
297
|
+
<b>class MultimediaParadise::AudioPlayer</b>:
|
298
|
+
|
299
|
+
If you want to play in a loop, you can pass the argument
|
300
|
+
"loop" or just "l".
|
301
|
+
|
302
|
+
Since as of the 24th February 2018, it can also act as a
|
303
|
+
"timer", together with class <b>Roebe::At</b>. For example,
|
304
|
+
if you want to play random songs at the time 21:35:00,
|
305
|
+
you can do:
|
306
|
+
|
307
|
+
rsong 21:35:00
|
308
|
+
|
309
|
+
Note that <b>rsong</b> is simply an alias that I use towards
|
310
|
+
<b>bin/audio_player</b>. Without an alias, the above becomes:
|
311
|
+
|
312
|
+
audio_player 21:35:00
|
313
|
+
|
314
|
+
Usually I tend to use <b>mpv</b>, but sometimes I do use
|
315
|
+
mplayer, e. g. when mpv has some problem due to recent
|
316
|
+
API changes. In this case, one can specify to use mplayer
|
317
|
+
on the commandline, via:
|
318
|
+
|
319
|
+
rsong 10:00:00 --use-mplayer
|
320
|
+
|
321
|
+
## Delaying the audio of a video-file
|
322
|
+
|
323
|
+
FFmpeg allows you to easily delay the audio of a video file.
|
324
|
+
|
325
|
+
MultimediaParadise has this included as well, via:
|
326
|
+
|
327
|
+
MultimediaParadise.delay_audio()
|
328
|
+
|
329
|
+
The first argument to this should be the name of the file
|
330
|
+
that you wish to manipulate, such as <b>foobar.mp4</b>.
|
331
|
+
|
332
|
+
The second argument is the amount of seconds for the delay,
|
333
|
+
such as 5.53 seconds.
|
334
|
+
|
335
|
+
A new video-file will be generated as a consequence, if all
|
336
|
+
goes well.
|
337
|
+
|
338
|
+
## Denoising audio/video
|
339
|
+
|
340
|
+
This subsection is about <b>removing noise from a multimedia file</b>.
|
341
|
+
|
342
|
+
**Noise** in this context refers to **unwanted audio**, such as
|
343
|
+
scratching on a blackboard during a university lecture, and similar
|
344
|
+
unwanted noises.
|
345
|
+
|
346
|
+
First, this functionality was needed because I inherited **audio recordings**
|
347
|
+
that were made via a cheap mp3-recorder from like **+10 years ago** or so,
|
348
|
+
say, the year 2009 - something like that.
|
349
|
+
|
350
|
+
The human voice has a **frequency range** between **300Hz** - **3000Hz**.
|
351
|
+
|
352
|
+
The **noise** in these files was extremey disturbing and distracting, and
|
353
|
+
I wanted to get rid of it, in order to more easily hear the voice of the
|
354
|
+
speaker. This also included increasing the volume as well, but that is
|
355
|
+
for another subsection.
|
356
|
+
|
357
|
+
The subsection here will additionally report some of my findings from back
|
358
|
+
then - as a **memo**.
|
359
|
+
|
360
|
+
A simple **filter-strategy** is to **first apply highpass**, and then
|
361
|
+
**lowpass**, via **ffmpeg**, such as in this way:
|
362
|
+
|
363
|
+
ffmpeg -i foobar.mp3 -af "lowpass=f=3000, highpass=f=200" output.mp3
|
364
|
+
|
365
|
+
Your local file comes first, such as the file **foobar.mp3*. This should
|
366
|
+
remove some of the noise that you may find in a recording, but you may
|
367
|
+
have to tweak the values a little in order to get the most out of it.
|
368
|
+
|
369
|
+
Note that you can use ffplay to see the effect of this:
|
370
|
+
|
371
|
+
ffplay INPUT_FILE -af lowpass=3000,highpass=200
|
372
|
+
ffplay foobar.mp3 -af lowpass=4000,highpass=200
|
373
|
+
ffplay foobar.mp3 -af lowpass=2000,highpass=200
|
374
|
+
|
375
|
+
I integrated this functionality into **MultimediaParadise**, via the
|
376
|
+
following simple API:
|
377
|
+
|
378
|
+
MultimediaParadise.denoise('foobar.mp3')
|
379
|
+
|
380
|
+
This is the default use case, by just supplying the name/path to the
|
381
|
+
audio file in question.
|
382
|
+
|
383
|
+
The second argument to this method is the **lowpass value**; the
|
384
|
+
third argument is for the **highpass value**:
|
385
|
+
|
386
|
+
MultimediaParadise.denoise('foobar.mp3', '250', '2000')
|
387
|
+
|
388
|
+
This, surprisingly enough, worked. But I do not think it is
|
389
|
+
the ideal value.
|
390
|
+
|
391
|
+
For more information, see the following blog entry from 2017:
|
392
|
+
|
393
|
+
https://manerosss.wordpress.com/2017/07/24/ffmpeg-%C2%B7-apply-a-filter-to-enhance-voice-by-removing-low-and-high-frequency-noises/
|
394
|
+
|
395
|
+
If you need to find out which values are best, you can use <b>ffplay</b>
|
396
|
+
such as in this way:
|
397
|
+
|
398
|
+
ffplay INPUT -af lowpass=3000,highpass=200
|
399
|
+
|
400
|
+
## Creating a screencast with multimedia_paradise and FFMPEG
|
401
|
+
|
402
|
+
Code in the file **multimedia_paradise/toplevel_methods/screencast.rb** can
|
403
|
+
be used to record a screencast (on Linux).
|
404
|
+
|
405
|
+
The API is as follows:
|
406
|
+
|
407
|
+
MultimediaParadise.start_screencast
|
408
|
+
|
409
|
+
The method accepts several parameters - if you need fine tuning then
|
410
|
+
have a look at that file.
|
411
|
+
|
412
|
+
Presently only video without audio can be recorded, but there are
|
413
|
+
tutorials out there that enable recording of audio as well. I will
|
414
|
+
have a look into this at a later time (<- written in September 2018).
|
415
|
+
|
416
|
+
## Changing the audio code of a video file via FFMpeg
|
417
|
+
|
418
|
+
If you want to change the audio codec in a given video file, say,
|
419
|
+
**foobar.avi**, then you can use this API:
|
420
|
+
|
421
|
+
MultimediaParadise.use_lame_codec('foobar.avi')
|
422
|
+
|
423
|
+
This essentially just combines **-vcodec copy -acodec libmp3lame**
|
424
|
+
but I wanted to have a simpler top-level API in ruby for this too,
|
425
|
+
so this method was added.
|
426
|
+
|
427
|
+
## Query the audio codec of a video file
|
428
|
+
|
429
|
+
You can use this top-level API to determine the audio codec of a
|
430
|
+
video file:
|
431
|
+
|
432
|
+
MultimediaParadise.query_the_audio_codec_of_this_file()
|
433
|
+
MultimediaParadise.query_the_audio_codec()
|
434
|
+
MultimediaParadise.audio_codec?()
|
435
|
+
|
436
|
+
All variants listed above work; the last option is the shortest
|
437
|
+
one, apparently.
|
438
|
+
|
439
|
+
The argument should be the path to a locally existing videofile.
|
440
|
+
|
441
|
+
Say that your file is at **/Depot/foobar.avi** then the ruby code
|
442
|
+
may look like this:
|
443
|
+
|
444
|
+
require 'multimedia_paradise'
|
445
|
+
uses_this_codec = MultimediaParadise.audio_codec?('/Depot/foobar.avi')
|
446
|
+
|
447
|
+
This functionality **depends on ffmpeg**.
|
448
|
+
|
449
|
+
## Converting into .mp3 format
|
450
|
+
|
451
|
+
You can use class **MultimediaParadise::Audio::ToMp3** to convert
|
452
|
+
e. g. a **.wav** file into a **.mp3** file:
|
453
|
+
|
454
|
+
MultimediaParadise::Audio::ToMp3.new('path_to_wav.waf')
|
455
|
+
|
456
|
+
As this may be a bit cumbersome to type, there exists a simpler
|
457
|
+
**top-level method** to convert an audio-file into the **.mp3
|
458
|
+
format**:
|
459
|
+
|
460
|
+
MultimediaParadise.to_mp3(*input_files_here)
|
461
|
+
MultimediaParadise.to_mp3( %( foo.wav bar.wav ) )
|
462
|
+
|
463
|
+
## ffmpeg options
|
464
|
+
|
465
|
+
This subsection just shows a few options for ffmpeg; I added this mostly
|
466
|
+
because I tend to be quite forgetful. That way I can have a quick
|
467
|
+
overview on the homepage of this gem here.
|
468
|
+
|
469
|
+
|Commandline flag | Example | Implementation Status
|
470
|
+
|-----------------|------------------------|----------------------------------------------------------------------------------------|
|
471
|
+
| **-s** | **-s 500×500** | convert the video into a **width x height** ratio, of 500 x 500 pixel |
|
472
|
+
| **-vcodec** | **-vcodec mpeg4** | specify which video-codec is to be used, e. g. for the conversion of a video file |
|
473
|
+
|
474
|
+
## Playing several multimedia-files from a list/file
|
475
|
+
|
476
|
+
You can pass a list of files that the MultimediaParadise project
|
477
|
+
should play.
|
478
|
+
|
479
|
+
The toplevel method is **MultimediaParadise.play_this_list()**,
|
480
|
+
so for example:
|
481
|
+
|
482
|
+
MultimediaParadise.play_this_list '
|
483
|
+
|
484
|
+
/Users/x/VIDEO/Cartoons/Simpsons-09/Treehouse_Of_Horror_VIII.m4v
|
485
|
+
/Users/x/VIDEO/Cartoons/Simpsons-09/The_Joy_Of_Sect.m4v
|
486
|
+
/Users/x/VIDEO/Cartoons/Simpsons-08/The_Springfield_Files.m4v
|
487
|
+
|
488
|
+
'
|
489
|
+
|
490
|
+
Empty lines will be ignored, so the method will only play these
|
491
|
+
entries if they are not empty.
|
492
|
+
|
493
|
+
The alias **MultimediaParadise.play_from_this_list()** would also
|
494
|
+
work, by the way.
|
495
|
+
|
496
|
+
I needed this functionality because sometimes other classes written
|
497
|
+
in ruby may show, on the commandline, such a flat list, via a long
|
498
|
+
String broken by newlines.
|
499
|
+
|
500
|
+
## Environment variables for the MultimediaParadise project
|
501
|
+
|
502
|
+
The MultimediaParadise project is tailored to my own needs primarily,
|
503
|
+
which means that other people may not necessarily benefit from the
|
504
|
+
project as much. Additionally, as of December 2018, there are some
|
505
|
+
hardcoded paths, which makes this even worse. I have decided in
|
506
|
+
December 2018 that this approach will change in the future.
|
507
|
+
|
508
|
+
For the time being, you can use certain ENV (environment) flags to
|
509
|
+
specify where your audio/video files are kept. This assumes that
|
510
|
+
you have **one central directory** for these files; respectively
|
511
|
+
up to two, if you keep your audio and video files **separate**.
|
512
|
+
|
513
|
+
For specifying where your **local video files** reside, you can use the
|
514
|
+
constant called **MULTIMEDIA_PARADISE_DEPOT_VIDEO**. Simply
|
515
|
+
set this, in your shell, to be the path to the directory where
|
516
|
+
your video files may be, such as in:
|
517
|
+
|
518
|
+
export MULTIMEDIA_PARADISE_DEPOT_VIDEO=/opt/videos
|
519
|
+
|
520
|
+
A similar constant exists for audio files; simply set
|
521
|
+
**MULTIMEDIA_PARADISE_DEPOT_AUDIO**.
|
522
|
+
|
523
|
+
export MULTIMEDIA_PARADISE_DEPOT_AUDIO=/opt/my_songs
|
524
|
+
|
525
|
+
## Genre support of video files
|
526
|
+
|
527
|
+
If you have a .yml file that keeps your video files
|
528
|
+
sorted, then you can also use a <b>genre:</b> tag
|
529
|
+
identifier to classify the video at hand.
|
530
|
+
|
531
|
+
For example, the movie <b>The Blade Runner</b> may have an associated
|
532
|
+
genre called <b>Science Fiction</b>. The movie <b>Poltergeist</b> may
|
533
|
+
have a genre tag called <b>Horror</b> and so on.
|
534
|
+
|
535
|
+
Once the genre-tagging has been done, we can search
|
536
|
+
for these genres on the commandline, via class
|
537
|
+
<b>VideoGenres</b>.
|
538
|
+
|
539
|
+
See its --help option for commands.
|
540
|
+
|
541
|
+
video_genres --help
|
542
|
+
|
543
|
+
If you wish to find out which science fiction movies
|
544
|
+
are registered, do:
|
545
|
+
|
546
|
+
video_genres --genre="Science Fiction"
|
547
|
+
|
548
|
+
You can also use a shorter variant, via a Pseudo-Regex:
|
549
|
+
|
550
|
+
video_genres "/Science Fiction/"
|
551
|
+
|
552
|
+
Some shortcuts exist if the above is too cumbersome. For example,
|
553
|
+
all science fiction movies could also be shown via this way:
|
554
|
+
|
555
|
+
video_genres --science-fiction
|
556
|
+
|
557
|
+
To see the available video genres, do this:
|
558
|
+
|
559
|
+
video_genres --available-video-genres
|
560
|
+
|
561
|
+
It you want to play a **random** horror movie, provided that you
|
562
|
+
have these registered tags, you can do the following:
|
563
|
+
|
564
|
+
video_genres --play-random-video-from-this-genre=horror
|
565
|
+
|
566
|
+
## Copying and merging the same video
|
567
|
+
|
568
|
+
If you sort of wish to "duplicate" a video, but append this
|
569
|
+
onto an existing one, then you can use this method:
|
570
|
+
|
571
|
+
MultimediaParadise.copy_and_merge_this_video_n_times
|
572
|
+
|
573
|
+
The first argument should be the existing video file; the
|
574
|
+
second argument should be how many times it should be
|
575
|
+
"repeated", which should be a number. For example, the
|
576
|
+
number 5 means that the video will be merged onto itself
|
577
|
+
4 times, thus creating a video that is 5x the length (all
|
578
|
+
with the same content).
|
579
|
+
|
580
|
+
There are alternatives to this, such as looping the same
|
581
|
+
video; but I wanted to really be able to have the same
|
582
|
+
video be played over and over again, even though this
|
583
|
+
made the size larger.
|
584
|
+
|
585
|
+
## MultimediaParadise::AnalyseMultimediaFile
|
586
|
+
|
587
|
+
class **MultimediaParadise::AnalyseMultimediaFile** can be used
|
588
|
+
to analyse multimedia files (e. g. audio and video files),
|
589
|
+
on the commandline.
|
590
|
+
|
591
|
+
I needed this because **ffmpeg -i** alone was tiresome to
|
592
|
+
read.
|
593
|
+
|
594
|
+
|
595
|
+
|
596
|
+
## Flipping and rotating video files
|
597
|
+
|
598
|
+
FFMpeg can easily flip video files. MultimediaParadise supports this
|
599
|
+
functionality too, through the file
|
600
|
+
<b>multimedia_paradise/toplevel_methods/flip_and_rotate.rb</b>.
|
601
|
+
|
602
|
+
Horizontal and vertical flipping is supported through these
|
603
|
+
two **toplevel APIs**:
|
604
|
+
|
605
|
+
MultimediaParadise.horizontal_flip()
|
606
|
+
MultimediaParadise.vertical_flip()
|
607
|
+
|
608
|
+
The latter variant also has a simpler, more intuitive API:
|
609
|
+
|
610
|
+
MultimediaParadise.flip_upside_down()
|
611
|
+
|
612
|
+
So essentially, you picture a video, and then simply flip
|
613
|
+
the top to the bottom, and the bottom to the top. Easy-peasy.
|
614
|
+
|
615
|
+
The **first argument** to this method should be the name/path
|
616
|
+
to an existing video file.
|
617
|
+
|
618
|
+
You can also rotate a video file by 90° via this API:
|
619
|
+
|
620
|
+
MultimediaParadise.rotate_this_video_file_by_90_degrees('foo.mpg')
|
621
|
+
|
622
|
+
Since as of March 2019, two more methods were added to flip a video
|
623
|
+
(rotate a video) clockwise and counter-clockwise, by 90° each:
|
624
|
+
|
625
|
+
MultimediaParadise.flip_video_to_the_right
|
626
|
+
MultimediaParadise.flip_video_to_the_left
|
627
|
+
|
628
|
+
So the older method **MultimediaParadise.rotate_this_video_file_by_90_degrees()**
|
629
|
+
is essentially the same as the newer method **MultimediaParadise.flip_video_to_the_right**.
|
630
|
+
|
631
|
+
## Merging audio files together
|
632
|
+
|
633
|
+
**class MultimediaParadise::MergeAudioFiles** can be used to merge different
|
634
|
+
audio files together. If no specific input argument is provided then this
|
635
|
+
class will scan for all audio files in the current working directory and all
|
636
|
+
subdirectories, then merge these together into a new file called **output.mp3**.
|
637
|
+
|
638
|
+
I needed this functionality so that I could put lectures together into a single
|
639
|
+
file - made it easier to listen to a single file, rather than find them all
|
640
|
+
spread out.
|
641
|
+
|
642
|
+
## Toplevel cutting multimedia files
|
643
|
+
|
644
|
+
This subsection deals with cutting multimedia files, that is,
|
645
|
+
to chop a longer file into one (or several) smaller files.
|
646
|
+
|
647
|
+
The primary method for this is called **MultimediaParadise.cut_from_to()**,
|
648
|
+
but you can also use a few aliases to this method, such as
|
649
|
+
**MultimediaParadise.cut()**.
|
650
|
+
|
651
|
+
The API is flexible.
|
652
|
+
|
653
|
+
Let's first show a few examples:
|
654
|
+
|
655
|
+
MultimediaParadise.cut_from_to('00:00:01-00:25:10', this_file: 'Tales_from_the_crypt_S05E10_Came_the_Dawn_1993.mp4')
|
656
|
+
MultimediaParadise.cut_from_to('00:02:23 / 00:28:04', this_file: 'Tales_from_the_crypt_S05E10_Came_the_Dawn_1993.mp4')
|
657
|
+
MultimediaParadise.cut(to: '00:22:50', this_file: 'TALES_FROM_THE_CRYPT/Tales_from_the_crypt_S06E11_Surprise_Party.mkv')
|
658
|
+
|
659
|
+
These are somewhat equivalent.
|
660
|
+
|
661
|
+
The simplest way may be to pass, as **first argument**, a String to
|
662
|
+
the method, denoting the start position and the end position, in
|
663
|
+
HH:MM:SS format. But you can also decide to use a Hash instead,
|
664
|
+
such as the third example shows.
|
665
|
+
|
666
|
+
Do note that if you decide to use a String, you can either use
|
667
|
+
the '-' variant or a ' / ' variant. The latter is the default
|
668
|
+
display format for the mpv video/audio player, so I added support
|
669
|
+
for it since copy/pasting may be a bit simpler that way.
|
670
|
+
|
671
|
+
The special key called **:this_file** should be the file that you
|
672
|
+
wish to cut. The absolute path should be given here; for my home
|
673
|
+
system I also use some fake-macros, such as TALES_FROM_THE_CRYPT/
|
674
|
+
to denote where tales from the crypt may reside (and other files).
|
675
|
+
This allows me to more easily make use of my local file system.
|
676
|
+
|
677
|
+
The key **:to** refers to the end position, that is, when to make
|
678
|
+
the cut.
|
679
|
+
|
680
|
+
The ideal scenario for this method is to simply cut from a start
|
681
|
+
position to an end position - in other words, to make an existing
|
682
|
+
video file shorter.
|
683
|
+
|
684
|
+
Do note that another class, called CutAudio, also exists as part of
|
685
|
+
the multimedia_paradise project. This is partially due to legacy
|
686
|
+
reasons; and partially due to CutAudio being primarily used for
|
687
|
+
.mp3 files, and for interactive use. One day the functionality
|
688
|
+
may be re-used, but for the time being I will keep it separate (less
|
689
|
+
work for now).
|
690
|
+
|
691
|
+
If you rather want a simple API, where you input only two Strings
|
692
|
+
usually (as parameters), then you could use:
|
693
|
+
|
694
|
+
MultimediaParadise.video_duration(of_this_file, '00:30:00-00:35:00')
|
695
|
+
|
696
|
+
The first argument would be the file that you wish to cut; and
|
697
|
+
the second is the duration, so two Strings in total. Interally this
|
698
|
+
will be passed to the method **MultimediaParadise.cut_from_to()**
|
699
|
+
anyway, so you could even use a Hash instead - but the primary use
|
700
|
+
case for that method is to allow for a simpler API. Use whatever
|
701
|
+
you prefer.
|
702
|
+
|
703
|
+
## Setting the title metadata of a .mp3 file
|
704
|
+
|
705
|
+
Thanks to ffmpeg we can easily modify the metadata entry of a .mp3
|
706
|
+
file. MultimediaParadise supports this too, via:
|
707
|
+
|
708
|
+
MultimediaParadise.set_title_of(this_audio_file, this_title)
|
709
|
+
|
710
|
+
So the first argument should be the local path to a .mp3 file; and
|
711
|
+
the second argument should be the title that this .mp3 file should
|
712
|
+
have. I use this for batch-setting the title - and a file called
|
713
|
+
**bin/auto_title** exists that does this from the commandline as well.
|
714
|
+
|
715
|
+
## CutAudio
|
716
|
+
|
717
|
+
You can cut audio files via the class **CutAudio**. The code to this
|
718
|
+
class resides under the subdirectory **multimedia_paradise/audio/cut_audio/**.
|
719
|
+
|
720
|
+
Invoke **cut_audio** (residing under **bin/cut_audio**) with the path
|
721
|
+
to an .mp3 file or another audio file. You will then enter the
|
722
|
+
**interactive menu** of class CutAudio, which allows you to do some
|
723
|
+
specific tasks related to cutting and merging audio files (see the
|
724
|
+
"help" section there, in interactive mode).
|
725
|
+
|
726
|
+
You may want to designate **start** and **stop** positions when in
|
727
|
+
interactive mode. You can do so via prefixing "s" and suffixing "e",
|
728
|
+
such as in the following way:
|
729
|
+
|
730
|
+
s10
|
731
|
+
e20
|
732
|
+
|
733
|
+
This would mean to "start at 10 seconds" and "end at 20 seconds". So
|
734
|
+
we will cut out the intermediate 10 seconds between these two points.
|
735
|
+
|
736
|
+
Via "play" you can play the audio file; I recommend having installed
|
737
|
+
**mplayer** or **mpv** for this task.
|
738
|
+
|
739
|
+
That way you can find out where you may wish to cut in the first place.
|
740
|
+
|
741
|
+
Once you have your start and end positions, you can run this command:
|
742
|
+
|
743
|
+
cut
|
744
|
+
|
745
|
+
This will cut out the selected subsection; in this case the part from
|
746
|
+
10 seconds to 20 seconds.
|
747
|
+
|
748
|
+
The number specifies how many seconds are to be used. This
|
749
|
+
can sometimes be a bit difficult to calculate in your head
|
750
|
+
e. g. how many seconds do 83 minutes entail to.
|
751
|
+
|
752
|
+
A pseudo-calculator can be queried within class CutAudio.
|
753
|
+
|
754
|
+
For example:
|
755
|
+
|
756
|
+
6*60
|
757
|
+
|
758
|
+
This would quickly show you that the result of this is 360
|
759
|
+
seconds (the input meant 6 minutes, if you think about it).
|
760
|
+
|
761
|
+
There are many more options available, so have a look at the
|
762
|
+
"help" section there. Keep in mind that CutAudio is a bit
|
763
|
+
complicated to use sometimes, and also has a very few bugs
|
764
|
+
as well (I did not get around to re-writing it, so for now
|
765
|
+
this has to suffice).
|
766
|
+
|
767
|
+
## Resizing a video
|
768
|
+
|
769
|
+
**ffmpeg** makes it easy to resize a video.
|
770
|
+
|
771
|
+
For example, say that you wish to re-scale an existing video
|
772
|
+
to the same ratio, but with fewer pixels, like 640. You could
|
773
|
+
use the following commandline invocation, with the **-vf**
|
774
|
+
flag, for this task:
|
775
|
+
|
776
|
+
ffmpeg -i input.mp4 -vf scale=640:-1 output.mp4
|
777
|
+
|
778
|
+
In this case, output.mp4 will have 640 pixels in width.
|
779
|
+
|
780
|
+
The strange -1 is simply a way to tell ffmpeg that the
|
781
|
+
same aspect ratio should be kept. That way ffmpeg will
|
782
|
+
calculate which ratio value should be used, in order
|
783
|
+
to retain the original width:height relation. You can
|
784
|
+
sometimes see that people use the wrong aspect ratio,
|
785
|
+
and then their video may look distorted.
|
786
|
+
|
787
|
+
MultimediaParadise also supports this via:
|
788
|
+
|
789
|
+
MultimediaParadise.scale_this_video()
|
790
|
+
MultimediaParadise.resize_this_vide()
|
791
|
+
|
792
|
+
The first argument is the path to the local input-file,
|
793
|
+
such as **input.mp4*.
|
794
|
+
|
795
|
+
After that a Hash can be used, where **height** and **width**
|
796
|
+
can be given.
|
797
|
+
|
798
|
+
MultimediaParadise.scale_this_video('input.mp4', height: 320, width: 220)
|
799
|
+
|
800
|
+
The argument for :width can be omitted, in which case -1 will be used
|
801
|
+
as default:
|
802
|
+
|
803
|
+
MultimediaParadise.scale_this_video('input.mp4', height: 320)
|
804
|
+
|
805
|
+
Would be the same as:
|
806
|
+
|
807
|
+
MultimediaParadise.scale_this_video('input.mp4', height: 320, height: -1)
|
808
|
+
|
809
|
+
The value for height: can be ignored too, in which case it will default
|
810
|
+
to 640 - but this default value may change one day in the future, so it
|
811
|
+
may be better to specify at the least one value here. But, ultimately,
|
812
|
+
if you don't care, this could also work:
|
813
|
+
|
814
|
+
MultimediaParadise.scale_this_video('input.mp4')
|
815
|
+
|
816
|
+
We may even omit the first argument in the future, one day, if we
|
817
|
+
assign a default file on the toplevel - but for the time being
|
818
|
+
(**September 2019**), the API is how it is and requires **at the
|
819
|
+
least one argument**.
|
820
|
+
|
821
|
+
## Creating a video out of an audio file, such as a .mp3 file
|
822
|
+
|
823
|
+
Via the API **MultimediaParadise.create_video_from_this_audio()**
|
824
|
+
you can "create" a video, from an audio file, such as a .mp3 file.
|
825
|
+
|
826
|
+
This requires a static image, which is the **second argument** to
|
827
|
+
that method.
|
828
|
+
|
829
|
+
Why did I add this method? I needed a way to upload .mp3 files
|
830
|
+
to a remote website but they had a **filter** removing .mp3 files;
|
831
|
+
they allowed for .mp4 files, so I converted it into a .mp4
|
832
|
+
file and that works. That is strange, since you can always
|
833
|
+
use **ffmpeg** to extract the .mp3 audio again - so I dont
|
834
|
+
understand the filter that prevents .mp3 upload but allows
|
835
|
+
.mp4 upload ...
|
836
|
+
|
837
|
+
Quite odd if you ask me.
|
838
|
+
|
839
|
+
**:\\**
|
840
|
+
|
841
|
+
**:/**
|
842
|
+
|
843
|
+
Anyway - here an example for the official API for this,
|
844
|
+
from within ruby:
|
845
|
+
|
846
|
+
this_audio_file = 'foobar.mp3'
|
847
|
+
this_image_file = '/FORENSIC_CAT.jpg'
|
848
|
+
MultimediaParadise.create_video_from_this_audio(this_audio_file, this_image_file)
|
849
|
+
|
850
|
+
## MovieSearcher
|
851
|
+
|
852
|
+
class MovieSearcher can be used to look up information about a
|
853
|
+
movie from http://www.omdbapi.com, if you have an API key.
|
854
|
+
|
855
|
+
The code written for this class is not great, but if all you
|
856
|
+
need is some quick commandline information then this class
|
857
|
+
could be used. It can be found at
|
858
|
+
**multimedia_paradise/video/movie_searcher.rb**.
|
859
|
+
|
860
|
+
Since as of 02.01.2020, an executable is now distributed
|
861
|
+
as well, called **movie_searcher** (under the **bin** subdirectory
|
862
|
+
of this gem).
|
863
|
+
|
864
|
+
I have aliased this executable to **videorating**, and then simply
|
865
|
+
do this on the commandline:
|
866
|
+
|
867
|
+
videorating tremors
|
868
|
+
|
869
|
+
You may need an API key called **OMDBAPI_API_KEY**. I recommend
|
870
|
+
you to set this; class MovieSearch will then try to pick it up
|
871
|
+
when it was set (see the ruby code for this).
|
872
|
+
|
873
|
+
## Deshaking videos
|
874
|
+
|
875
|
+
Ffmpeg has support for deshaking videos through a filter:
|
876
|
+
|
877
|
+
https://ffmpeg.org/ffmpeg-filters.html#deshake
|
878
|
+
|
879
|
+
The deshake-filter from ffmpeg helps remove camera shake from
|
880
|
+
hand-holding a camera.
|
881
|
+
|
882
|
+
The API for multimedia_paradise is the following:
|
883
|
+
|
884
|
+
MultimediaParadise.deshake(input_files_go_here)
|
885
|
+
MultimediaParadise.deshake('foobar.mp4')
|
886
|
+
|
887
|
+
## Missing video files
|
888
|
+
|
889
|
+
Via:
|
890
|
+
|
891
|
+
mpa --missing-videos?
|
892
|
+
|
893
|
+
I can determine which video files are missing locally.
|
894
|
+
|
895
|
+
This is evidently catered to my own use case, and a big .yml
|
896
|
+
file that I maintain. You may have to create your own .yml
|
897
|
+
file here if you wish to make use of this functionality.
|
898
|
+
|
899
|
+
## class ConvertAudioToVideoWithImage
|
900
|
+
|
901
|
+
**class ConvertAudioToVideoWithImage** allows you to "attach"
|
902
|
+
a static image file to an audio file, such as a <b>.mp3</b>
|
903
|
+
file.
|
904
|
+
|
905
|
+
This functionality depends on **ffmpeg**, so you need to
|
906
|
+
have ffmpeg available in order to make use of this class.
|
907
|
+
|
908
|
+
Two arguments are necessary to class ConvertAudioToVideoWithImage:
|
909
|
+
|
910
|
+
(1) first, the audio-file
|
911
|
+
(2) second, the image file that you wish to use
|
912
|
+
|
913
|
+
You can also use the following toplevel-method:
|
914
|
+
|
915
|
+
MultimediaParadise.to_avi_with_this_image()
|
916
|
+
|
917
|
+
with the same parameter pattern.
|
918
|
+
|
919
|
+
To give you a specific example - say that you have your .mp3
|
920
|
+
file at:
|
921
|
+
|
922
|
+
/Depot/j/foobar.mp3
|
923
|
+
|
924
|
+
And your image at:
|
925
|
+
|
926
|
+
/Depot/Images/foobar.png
|
927
|
+
|
928
|
+
Then the proper way to use the **toplevel-method** would be:
|
929
|
+
|
930
|
+
MultimediaParadise.to_avi_with_this_image('/Depot/j/foobar.mp3','/Depot/Images/foobar.png')
|
931
|
+
|
932
|
+
It does not have to be an **.avi** file though. You can also
|
933
|
+
use a .mp4 file via:
|
934
|
+
|
935
|
+
MultimediaParadise.to_mp4_with_this_image('foo.mp3','bar.png')
|
936
|
+
|
937
|
+
The latter method can also be used from the commandline via:
|
938
|
+
|
939
|
+
convert_audio_to_mp4video_with_image a.mp3 b.png
|
940
|
+
|
941
|
+
Remember that the audio file comes first, and the image file
|
942
|
+
comes last.
|
943
|
+
|
944
|
+
## Removing the last second of an audio file
|
945
|
+
|
946
|
+
If you just need to quickly chop off the last 1 second from
|
947
|
+
an audio file then you can use this API:
|
948
|
+
|
949
|
+
MultimediaParadise::RemoveLastSecond.new(ARGV)
|
950
|
+
MultimediaParadise::RemoveLastSecond.new('foobar.mp3')
|
951
|
+
|
952
|
+
## Encoding a video via MultimediaParadise
|
953
|
+
|
954
|
+
You can use the toplevel method called **MultimediaParadise.encode_this_video()**
|
955
|
+
to encode a video.
|
956
|
+
|
957
|
+
By default CRF will be used, which is the **Constant Rate Factor**.
|
958
|
+
|
959
|
+
Support for two-pass encoding has not been added to MultimediParadise,
|
960
|
+
but you can read up on ffmpeg how to do this:
|
961
|
+
|
962
|
+
https://trac.ffmpeg.org/wiki/Encode/H.264
|
963
|
+
|
964
|
+
Example:
|
965
|
+
|
966
|
+
require 'multimedia_paradise/toplevel_methods/encode_this_video.rb'
|
967
|
+
MultimediaParadise.encode_this_video('foobar.avi')
|
968
|
+
|
969
|
+
The default output for this will be .mkv, which is the matroska container.
|
970
|
+
(Currently that method in MultimediaParadise does not allow for
|
971
|
+
another output format, in **June 2020**; but this may be changed in the
|
972
|
+
future in another release of this project.)
|
973
|
+
|
974
|
+
## MultimediaParadise.set_player_in_use()
|
975
|
+
|
976
|
+
The toplevel method **MultimediaParadise.set_player_in_use()** can
|
977
|
+
be used to set the main multimedia player (audio + video) in use
|
978
|
+
for the MultimediaProject. Normally I set this to **mplayer** or
|
979
|
+
**mpv**, but **vlc** or any other player could also be used here.
|
980
|
+
|
981
|
+
You can also quickly set to use **mpv** since as of the 30th
|
982
|
+
June 2020.
|
983
|
+
|
984
|
+
Usage example for permanently setting this:
|
985
|
+
|
986
|
+
multimedia_paradise --use-mpv
|
987
|
+
|
988
|
+
This will modify the content of a .yml file.
|
989
|
+
|
990
|
+
## Playlists
|
991
|
+
|
992
|
+
The **MultimediaParadise** project can generate **.m3u** files, as
|
993
|
+
long as they are simple, e. g. one entry per line. For the purpose
|
994
|
+
of the document here, we will call such **.m3u** files
|
995
|
+
**playlists**.
|
996
|
+
|
997
|
+
The class responsible for the creation of **.m3u** files is
|
998
|
+
class <b>MultimediaParadise::CreateM3uPlaylist</b>, residing
|
999
|
+
at the location <b>multimedia_paradise/audio/create_m3u_playlist.rb</b>
|
1000
|
+
within the **MultimediaParadise** project.
|
1001
|
+
|
1002
|
+
The primary objective of this class is to generate that
|
1003
|
+
**.m3u** text file. Of course you can do so easily without the
|
1004
|
+
project - just do a "ls" and pipe it into a file - but I wanted
|
1005
|
+
this functionality specifically within the project, so that I
|
1006
|
+
can automate the creation of playlists, including batch-uploading
|
1007
|
+
to other sites at a later time, such as for youtube and other
|
1008
|
+
sites.
|
1009
|
+
|
1010
|
+
I myself use this class to generate playlists for various different
|
1011
|
+
**song types** - be these **eurodance songs**, **trance songs**,
|
1012
|
+
**pop songs** and so forth. Once such a .m3u file has been
|
1013
|
+
(auto)generated, it could then be used for upload to an external
|
1014
|
+
site, as mentioned, such as to **youtube** or other websites that
|
1015
|
+
support such playlists. Of course in order for this to work you may
|
1016
|
+
need to provide valid URLs to these individual entries somehow. The
|
1017
|
+
primary use case for class <b>MultimediaParadise::CreateM3uPlaylist</b>
|
1018
|
+
is for **local audio files**, though.
|
1019
|
+
|
1020
|
+
The input to class <b>MultimediaParadise::CreateM3uPlaylist</b>
|
1021
|
+
should ideally be a **yaml file** describing your songs (at the
|
1022
|
+
least the path to these songs), but you could also use the **API**
|
1023
|
+
from within Ruby, naturally (and thus use a **ruby array** directly
|
1024
|
+
that is to be passed to the class; just pass this Array to **.new()**).
|
1025
|
+
|
1026
|
+
You can also use this simpler **toplevel method**, in ruby
|
1027
|
+
instead:
|
1028
|
+
|
1029
|
+
MultimediaParadise.create_m3u_playlist()
|
1030
|
+
|
1031
|
+
The **first argument** to this method should contain the **dataset**
|
1032
|
+
that you will use for the .m3u file that is to be autogenerated.
|
1033
|
+
This should be a simple Array.
|
1034
|
+
|
1035
|
+
You can, naturally, rename the .m3u file after it has been created,
|
1036
|
+
since a default name will be used - the generic name used for
|
1037
|
+
generation of the file will be **playlist.m3u**.
|
1038
|
+
|
1039
|
+
For my own custom dataset, e. g. to generate a playlist
|
1040
|
+
with good **tales-from-the-crypt** videos, I can just do:
|
1041
|
+
|
1042
|
+
playlist --tales-from-the-crypt
|
1043
|
+
|
1044
|
+
The MultimediaParadise project also comes with another class,
|
1045
|
+
called **class Playlist**, which has a different task. That
|
1046
|
+
**class Playlist** will handle audio-playlists, primarily. For
|
1047
|
+
example, it can play audio files at certain positions in
|
1048
|
+
the playlist.
|
1049
|
+
|
1050
|
+
Usage example from the commandline for this:
|
1051
|
+
|
1052
|
+
playlist 33,44,55
|
1053
|
+
|
1054
|
+
Would play the songs at position 33, then 44 and then 55. It
|
1055
|
+
is thus a very primitive sort of **jukebox**. See
|
1056
|
+
**playlist --help** for help options.
|
1057
|
+
|
1058
|
+
You can change positions in that playlist. To exchange position
|
1059
|
+
95 with position 94, you could use input like this:
|
1060
|
+
|
1061
|
+
playlist "95 -> 94"
|
1062
|
+
|
1063
|
+
This would mean to take the song at position 95 and move it
|
1064
|
+
to position 94. Conversely the song at position 94 will be
|
1065
|
+
moved to 95; this is thus ***an exchange operation***.
|
1066
|
+
|
1067
|
+
To show the entries of a playlist do:
|
1068
|
+
|
1069
|
+
playlist --show
|
1070
|
+
|
1071
|
+
## The file video_collection.yml
|
1072
|
+
|
1073
|
+
The file video_collection.yml, which is distributed by this
|
1074
|
+
project, can be used to denote different videos files.
|
1075
|
+
|
1076
|
+
This is catered to my own use case, but you can adapt this
|
1077
|
+
file to your own use case.
|
1078
|
+
|
1079
|
+
I use the file to automatically handle local videos, such
|
1080
|
+
as batch-renaming or ensuring that everything is correct,
|
1081
|
+
and so on.
|
1082
|
+
|
1083
|
+
To determine the default (assumed) location, try this
|
1084
|
+
method:
|
1085
|
+
|
1086
|
+
MultimediaParadise.file_video_collection
|
1087
|
+
|
1088
|
+
## Converting a video file to the corresponding images
|
1089
|
+
|
1090
|
+
Via:
|
1091
|
+
|
1092
|
+
MultimediaParadise.video_to_images
|
1093
|
+
|
1094
|
+
you can convert a video to its corresponding images.
|
1095
|
+
|
1096
|
+
See the file **multimedia_paradise/toplevel_methods/conversion.rb**
|
1097
|
+
for more information about that functionality - it is made possible
|
1098
|
+
thanks to ffmpeg.
|
1099
|
+
|
1100
|
+
## Working with subtitles
|
1101
|
+
|
1102
|
+
You can embed subtitles into a video directly. This subsection
|
1103
|
+
explains how this can be done.
|
1104
|
+
|
1105
|
+
Embedding subtitles (text files such as .srt files) into a video
|
1106
|
+
file is trivial with ffmpeg. The multimedia_paradise project
|
1107
|
+
supports this as well, via the following toplevel API:
|
1108
|
+
|
1109
|
+
require 'multimedia_paradise/toplevel_methods/subtitles.rb'
|
1110
|
+
MultimediaParadise.embed_this_subtitle_onto_that_video('foo.srt','bar.avi')
|
1111
|
+
|
1112
|
+
If you wish to remove a subtitle from a video file, try this:
|
1113
|
+
|
1114
|
+
MultimediaParadise.remove_subtitles_from_this_video_file('foobar.mp4')
|
1115
|
+
|
1116
|
+
Since as of October 2020, a file called **bin/remove_subtitles**
|
1117
|
+
is made available as well, for commandline usage.
|
1118
|
+
|
1119
|
+
## Graphical User Interface (GUI)
|
1120
|
+
|
1121
|
+
There is some ruby-gtk code for the MultimediaParadise available and
|
1122
|
+
distributed within this gem, mostly for **gtk2** right now. It is
|
1123
|
+
planned to transition into ruby-gtk3 at a later point, but this depends
|
1124
|
+
on many factors, including how well-polished the **gtk_paradise**
|
1125
|
+
gem is, since I use that gem a lot.
|
1126
|
+
|
1127
|
+
Note that in general a lot of the GUI parts of MultimediaParadise
|
1128
|
+
is in a **very experimental** state, subject to change, and possibly
|
1129
|
+
filled with bugs - but you can have a look at e. g. the **gtk-radio**
|
1130
|
+
part.
|
1131
|
+
|
1132
|
+
That one even has a stop/play/resume button, and an increase/decrease
|
1133
|
+
in audio volume, if ALSA is available. It lists some radio stations,
|
1134
|
+
based on a .yml file - you could use the same format and supply
|
1135
|
+
your own .yml file there, but support for this has not yet been
|
1136
|
+
added (need to re-think that part).
|
1137
|
+
|
1138
|
+
Evidently LOTS of features are missing there that might make sense
|
1139
|
+
for a GUI about radio-streams, and some bugs may exist as well, so
|
1140
|
+
don't use any of these widgets in "production" or for anything
|
1141
|
+
serious. I will, however had, try to make the GUI components,
|
1142
|
+
including the www-interfaces, more useful over the coming months
|
1143
|
+
and years, as time (and motivation) permits.
|
1144
|
+
|
1145
|
+
Note that for the first 10 buttons, you can access them via the
|
1146
|
+
keyboard too - by pressing ALT+number, such as **ALT+1** for
|
1147
|
+
the first button.
|
1148
|
+
|
1149
|
+
## Additional documentation and information
|
1150
|
+
|
1151
|
+
In October 2020 I decided to publish all my collected local video
|
1152
|
+
and audio related content, which is made available through
|
1153
|
+
oldschool .cgi files. To make this even more complicated, most
|
1154
|
+
of these files are written in german so these have only a limited
|
1155
|
+
use for most people. Still, I think some of the information
|
1156
|
+
contained therein may be useful for other people, which is why
|
1157
|
+
I will publish this slowly over the coming months. Furthermore,
|
1158
|
+
some yaml-files are part of this, and publishing yaml files is
|
1159
|
+
useful, as it is decoupled from the programming language
|
1160
|
+
(in this case **ruby**).
|
1161
|
+
|
1162
|
+
|
1163
|
+
## Contact information
|
1164
|
+
|
1165
|
+
If your creative mind has ideas and specific suggestions to make this
|
1166
|
+
gem more useful in general, feel free to drop me an email at any
|
1167
|
+
time, via:
|
1168
|
+
|
1169
|
+
shevegen@gmail.com
|
1170
|
+
|
1171
|
+
(Do keep in mind that responding to emails may take some time, depending
|
1172
|
+
on the amount of work I may have at that moment, due to reallife. I will,
|
1173
|
+
however had, read feedback. Patches and code changes are welcome too
|
1174
|
+
of course, as long as they are in the spirit of the project at
|
1175
|
+
hand, e. g. fitting to the general theme.)
|
1176
|
+
|
1177
|
+
Thank you.
|