id3taginator 0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|