Class: Riff::MetaEditor
- Inherits:
-
Object
- Object
- Riff::MetaEditor
- Defined in:
- lib/riff/info.rb
Overview
Th MetaEditor class provides a reader-writer for the INFO meta-chunk on RIFF AVI and WAVE files.
Aside from the stated methods, there is a convenience method for every attribute name listed in the MetaEditor.available_names
array, thus, these lines are equivalent:
editor. = "Me Myself"
editor.artist = "Me Myself"
editor['IART'] = "Me Myself"
Note that some names map to the same fourcc.
Also note that RIFF INFO datums are generally encoded using ISO-8859-1 WinANSI. We expect to be able to support this more fully with Ruby 1.9 and its integrated text encoding facilities.
Constant Summary collapse
- ATTRIBUTE_FOURCCs =
[ 'IARL', 'IART','ICSM','ICMT', 'ICOP', 'ICRD', 'ICRP', 'IDIM', 'IDPI', 'IENG','IGNR', 'IKEY', 'ILGT', 'IMED', 'INAM', 'IPLT', 'IPRD', 'ISBJ', 'ISFT', 'ISHP', 'ISRC', 'ISRF', 'ITCH']
- ATTRIBUTE_NAMES =
{ 'Archival Location' => 'IARL', 'Artist' => 'IART', 'Author' => 'IART', 'Comissioned' => 'ICSM', 'Comment' => 'ICMT', 'Description' => 'ICMT', 'Copyright' => 'ICOP', 'Date Created' => 'ICRD', 'Cropped' => 'ICRP', 'Dimensions' => 'IDIM', 'Dots Per Inch' => 'IDPI', 'Engineer' => 'IENG', 'Genre' => 'IGNR', 'Keywords' => 'IKEY', 'Lightness' => 'ILGT', 'Medium' => 'IMED', 'Title' => 'INAM', 'Name' => 'INAM', 'Number of Colors' => 'IPLT', 'Product' => 'IPRD', 'Subject' => 'ISBJ', 'Software' => 'ISFT', 'Encoding Application' => 'ISFT', 'Sharpness' => 'ISHP', 'Source' => 'ISRC', 'Source Form' => 'ISRF', 'Technician' => 'ITCH' }
Instance Attribute Summary collapse
-
#pad_out ⇒ Object
the number of bytes padding to add after the INFO chunk.
-
#path ⇒ Object
readonly
the path to the file being edited.
Class Method Summary collapse
-
.available_names(fourcc) ⇒ Object
Returns an array of all the settable attributes for the file.
-
.fourcc_for_name(name) ⇒ Object
Gives the fourcc the class will map to a given English name.
-
.names_for_fourcc(fourcc) ⇒ Object
Returns an array of English names for a fourcc tag.
Instance Method Summary collapse
-
#[](fourcc) ⇒ Object
Get a metadatum by
fourcc
. -
#[]=(fourcc, value) ⇒ Object
Set a metadatum by
fourcc
. -
#each_metadatum ⇒ Object
Yields each metadatum.
-
#initialize(path) ⇒ MetaEditor
constructor
Creates a MetaEditor object for the file locates at
path
. -
#save! ⇒ Object
Commit the changed metadata to the file.
Constructor Details
#initialize(path) ⇒ MetaEditor
Creates a MetaEditor object for the file locates at path
If you provide a block, the MetaEditor itself will be yielded, and a save!
will be called upon the block closing.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/riff/info.rb', line 129 def initialize(path) #:yields: self reader = Reader.open(path,'r') @pad_out = 1024 @path = path @metadata = {} @dirty = false infoChunk = reader.root_chunk.find {|c| c.signature == 'INFO'} if infoChunk && infoChunk.is_list? infoChunk.each do |subChunk| @metadata[subChunk.fourcc] = subChunk.body end end if block_given? yield self save! end self end |
Instance Attribute Details
#pad_out ⇒ Object
the number of bytes padding to add after the INFO chunk. The default is 1024 bytes.
48 49 50 |
# File 'lib/riff/info.rb', line 48 def pad_out @pad_out end |
#path ⇒ Object (readonly)
the path to the file being edited
44 45 46 |
# File 'lib/riff/info.rb', line 44 def path @path end |
Class Method Details
.available_names(fourcc) ⇒ Object
Returns an array of all the settable attributes for the file
116 117 118 |
# File 'lib/riff/info.rb', line 116 def MetaEditor.available_names(fourcc) return ATTRIBUTE_NAMES.keys end |
.fourcc_for_name(name) ⇒ Object
Gives the fourcc the class will map to a given English name
121 122 123 |
# File 'lib/riff/info.rb', line 121 def MetaEditor.fourcc_for_name(name) return ATTRIBUTE_NAMES[name] end |
.names_for_fourcc(fourcc) ⇒ Object
Returns an array of English names for a fourcc tag
111 112 113 |
# File 'lib/riff/info.rb', line 111 def MetaEditor.names_for_fourcc(fourcc) return (ATTRIBUTE_NAMES.select {|k,v| v == fourcc}).map {|a| a[0]} end |
Instance Method Details
#[](fourcc) ⇒ Object
Get a metadatum by fourcc
149 150 151 |
# File 'lib/riff/info.rb', line 149 def [](fourcc) return @metadata[fourcc] end |
#[]=(fourcc, value) ⇒ Object
Set a metadatum by fourcc
154 155 156 157 |
# File 'lib/riff/info.rb', line 154 def []=(fourcc,value) @dirty = true @metadata[fourcc] = value end |
#each_metadatum ⇒ Object
Yields each metadatum
160 161 162 163 164 |
# File 'lib/riff/info.rb', line 160 def @metadata.each_pair do |fourcc,value| yield fourcc,value end end |
#save! ⇒ Object
Commit the changed metadata to the file. Presently, the complete file is rewritten to a temp file and then is moved to the name of the target.
If a pad_out number is specified, a “JUNK” chunk with a payload of pad_out bytes will be added after the INFO chunk.
If you have not modified any metadatums of the file, this method will have no effect on the system.
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/riff/info.rb', line 174 def save! return unless @dirty tempPath = File.dirname(path) + "/" + (([?a] *16).map {|i| (i + rand(26)).chr}).join + ".tmp" Reader.open(path,'r') do |reader| begin Builder.create(tempPath,reader.root_chunk.signature) do |riffwriter| riffwriter.list('INFO') do |infochunk| @metadata.each_pair do |key,value| infochunk.chunk(key) { |io| io << value } end end if @pad_out > 0 riffwriter.chunk("JUNK") do |jnk| jnk << "\0" * @pad_out end end reader.root_chunk.each do |ck| unless ck.is_list? && ck.signature == 'INFO' then riffwriter.chunk(ck.fourcc) {|io| io << ck.body} end #unless end end rescue Exception => e File.unlink(tempPath) if FileTest.exist?(tempPath) raise e end end File.rename(tempPath,path) end |