To learn rust!
- This library is used for console based
ID3 tagging
tool Markdang.
This is ID3
read and write library.
- Add dependency
- Reding: How to read
ID3
information - Writing: How to write
ID3
information - Rewrite: How to rewrite all
ID3
information to version 4 - Getting information of a frame body without property name.
other usecases See tests.
This can be used by adding rtag
to your dependencies in your project's Cargo.toml
[dependencies]
rtag = "0.3.5"
and this to your crate root:
extern crate rtag;
To read a ID3
metadata, you use a MetadataReader and a Unit enum.
and the MetadataReader
is implementing the std::iter::Iterator trait,
you can use filter, map, fold.. and so on.
// read a frame1
for m in MetadataReader::new("./test-resources/v1-v2.mp3").unwrap() {
match m {
Unit::FrameV1(frame) => {
debug!("v1: {:?}", frame);
assert_eq!("Artist", frame.artist);
assert_eq!("!@#$", frame.comment);
assert_eq!("1", frame.track);
assert_eq!("137", frame.genre);
}
_ => (),
}
}
// filter a frame v3 having `compression flag`
let mut i = MetadataReader::new(path).unwrap().filter(|m| match m {
&Unit::FrameV2(FrameHeader::V23(ref header), _) => {
header.has_flag(FrameHeaderFlag::Compression)
}
_ => false,
});
// fold a frame v2
let new_data = MetadataReader::new(path)
.unwrap()
.fold(Vec::new(), |mut vec, unit| {
if let Unit::FrameV2(frame_head, frame_body) = unit {
let new_frame_body = if let FrameBody::TALB(ref frame) = frame_body {
let mut new_frame = frame.clone();
new_frame.text = "Album!".to_string();
FrameBody::TALB(new_frame)
} else {
frame_body.clone()
};
vec.push(Unit::FrameV2(frame_head, new_frame_body));
} else {
vec.push(unit);
}
vec
});
To write a ID3
metadata, you pass FrameHeader and FrameBody to MetadataWriter via std::vec::Vec.
let new_data = MetadataReader::new(path)
.unwrap()
.fold(Vec::new(), |mut vec, unit| {
if let Unit::FrameV2(frame_head, frame_body) = unit {
let new_frame_body = ...
vec.push(Unit::FrameV2(frame_head, new_frame_body));
}
vec
});
let _ = MetadataWriter::new(path).unwrap().write(new_data, false);
To rewrite all the frames to version 4, it is same to above example but second parameter is true
.
Note: the frame v1 information is ignored and some frames that are ignored.
- In 2.2 'CRM', 'PIC'.
- In 2.3 'EQUA', 'IPLS', 'RVAD', 'TDAT', 'TIME', 'TORY', 'TRDA', 'TSIZ', 'TYER'
// collect frames having version 2
let frames = MetadataReader::new(path).unwrap().collect::<Vec<Unit>>();
// rewrite to version 4
let _ = MetadataWriter::new(path).unwrap().write(frames, true);
// read a version 4
for unit in MetadataReader::new(path).unwrap() {
match unit {
Unit::FrameV2(FrameHeader::V24(head), frame_body) => {
...
},
_ => (),
}
}
To read value of frame without property name, FrameBody support to_map
and inside
.
for unit in MetadataReader::new(path).unwrap() {
match unit {
Unit::FrameV2(_, ref frame_body) => {
// 1. using to_map();
let map = frame_body.to_map();
//{
// <key1:&str>: <value1:String>
// ...
//}
// 2. using inside
frame_body.inside(|key, value| {
// key<&str>, value<String>
...
true // if true, look inside next.
})
},
_ => (),
}
}