id3taginator 0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.idea/.gitignore +8 -0
- data/.idea/ID3Taginator.iml +73 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.rspec +3 -0
- data/.rubocop.yml +26 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +21 -0
- data/README.md +408 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/id3taginator.gemspec +37 -0
- data/lib/id3taginator/audio_file.rb +136 -0
- data/lib/id3taginator/errors/id3_tag_error.rb +12 -0
- data/lib/id3taginator/extensions/argument_check.rb +88 -0
- data/lib/id3taginator/extensions/comparable.rb +28 -0
- data/lib/id3taginator/extensions/encodable.rb +215 -0
- data/lib/id3taginator/extensions/optionable.rb +73 -0
- data/lib/id3taginator/frames/buffer/entities/buffer.rb +26 -0
- data/lib/id3taginator/frames/buffer/rbuf_recommended_buffer_size_frame.rb +59 -0
- data/lib/id3taginator/frames/buffer_frames.rb +32 -0
- data/lib/id3taginator/frames/comment/comm_comment_frame.rb +56 -0
- data/lib/id3taginator/frames/comment/entities/comment.rb +26 -0
- data/lib/id3taginator/frames/comment_frames.rb +42 -0
- data/lib/id3taginator/frames/count/entities/popularimeter.rb +26 -0
- data/lib/id3taginator/frames/count/pcnt_play_counter_frame.rb +40 -0
- data/lib/id3taginator/frames/count/popm_popularimeter_frame.rb +52 -0
- data/lib/id3taginator/frames/count_frames.rb +51 -0
- data/lib/id3taginator/frames/custom_frame.rb +39 -0
- data/lib/id3taginator/frames/custom_frames.rb +54 -0
- data/lib/id3taginator/frames/encryption/aenc_audio_encryption.rb +54 -0
- data/lib/id3taginator/frames/encryption/encr_encryption_method_frame.rb +49 -0
- data/lib/id3taginator/frames/encryption/entities/audio_encryption.rb +28 -0
- data/lib/id3taginator/frames/encryption/entities/encryption_method.rb +26 -0
- data/lib/id3taginator/frames/encryption_frames.rb +77 -0
- data/lib/id3taginator/frames/frameable.rb +75 -0
- data/lib/id3taginator/frames/geo/entities/encapsulated_object.rb +28 -0
- data/lib/id3taginator/frames/geo/geob_general_encapsulated_object_frame.rb +59 -0
- data/lib/id3taginator/frames/geo_frames.rb +41 -0
- data/lib/id3taginator/frames/grouping/entities/group_identification.rb +26 -0
- data/lib/id3taginator/frames/grouping/grid_group_identification_frame.rb +49 -0
- data/lib/id3taginator/frames/grouping/grp1_grouping_frame.rb +40 -0
- data/lib/id3taginator/frames/grouping_frames.rb +61 -0
- data/lib/id3taginator/frames/has_id.rb +51 -0
- data/lib/id3taginator/frames/id3v23_frame_flags.rb +64 -0
- data/lib/id3taginator/frames/id3v24_frame_flags.rb +80 -0
- data/lib/id3taginator/frames/id3v2_frame.rb +249 -0
- data/lib/id3taginator/frames/id3v2_frame_factory.rb +98 -0
- data/lib/id3taginator/frames/ipl/entities/involved_person.rb +24 -0
- data/lib/id3taginator/frames/ipl/ipls_involved_people_frame.rb +48 -0
- data/lib/id3taginator/frames/ipl_frames.rb +31 -0
- data/lib/id3taginator/frames/lyrics/entities/unsync_lyrics.rb +26 -0
- data/lib/id3taginator/frames/lyrics/uslt_unsync_lyrics_frame.rb +56 -0
- data/lib/id3taginator/frames/lyrics_frames.rb +42 -0
- data/lib/id3taginator/frames/mcdi/mcdi_music_cd_identifier_frame.rb +40 -0
- data/lib/id3taginator/frames/mcdi_frames.rb +28 -0
- data/lib/id3taginator/frames/picture/apic_picture_frame.rb +106 -0
- data/lib/id3taginator/frames/picture/entities/picture.rb +32 -0
- data/lib/id3taginator/frames/picture_frames.rb +51 -0
- data/lib/id3taginator/frames/private/entities/private_frame.rb +24 -0
- data/lib/id3taginator/frames/private/priv_private_frame.rb +45 -0
- data/lib/id3taginator/frames/private_frames.rb +40 -0
- data/lib/id3taginator/frames/text/entities/copyright.rb +24 -0
- data/lib/id3taginator/frames/text/entities/date.rb +24 -0
- data/lib/id3taginator/frames/text/entities/part_of_set.rb +24 -0
- data/lib/id3taginator/frames/text/entities/time.rb +24 -0
- data/lib/id3taginator/frames/text/entities/track_number.rb +24 -0
- data/lib/id3taginator/frames/text/entities/user_info.rb +24 -0
- data/lib/id3taginator/frames/text/talb_album_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tbpm_bpm_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tcom_composer_frame.rb +42 -0
- data/lib/id3taginator/frames/text/tcon_genre_frame.rb +104 -0
- data/lib/id3taginator/frames/text/tcop_copyright_frame.rb +55 -0
- data/lib/id3taginator/frames/text/tdat_date_frame.rb +60 -0
- data/lib/id3taginator/frames/text/tdly_playlist_delay_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tenc_encoded_by_frame.rb +40 -0
- data/lib/id3taginator/frames/text/text_writers_frame.rb +43 -0
- data/lib/id3taginator/frames/text/tflt_file_type_frame.rb +71 -0
- data/lib/id3taginator/frames/text/time_time_frame.rb +60 -0
- data/lib/id3taginator/frames/text/tit1_content_group_description_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tit2_title_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tit3_subtitle_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tkey_initial_key_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tlan_language_frame.rb +48 -0
- data/lib/id3taginator/frames/text/tlen_length_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tmed_media_type_frame.rb +40 -0
- data/lib/id3taginator/frames/text/toal_original_album_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tofn_original_filename_frame.rb +40 -0
- data/lib/id3taginator/frames/text/toly_original_writers_frame.rb +43 -0
- data/lib/id3taginator/frames/text/tope_original_artists_frame.rb +43 -0
- data/lib/id3taginator/frames/text/tory_original_release_year_frame.rb +42 -0
- data/lib/id3taginator/frames/text/town_file_owner_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tpe1_artist_frame.rb +43 -0
- data/lib/id3taginator/frames/text/tpe2_album_artist_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tpe3_conductor_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tpe4_modified_by_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tpos_part_of_set_frame.rb +50 -0
- data/lib/id3taginator/frames/text/tpub_publisher_frame.rb +40 -0
- data/lib/id3taginator/frames/text/trck_track_number_frame.rb +50 -0
- data/lib/id3taginator/frames/text/trda_recording_dates_frame.rb +42 -0
- data/lib/id3taginator/frames/text/trsn_internet_radio_station_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tsiz_size_frame.rb +41 -0
- data/lib/id3taginator/frames/text/tsoa_album_sort_order_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tsop_performer_sort_order_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tsot_title_sort_order_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tsrc_isrc_frame.rb +40 -0
- data/lib/id3taginator/frames/text/tsse_encoder_frame.rb +40 -0
- data/lib/id3taginator/frames/text/txxx_user_text_info_frame.rb +51 -0
- data/lib/id3taginator/frames/text/tyer_year_frame.rb +42 -0
- data/lib/id3taginator/frames/text_frames.rb +840 -0
- data/lib/id3taginator/frames/tos/entities/ownership.rb +26 -0
- data/lib/id3taginator/frames/tos/entities/terms_of_use.rb +24 -0
- data/lib/id3taginator/frames/tos/owne_ownership_frame.rb +53 -0
- data/lib/id3taginator/frames/tos/user_terms_of_use_frame.rb +49 -0
- data/lib/id3taginator/frames/tos_frames.rb +54 -0
- data/lib/id3taginator/frames/ufid/entities/ufid_info.rb +24 -0
- data/lib/id3taginator/frames/ufid/ufid_unique_file_identifier_frame.rb +47 -0
- data/lib/id3taginator/frames/ufid_frames.rb +40 -0
- data/lib/id3taginator/frames/url/entities/user_info.rb +24 -0
- data/lib/id3taginator/frames/url/wcom_commercial_url_frame.rb +40 -0
- data/lib/id3taginator/frames/url/wcop_copyright_url_frame.rb +40 -0
- data/lib/id3taginator/frames/url/woaf_official_file_webpage_frame.rb +40 -0
- data/lib/id3taginator/frames/url/woar_official_artist_webpage_frame.rb +40 -0
- data/lib/id3taginator/frames/url/woas_official_source_webpage_frame.rb +40 -0
- data/lib/id3taginator/frames/url/wors_official_radio_station_homepage_frame.rb +40 -0
- data/lib/id3taginator/frames/url/wpay_payment_url_frame.rb +40 -0
- data/lib/id3taginator/frames/url/wpub_official_publisher_webpage_frame.rb +40 -0
- data/lib/id3taginator/frames/url/wxxx_user_url_link_frame.rb +50 -0
- data/lib/id3taginator/frames/url_frames.rb +195 -0
- data/lib/id3taginator/genres.rb +168 -0
- data/lib/id3taginator/header/id3v23_extended_header.rb +37 -0
- data/lib/id3taginator/header/id3v24_extended_header.rb +100 -0
- data/lib/id3taginator/header/id3v2_flags.rb +64 -0
- data/lib/id3taginator/id3v1_tag.rb +156 -0
- data/lib/id3taginator/id3v22_tag.rb +30 -0
- data/lib/id3taginator/id3v23_tag.rb +63 -0
- data/lib/id3taginator/id3v24_tag.rb +75 -0
- data/lib/id3taginator/id3v2_tag.rb +241 -0
- data/lib/id3taginator/options/options.rb +33 -0
- data/lib/id3taginator/util/compress_util.rb +25 -0
- data/lib/id3taginator/util/math_util.rb +68 -0
- data/lib/id3taginator/util/sync_util.rb +65 -0
- data/lib/id3taginator.rb +449 -0
- metadata +198 -0
|
@@ -0,0 +1,840 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Id3Taginator
|
|
4
|
+
module Frames
|
|
5
|
+
module TextFrames
|
|
6
|
+
include Frames::Frameable
|
|
7
|
+
|
|
8
|
+
# extracts the album (TALB/TAL)
|
|
9
|
+
#
|
|
10
|
+
# @return [String, nil] returns the Album
|
|
11
|
+
def album
|
|
12
|
+
find_frame(Text::AlbumFrame.frame_id(@major_version, @options))&.album
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# sets the album (TALB/TAL)
|
|
16
|
+
#
|
|
17
|
+
# @param album [String] the album
|
|
18
|
+
def album=(album)
|
|
19
|
+
set_frame_fields(Text::AlbumFrame, [:@album], album)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# removes the album frame
|
|
23
|
+
def remove_album
|
|
24
|
+
@frames.delete_if { |f| f.frame_id == Text::AlbumFrame.frame_id(@major_version, @options) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# extracts the album (TSOA)
|
|
28
|
+
#
|
|
29
|
+
# @return [String, nil] returns the Album Sort Order
|
|
30
|
+
def album_sort_order
|
|
31
|
+
find_frame(Text::AlbumSortOrderFrame.frame_id(@major_version, @options))&.album
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# sets the album name used for sorting (TSOA)
|
|
35
|
+
#
|
|
36
|
+
# @param album [String] the album for sorting
|
|
37
|
+
def album_sort_order=(album)
|
|
38
|
+
set_frame_fields(Text::AlbumSortOrderFrame, [:@album], album)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# removes the album sort order frame
|
|
42
|
+
def remove_album_sort_order
|
|
43
|
+
@frames.delete_if { |f| f.frame_id == Text::AlbumSortOrderFrame.frame_id(@major_version, @options) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# extracts the performer sort order (TSOP)
|
|
47
|
+
#
|
|
48
|
+
# @return [String, nil] returns the Performer Sort Order
|
|
49
|
+
def performer_sort_order
|
|
50
|
+
find_frame(Text::PerformerSortOrderFrame.frame_id(@major_version, @options))&.performer
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# sets the performer used for sorting (TSOP)
|
|
54
|
+
#
|
|
55
|
+
# @param performer [String] the performer for sorting
|
|
56
|
+
def performer_sort_order=(performer)
|
|
57
|
+
set_frame_fields(Text::PerformerSortOrderFrame, [:@performer], performer)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# removes the performer sort order frame
|
|
61
|
+
def remove_performer_sort_order
|
|
62
|
+
@frames.delete_if { |f| f.frame_id == Text::PerformerSortOrderFrame.frame_id(@major_version, @options) }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# extracts the title sort order (TSOT)
|
|
66
|
+
#
|
|
67
|
+
# @return [String, nil] returns the Title Sort Order
|
|
68
|
+
def title_sort_order
|
|
69
|
+
find_frame(Text::TitleSortOrderFrame.frame_id(@major_version, @options))&.title
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# sets the title used for sorting (TSOT)
|
|
73
|
+
#
|
|
74
|
+
# @param title [String] the title for sorting
|
|
75
|
+
def title_sort_order=(title)
|
|
76
|
+
set_frame_fields(Text::TitleSortOrderFrame, [:@title], title)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# removes the title sort order frame
|
|
80
|
+
def remove_title_sort_order
|
|
81
|
+
@frames.delete_if { |f| f.frame_id == Text::TitleSortOrderFrame.frame_id(@major_version, @options) }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# extracts the bpm (TBPM/TBP)
|
|
85
|
+
#
|
|
86
|
+
# @return [String, nil] returns the bpm
|
|
87
|
+
def bpm
|
|
88
|
+
find_frame(Text::BPMFrame.frame_id(@major_version, @options))&.bpm
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# sets the bpm (TBPM/TBP)
|
|
92
|
+
#
|
|
93
|
+
# @param bpm [String, Integer] the bpm
|
|
94
|
+
def bpm=(bpm)
|
|
95
|
+
set_frame_fields(Text::BPMFrame, [:@bpm], bpm)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# removes the bpm frame
|
|
99
|
+
def remove_bpm
|
|
100
|
+
@frames.delete_if { |f| f.frame_id == Text::BPMFrame.frame_id(@major_version, @options) }
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# extracts the composer (TCOM/TCM)
|
|
104
|
+
#
|
|
105
|
+
# @return [Array<String>] returns the composer
|
|
106
|
+
def composers
|
|
107
|
+
frame = find_frame(Text::ComposerFrame.frame_id(@major_version, @options))
|
|
108
|
+
return [] if frame.nil?
|
|
109
|
+
|
|
110
|
+
frame.composers
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# sets the composers (TCOM/TCM)
|
|
114
|
+
#
|
|
115
|
+
# @param composers [Array<String>, String] the composers (or one composer)
|
|
116
|
+
def composers=(composers)
|
|
117
|
+
set_frame_fields(Text::ComposerFrame, [:@composers], composers)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# removes the composers frame
|
|
121
|
+
def remove_composers
|
|
122
|
+
@frames.delete_if { |f| f.frame_id == Text::ComposerFrame.frame_id(@major_version, @options) }
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# extracts the genres (TCON/TCO)
|
|
126
|
+
#
|
|
127
|
+
# @return [Array<String>] returns the composer
|
|
128
|
+
def genres
|
|
129
|
+
frame = find_frame(Text::GenreFrame.frame_id(@major_version, @options))
|
|
130
|
+
return [] if frame.nil?
|
|
131
|
+
|
|
132
|
+
frame.genres
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# sets the genres (TCON/TCO)
|
|
136
|
+
#
|
|
137
|
+
# @param genres [Array<String, Symbol>] the genres as String or Symbols
|
|
138
|
+
def genres=(genres)
|
|
139
|
+
set_frame_fields(Text::GenreFrame, [:@genres], genres)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# removes the genre frame
|
|
143
|
+
def remove_genres
|
|
144
|
+
@frames.delete_if { |f| f.frame_id == Text::GenreFrame.frame_id(@major_version, @options) }
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# extracts the copyright (TCOP/TCR)
|
|
148
|
+
#
|
|
149
|
+
# @return [Frames::Text::Entities::Copyright, nil] returns the copyright
|
|
150
|
+
def copyright
|
|
151
|
+
frame = find_frame(Text::CopyrightFrame.frame_id(@major_version, @options))
|
|
152
|
+
return nil if frame.nil?
|
|
153
|
+
|
|
154
|
+
Text::Entities::Copyright.new(frame.year, frame.holder)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# sets the copyright (TCOP/TCR)
|
|
158
|
+
#
|
|
159
|
+
# @param copyright [Frames::Text::Entities::Copyright] the copyright
|
|
160
|
+
def copyright=(copyright)
|
|
161
|
+
set_frame_fields(Text::CopyrightFrame, %i[@year @holder], copyright.year, copyright.holder)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# removes the copyright frame
|
|
165
|
+
def remove_copyright
|
|
166
|
+
@frames.delete_if { |f| f.frame_id == Text::CopyrightFrame.frame_id(@major_version, @options) }
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# extracts the date (TDAT/TDA)
|
|
170
|
+
#
|
|
171
|
+
# @return [Frames::Text::Entities::Date, nil] returns the date
|
|
172
|
+
def date
|
|
173
|
+
frame = find_frame(Text::DateFrame.frame_id(@major_version, @options))
|
|
174
|
+
return nil if frame.nil?
|
|
175
|
+
|
|
176
|
+
Text::Entities::Date.new(frame.month, frame.day)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# sets the date (TDAT/TDA)
|
|
180
|
+
#
|
|
181
|
+
# @param date [Frames::Text::Entities::Date] the date
|
|
182
|
+
def date=(date)
|
|
183
|
+
set_frame_fields(Text::DateFrame, %i[@month @day], date.month, date.day)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# removes the date frame
|
|
187
|
+
def remove_date
|
|
188
|
+
@frames.delete_if { |f| f.frame_id == Text::DateFrame.frame_id(@major_version, @options) }
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# extracts the playlist delay (TDLY/TDY)
|
|
192
|
+
#
|
|
193
|
+
# @return [String, nil] returns the date
|
|
194
|
+
def playlist_delay
|
|
195
|
+
find_frame(Text::PlaylistDelayFrame.frame_id(@major_version, @options))&.delay
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# sets the playlist delay (TDLY/TDY)
|
|
199
|
+
#
|
|
200
|
+
# @param delay_in_ms [String, Integer] the delay in ms
|
|
201
|
+
def playlist_delay=(delay_in_ms)
|
|
202
|
+
set_frame_fields(Text::PlaylistDelayFrame, [:@delay], delay_in_ms)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# removes the playlist delay frame
|
|
206
|
+
def remove_playlist_delay
|
|
207
|
+
@frames.delete_if { |f| f.frame_id == Text::PlaylistDelayFrame.frame_id(@major_version, @options) }
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# extracts the encoded by (TENC/TEN)
|
|
211
|
+
#
|
|
212
|
+
# @return [String, nil] returns the encoded by
|
|
213
|
+
def encoded_by
|
|
214
|
+
find_frame(Text::EncodedByFrame.frame_id(@major_version, @options))&.encoded_by
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# sets the playlist delay (TENC/TEN)
|
|
218
|
+
#
|
|
219
|
+
# @param encoded_by [String] the encoded by
|
|
220
|
+
def encoded_by=(encoded_by)
|
|
221
|
+
set_frame_fields(Text::EncodedByFrame, [:@encoded_by], encoded_by)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# removes the encoded by frame
|
|
225
|
+
def remove_encoded_by
|
|
226
|
+
@frames.delete_if { |f| f.frame_id == Text::EncodedByFrame.frame_id(@major_version, @options) }
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# extracts the writers (TEXT/TXT)
|
|
230
|
+
#
|
|
231
|
+
# @return [Array<String>] returns the writers
|
|
232
|
+
def writers
|
|
233
|
+
frame = find_frame(Text::WritersFrame.frame_id(@major_version, @options))
|
|
234
|
+
return [] if frame.nil?
|
|
235
|
+
|
|
236
|
+
frame.writers
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# sets the writers (TENC/TEN)
|
|
240
|
+
#
|
|
241
|
+
# @param writers [Array<String>, String] the writers
|
|
242
|
+
def writers=(writers)
|
|
243
|
+
set_frame_fields(Text::WritersFrame, [:@writers], writers)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# removes the writers frame
|
|
247
|
+
def remove_writers
|
|
248
|
+
@frames.delete_if { |f| f.frame_id == Text::WritersFrame.frame_id(@major_version, @options) }
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# extracts the file type (TFLT/TFT)
|
|
252
|
+
#
|
|
253
|
+
# @return [String, nil] returns the file type
|
|
254
|
+
def file_type
|
|
255
|
+
find_frame(Text::FileTypeFrame.frame_id(@major_version, @options))&.file_type
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# sets the file type (TFLT/TFT)
|
|
259
|
+
#
|
|
260
|
+
# @param file_type [String] the file type
|
|
261
|
+
def file_type=(file_type)
|
|
262
|
+
set_frame_fields(Text::FileTypeFrame, [:@file_type], file_type)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# removes the file type frame
|
|
266
|
+
def remove_file_type
|
|
267
|
+
@frames.delete_if { |f| f.frame_id == Text::FileTypeFrame.frame_id(@major_version, @options) }
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# extracts the time (TIME/TIM)
|
|
271
|
+
#
|
|
272
|
+
# @return [Frames::Text::Entities::Time, nil] returns the time
|
|
273
|
+
def time
|
|
274
|
+
frame = find_frame(Text::TimeFrame.frame_id(@major_version, @options))
|
|
275
|
+
return nil if frame.nil?
|
|
276
|
+
|
|
277
|
+
Text::Entities::Time.new(frame.hours, frame.minutes)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# sets the time (TIME/TIM)
|
|
281
|
+
#
|
|
282
|
+
# @param time [Frames::Text::Entities::Time] the time
|
|
283
|
+
def time=(time)
|
|
284
|
+
set_frame_fields(Text::TimeFrame, %i[@hours @minutes], time.hours, time.minutes)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# removes the time frame
|
|
288
|
+
def remove_time
|
|
289
|
+
@frames.delete_if { |f| f.frame_id == Text::TimeFrame.frame_id(@major_version, @options) }
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# extracts the content group description (TIT1/TT1)
|
|
293
|
+
#
|
|
294
|
+
# @return [String, nil] returns content group description
|
|
295
|
+
def content_group_description
|
|
296
|
+
find_frame(Text::ContentGroupDescriptionFrame.frame_id(@major_version, @options))&.content_description
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# sets the content group description (TIT1/TT1)
|
|
300
|
+
#
|
|
301
|
+
# @param content_group_description [String] the content group description
|
|
302
|
+
def content_group_description=(content_group_description)
|
|
303
|
+
set_frame_fields(Text::ContentGroupDescriptionFrame, [:@content_group_description], content_group_description)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# removes the content group description frame
|
|
307
|
+
def remove_content_group_description
|
|
308
|
+
@frames.delete_if { |f| f.frame_id == Text::ContentGroupDescriptionFrame.frame_id(@major_version, @options) }
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# extracts the title (TIT2/TT2)
|
|
312
|
+
#
|
|
313
|
+
# @return [String, nil] returns title
|
|
314
|
+
def title
|
|
315
|
+
find_frame(Text::TitleFrame.frame_id(@major_version, @options))&.title
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# sets the title (TIT2/TT2)
|
|
319
|
+
#
|
|
320
|
+
# @param title [String] the title
|
|
321
|
+
def title=(title)
|
|
322
|
+
set_frame_fields(Text::TitleFrame, [:@title], title)
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# removes the title frame
|
|
326
|
+
def remove_title
|
|
327
|
+
@frames.delete_if { |f| f.frame_id == Text::TitleFrame.frame_id(@major_version, @options) }
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
# extracts the subtitle (TIT3/TT3)
|
|
331
|
+
#
|
|
332
|
+
# @return [String, nil] returns subtitle
|
|
333
|
+
def subtitle
|
|
334
|
+
find_frame(Text::SubtitleFrame.frame_id(@major_version, @options))&.subtitle
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# sets the subtitle (TIT3/TT3)
|
|
338
|
+
#
|
|
339
|
+
# @param subtitle [String] the subtitle
|
|
340
|
+
def subtitle=(subtitle)
|
|
341
|
+
set_frame_fields(Text::SubtitleFrame, [:@subtitle], subtitle)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
# removes the subtitle frame
|
|
345
|
+
def remove_subtitle
|
|
346
|
+
@frames.delete_if { |f| f.frame_id == Text::SubtitleFrame.frame_id(@major_version, @options) }
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
# extracts the initial key (<= 3 characters) (TKEY/TKE)
|
|
350
|
+
#
|
|
351
|
+
# @return [String, nil] returns the initial key
|
|
352
|
+
def initial_key
|
|
353
|
+
find_frame(Text::InitialKeyFrame.frame_id(@major_version, @options))&.initial_key
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
# sets the initial key (<= 3 characters) (TKEY/TKE)
|
|
357
|
+
#
|
|
358
|
+
# @param initial_key [String] the initial key (<= 3 characters)
|
|
359
|
+
def initial_key=(initial_key)
|
|
360
|
+
set_frame_fields(Text::InitialKeyFrame, [:@initial_key], initial_key)
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
# removes the initial key frame
|
|
364
|
+
def remove_initial_key
|
|
365
|
+
@frames.delete_if { |f| f.frame_id == Text::InitialKeyFrame.frame_id(@major_version, @options) }
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# extracts the languages (TLAN/TLA)
|
|
369
|
+
#
|
|
370
|
+
# @return [Array<String>] returns the languages
|
|
371
|
+
def languages
|
|
372
|
+
frame = find_frame(Text::LanguageFrame.frame_id(@major_version, @options))
|
|
373
|
+
return [] if frame.nil?
|
|
374
|
+
|
|
375
|
+
frame.languages
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
# sets the languages (TLAN/TLA)
|
|
379
|
+
#
|
|
380
|
+
# @param languages [Array<String>, String] the languages (3 character code languages)
|
|
381
|
+
def languages=(languages)
|
|
382
|
+
set_frame_fields(Text::LanguageFrame, [:@languages], languages)
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# removes the languages frame
|
|
386
|
+
def remove_languages
|
|
387
|
+
@frames.delete_if { |f| f.frame_id == Text::LanguageFrame.frame_id(@major_version, @options) }
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
# extracts the length in seconds (TLEN/TLE)
|
|
391
|
+
#
|
|
392
|
+
# @return [String, nil] returns the length
|
|
393
|
+
def length
|
|
394
|
+
find_frame(Text::LengthFrame.frame_id(@major_version, @options))&.length
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
# sets the length in seconds (TLEN/TLE)
|
|
398
|
+
#
|
|
399
|
+
# @param length [String, Integer] the length in seconds
|
|
400
|
+
def length=(length)
|
|
401
|
+
set_frame_fields(Text::LengthFrame, [:@length], length)
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
# removes the length frame
|
|
405
|
+
def remove_length
|
|
406
|
+
@frames.delete_if { |f| f.frame_id == Text::LengthFrame.frame_id(@major_version, @options) }
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# extracts the media type (TMED/TMT)
|
|
410
|
+
#
|
|
411
|
+
# @return [String, nil] returns the media type
|
|
412
|
+
def media_type
|
|
413
|
+
find_frame(Text::MediaTypeFrame.frame_id(@major_version, @options))&.media_type
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
# sets the media type (TMED/TMT)
|
|
417
|
+
#
|
|
418
|
+
# @param media_type [String] the media type
|
|
419
|
+
def media_type=(media_type)
|
|
420
|
+
set_frame_fields(Text::MediaTypeFrame, [:@media_type], media_type)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
# removes the media type frame
|
|
424
|
+
def remove_media_type
|
|
425
|
+
@frames.delete_if { |f| f.frame_id == Text::MediaTypeFrame.frame_id(@major_version, @options) }
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
# extracts the original album (TOAL/TOT)
|
|
429
|
+
#
|
|
430
|
+
# @return [String, nil] returns the original album
|
|
431
|
+
def original_album
|
|
432
|
+
find_frame(Text::OriginalAlbumFrame.frame_id(@major_version, @options))&.original_album
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
# sets the original album (TOAL/TOT)
|
|
436
|
+
#
|
|
437
|
+
# @param original_album [String] the original album
|
|
438
|
+
def original_album=(original_album)
|
|
439
|
+
set_frame_fields(Text::OriginalAlbumFrame, [:@original_album], original_album)
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
# removes the original album frame
|
|
443
|
+
def remove_original_album
|
|
444
|
+
@frames.delete_if { |f| f.frame_id == Text::OriginalAlbumFrame.frame_id(@major_version, @options) }
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# extracts the original file name (TOFN/TOF)
|
|
448
|
+
#
|
|
449
|
+
# @return [String, nil] returns the original file name
|
|
450
|
+
def original_filename
|
|
451
|
+
find_frame(Text::OriginalFilenameFrame.frame_id(@major_version, @options))&.original_filename
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# sets the original filename (TOFN/TOF)
|
|
455
|
+
#
|
|
456
|
+
# @param original_filename [String] the original filename
|
|
457
|
+
def original_filename=(original_filename)
|
|
458
|
+
set_frame_fields(Text::OriginalFilenameFrame, [:@original_filename], original_filename)
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
# removes the original filename frame
|
|
462
|
+
def remove_original_filename
|
|
463
|
+
@frames.delete_if { |f| f.frame_id == Text::OriginalFilenameFrame.frame_id(@major_version, @options) }
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
# extracts the original writers (TOLY/TOL)
|
|
467
|
+
#
|
|
468
|
+
# @return [Array<String>] returns the original writers
|
|
469
|
+
def original_writers
|
|
470
|
+
frame = find_frame(Text::OriginalWritersFrame.frame_id(@major_version, @options))
|
|
471
|
+
return [] if frame.nil?
|
|
472
|
+
|
|
473
|
+
frame.original_writers
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
# sets the original writers (TOLY/TOL)
|
|
477
|
+
#
|
|
478
|
+
# @param original_writers [Array<String>, String] the original writers
|
|
479
|
+
def original_writers=(original_writers)
|
|
480
|
+
set_frame_fields(Text::OriginalWritersFrame, [:@original_writers], original_writers)
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
# removes the original writers frame
|
|
484
|
+
def remove_original_writers
|
|
485
|
+
@frames.delete_if { |f| f.frame_id == Text::OriginalWritersFrame.frame_id(@major_version, @options) }
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
# extracts the original artists (TOPE, :TOA)
|
|
489
|
+
#
|
|
490
|
+
# @return [Array<String>] returns the original artists
|
|
491
|
+
def original_artists
|
|
492
|
+
frame = find_frame(Text::OriginalArtistsFrame.frame_id(@major_version, @options))
|
|
493
|
+
return [] if frame.nil?
|
|
494
|
+
|
|
495
|
+
frame.original_artists
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
# sets the original artists (TOPE, :TOA)
|
|
499
|
+
#
|
|
500
|
+
# @param original_artists [Array<String>, String] the original artists
|
|
501
|
+
def original_artists=(original_artists)
|
|
502
|
+
set_frame_fields(Text::OriginalArtistsFrame, [:@original_artists], original_artists)
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
# removes the original artists frame
|
|
506
|
+
def remove_original_artists
|
|
507
|
+
@frames.delete_if { |f| f.frame_id == Text::OriginalArtistsFrame.frame_id(@major_version, @options) }
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
# extracts the original release year (TORY, :TOR)
|
|
511
|
+
#
|
|
512
|
+
# @return [String, nil] returns the original album
|
|
513
|
+
def original_release_year
|
|
514
|
+
find_frame(Text::OriginalReleaseYearFrame.frame_id(@major_version, @options))&.original_release_year
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
# sets the original release year (TORY, :TOR)
|
|
518
|
+
#
|
|
519
|
+
# @param original_release_year [String, Integer] the original release year
|
|
520
|
+
def original_release_year=(original_release_year)
|
|
521
|
+
set_frame_fields(Text::OriginalReleaseYearFrame, [:@original_release_year], original_release_year)
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
# removes the original release year frame
|
|
525
|
+
def remove_original_release_year
|
|
526
|
+
@frames.delete_if { |f| f.frame_id == Text::OriginalReleaseYearFrame.frame_id(@major_version, @options) }
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
# extracts the file owner (TOWN)
|
|
530
|
+
#
|
|
531
|
+
# @return [String, nil] returns the file owner
|
|
532
|
+
def file_owner
|
|
533
|
+
find_frame(Text::FileOwnerFrame.frame_id(@major_version, @options))&.file_owner
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
# sets the file owner (TOWN)
|
|
537
|
+
#
|
|
538
|
+
# @param file_owner [String] the file owner
|
|
539
|
+
def file_owner=(file_owner)
|
|
540
|
+
set_frame_fields(Text::FileOwnerFrame, [:@file_owner], file_owner)
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
# removes the file owner frame
|
|
544
|
+
def remove_file_owner
|
|
545
|
+
@frames.delete_if { |f| f.frame_id == Text::FileOwnerFrame.frame_id(@major_version, @options) }
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
# extracts the artists (TPE1/TP1)
|
|
549
|
+
#
|
|
550
|
+
# @return [Array<String>] returns the artists
|
|
551
|
+
def artists
|
|
552
|
+
frame = find_frame(Text::ArtistsFrame.frame_id(@major_version, @options))
|
|
553
|
+
return [] if frame.nil?
|
|
554
|
+
|
|
555
|
+
frame.artists
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
# sets the artists (TPE1/TP1)
|
|
559
|
+
#
|
|
560
|
+
# @param artists [Array<String>, String] the artists
|
|
561
|
+
def artists=(artists)
|
|
562
|
+
set_frame_fields(Text::ArtistsFrame, [:@artists], artists)
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
# removes the artists frame
|
|
566
|
+
def remove_artists
|
|
567
|
+
@frames.delete_if { |f| f.frame_id == Text::ArtistsFrame.frame_id(@major_version, @options) }
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
# extracts the album artist (TPE2/TP2)
|
|
571
|
+
#
|
|
572
|
+
# @return [String, nil] returns the album artist
|
|
573
|
+
def album_artist
|
|
574
|
+
find_frame(Text::AlbumArtistFrame.frame_id(@major_version, @options))&.album_artist
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
# sets the album artist (TPE2/TP2)
|
|
578
|
+
#
|
|
579
|
+
# @param album_artist [String] the album artist
|
|
580
|
+
def album_artist=(album_artist)
|
|
581
|
+
set_frame_fields(Text::AlbumArtistFrame, [:@album_artist], album_artist)
|
|
582
|
+
end
|
|
583
|
+
|
|
584
|
+
# removes the album artist frame
|
|
585
|
+
def remove_album_artist
|
|
586
|
+
@frames.delete_if { |f| f.frame_id == Text::AlbumArtistFrame.frame_id(@major_version, @options) }
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
# extracts the conductor (TPE3/TP3)
|
|
590
|
+
#
|
|
591
|
+
# @return [String, nil] returns the conductor
|
|
592
|
+
def conductor
|
|
593
|
+
find_frame(Text::ConductorFrame.frame_id(@major_version, @options))&.conductor
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
# sets the conductor (TPE3/TP3)
|
|
597
|
+
#
|
|
598
|
+
# @param conductor [String] the conductor
|
|
599
|
+
def conductor=(conductor)
|
|
600
|
+
set_frame_fields(Text::ConductorFrame, [:@conductor], conductor)
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
# removes the conductor frame
|
|
604
|
+
def remove_conductor
|
|
605
|
+
@frames.delete_if { |f| f.frame_id == Text::ConductorFrame.frame_id(@major_version, @options) }
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
# extracts the modified by (TPE4/TP4)
|
|
609
|
+
#
|
|
610
|
+
# @return [String, nil] returns the modified by
|
|
611
|
+
def modified_by
|
|
612
|
+
find_frame(Text::ModifiedByFrame.frame_id(@major_version, @options))&.modified_by
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
# sets the modified by (TPE4/TP4)
|
|
616
|
+
#
|
|
617
|
+
# @param modified_by [String] the modified_by
|
|
618
|
+
def modified_by=(modified_by)
|
|
619
|
+
set_frame_fields(Text::ModifiedByFrame, [:@modified_by], modified_by)
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
# removes the modified by frame
|
|
623
|
+
def remove_modified_by
|
|
624
|
+
@frames.delete_if { |f| f.frame_id == Text::ModifiedByFrame.frame_id(@major_version, @options) }
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
# extracts the part of set, e.g. CD 1/2 (TPOS/TPA)
|
|
628
|
+
#
|
|
629
|
+
# @return [Frames::Text::Entities::PartOfSet, nil] returns the part of set
|
|
630
|
+
def part_of_set
|
|
631
|
+
frame = find_frame(Text::PartOfSetFrame.frame_id(@major_version, @options))
|
|
632
|
+
return nil if frame.nil?
|
|
633
|
+
|
|
634
|
+
Text::Entities::PartOfSet.new(frame.part, frame.total)
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
# sets the part of set (TPOS/TPA)
|
|
638
|
+
#
|
|
639
|
+
# @param part_of_set [Frames::Text::Entities::PartOfSet] the part of set
|
|
640
|
+
def part_of_set=(part_of_set)
|
|
641
|
+
set_frame_fields(Text::PartOfSetFrame, %i[@part @htotal], part_of_set.part, part_of_set.total)
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
# removes the part of set frame
|
|
645
|
+
def remove_part_of_set
|
|
646
|
+
@frames.delete_if { |f| f.frame_id == Text::PartOfSetFrame.frame_id(@major_version, @options) }
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
# extracts the publisher (TPUB/TPB)
|
|
650
|
+
#
|
|
651
|
+
# @return [String, nil] returns the publisher
|
|
652
|
+
def publisher
|
|
653
|
+
find_frame(Text::PublisherFrame.frame_id(@major_version, @options))&.publisher
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
# sets the publisher (TPUB/TPB)
|
|
657
|
+
#
|
|
658
|
+
# @param publisher [String] the publisher
|
|
659
|
+
def publisher=(publisher)
|
|
660
|
+
set_frame_fields(Text::PublisherFrame, [:@publisher], publisher)
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
# removes the publisher frame
|
|
664
|
+
def remove_publisher
|
|
665
|
+
@frames.delete_if { |f| f.frame_id == Text::PublisherFrame.frame_id(@major_version, @options) }
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
# extracts the track number (TRCK/TRK)
|
|
669
|
+
#
|
|
670
|
+
# @return [Frames::Text::Entities::TrackNumber, nil] returns the track number
|
|
671
|
+
def track_number
|
|
672
|
+
frame = find_frame(Text::TrackNumberFrame.frame_id(@major_version, @options))
|
|
673
|
+
return nil if frame.nil?
|
|
674
|
+
|
|
675
|
+
Text::Entities::TrackNumber.new(frame.track_number, frame.total)
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
# sets the track number (TRCK/TRK)
|
|
679
|
+
#
|
|
680
|
+
# @param track_number [Frames::Text::Entities::TrackNumber] the track number
|
|
681
|
+
def track_number=(track_number)
|
|
682
|
+
set_frame_fields(Text::TrackNumberFrame, %i[@track_number @htotal], track_number.track_number,
|
|
683
|
+
track_number.total)
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
# removes the track number frame
|
|
687
|
+
def remove_track_number
|
|
688
|
+
@frames.delete_if { |f| f.frame_id == Text::TrackNumberFrame.frame_id(@major_version, @options) }
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
# extracts the recording dates (TRDA/TRD)
|
|
692
|
+
#
|
|
693
|
+
# @return [Array<String>] returns the recording dates
|
|
694
|
+
def recording_dates
|
|
695
|
+
frame = find_frame(Text::RecordingDatesFrame.frame_id(@major_version, @options))
|
|
696
|
+
return [] if frame.nil?
|
|
697
|
+
|
|
698
|
+
frame.recording_dates
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
# sets the recording dates (TRDA/TRD)
|
|
702
|
+
#
|
|
703
|
+
# @param recording_dates [Array<String>, String] the recording date(s)
|
|
704
|
+
def recording_dates=(recording_dates)
|
|
705
|
+
set_frame_fields(Text::RecordingDatesFrame, [:@recording_dates], recording_dates)
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
# removes the recording dates frame
|
|
709
|
+
def remove_recording_dates
|
|
710
|
+
@frames.delete_if { |f| f.frame_id == Text::RecordingDatesFrame.frame_id(@major_version, @options) }
|
|
711
|
+
end
|
|
712
|
+
|
|
713
|
+
# extracts the internet radio station name (TRSN)
|
|
714
|
+
#
|
|
715
|
+
# @return [String, nil] returns the internet radio station name
|
|
716
|
+
def internet_radio_station_name
|
|
717
|
+
find_frame(Text::InternetRadioStationFrame.frame_id(@major_version, @options))&.station_name
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
# sets the internet radio station (TRSN)
|
|
721
|
+
#
|
|
722
|
+
# @param station_name [String] the internet radio station
|
|
723
|
+
def internet_radio_station_name=(station_name)
|
|
724
|
+
set_frame_fields(Text::InternetRadioStationFrame, [:@station_name], station_name)
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
# removes the internet radio station name frame
|
|
728
|
+
def remove_internet_radio_station_name
|
|
729
|
+
@frames.delete_if { |f| f.frame_id == Text::InternetRadioStationFrame.frame_id(@major_version, @options) }
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
# extracts the file size in bytes excluding the id3v2 tag size (TSIZ/TSI)
|
|
733
|
+
#
|
|
734
|
+
# @return [String, nil] returns the size in bytes
|
|
735
|
+
def size
|
|
736
|
+
find_frame(Text::SizeFrame.frame_id(@major_version, @options))&.size
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
# sets the file size in bytes excluding the id3v2 tag size (TSIZ/TSI)
|
|
740
|
+
#
|
|
741
|
+
# @param size [String, Integer] the size in bytes
|
|
742
|
+
def size=(size)
|
|
743
|
+
set_frame_fields(Text::SizeFrame, [:@size], size)
|
|
744
|
+
end
|
|
745
|
+
|
|
746
|
+
# removes the size frame
|
|
747
|
+
def remove_size
|
|
748
|
+
@frames.delete_if { |f| f.frame_id == Text::SizeFrame.frame_id(@major_version, @options) }
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
# extracts the ISRC number (12 characters) (TSRC/TRC)
|
|
752
|
+
#
|
|
753
|
+
# @return [String, nil] returns the ISRC number
|
|
754
|
+
def isrc
|
|
755
|
+
find_frame(Text::ISRCFrame.frame_id(@major_version, @options))&.isrc
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
# sets the ISRC number (TSRC/TRC)
|
|
759
|
+
#
|
|
760
|
+
# @param isrc [String] the ISRC number (12 characters)
|
|
761
|
+
def isrc=(isrc)
|
|
762
|
+
set_frame_fields(Text::ISRCFrame, [:@isrc], isrc)
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
# removes the ISRC frame
|
|
766
|
+
def remove_isrc
|
|
767
|
+
@frames.delete_if { |f| f.frame_id == Text::ISRCFrame.frame_id(@major_version, @options) }
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
# extracts the encoder (TSSE/TSS)
|
|
771
|
+
#
|
|
772
|
+
# @return [String, nil] returns the Encoder
|
|
773
|
+
def encoder
|
|
774
|
+
find_frame(Text::EncoderFrame.frame_id(@major_version, @options))&.encoder
|
|
775
|
+
end
|
|
776
|
+
|
|
777
|
+
# sets the Encoder (TSSE/TSS)
|
|
778
|
+
#
|
|
779
|
+
# @param encoder [String] the Encoder
|
|
780
|
+
def encoder=(encoder)
|
|
781
|
+
set_frame_fields(Text::EncoderFrame, [:@encoder], encoder)
|
|
782
|
+
end
|
|
783
|
+
|
|
784
|
+
# removes the encoder frame
|
|
785
|
+
def remove_encoder
|
|
786
|
+
@frames.delete_if { |f| f.frame_id == Text::EncoderFrame.frame_id(@major_version, @options) }
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
# extracts the year (TYER/TYE)
|
|
790
|
+
#
|
|
791
|
+
# @return [String, nil] returns the year
|
|
792
|
+
def year
|
|
793
|
+
find_frame(Text::YearFrame.frame_id(@major_version, @options))&.year
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
# sets the Year (TYER/TYE)
|
|
797
|
+
#
|
|
798
|
+
# @param year [String, Integer] the Year, must be 4 characters long e.g. 2020
|
|
799
|
+
def year=(year)
|
|
800
|
+
set_frame_fields(Text::YearFrame, [:@year], year)
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
# removes the year frame
|
|
804
|
+
def remove_year
|
|
805
|
+
@frames.delete_if { |f| f.frame_id == Text::YearFrame.frame_id(@major_version, @options) }
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
# extracts the user text infos (TXXX/TXX)
|
|
809
|
+
#
|
|
810
|
+
# @return [Array<Frames::Text::Entities::UserInfo>] returns the User Text Infos
|
|
811
|
+
def user_custom_text_information
|
|
812
|
+
frame = find_frames(Text::UserTextInfoFrame.frame_id(@major_version, @options))
|
|
813
|
+
return [] if frame.nil? || frame.empty?
|
|
814
|
+
|
|
815
|
+
frame.map { |f| Text::Entities::UserInfo.new(f.description, f.content) }
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
# adds a user text info (TXXX/TXX)
|
|
819
|
+
# Multiple ones can be added, as long as they have different description
|
|
820
|
+
#
|
|
821
|
+
# @param information [Frames::Text::Entities::UserInfo] the user text info to add
|
|
822
|
+
def user_custom_text_information=(information)
|
|
823
|
+
set_frame_fields_by_selector(Text::UserTextInfoFrame, %i[@description @content],
|
|
824
|
+
->(f) { f.description == information.description },
|
|
825
|
+
information.description, information.content)
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
alias add_user_custom_text_information user_custom_text_information=
|
|
829
|
+
|
|
830
|
+
# removes a user text info for the specific description (TXXX/TXX)
|
|
831
|
+
#
|
|
832
|
+
# @param description [String] the description
|
|
833
|
+
def remove_user_custom_text_information(description)
|
|
834
|
+
@frames.delete_if do |f|
|
|
835
|
+
f.frame_id == Text::UserTextInfoFrame.frame_id(@major_version, @options) && f.description == description
|
|
836
|
+
end
|
|
837
|
+
end
|
|
838
|
+
end
|
|
839
|
+
end
|
|
840
|
+
end
|