pub struct ID3Parser<T>
where T: AsRef<Path>,
{ pub pheader: ProtocolHeader, pub eheader: ExtendedHeader, pub padding_size: u32, pub footer: Footer, pub id3v1: ID3v1, /* private fields */ }

Fields§

§pheader: ProtocolHeader

protocol header

§eheader: ExtendedHeader

extended header

§padding_size: u32

sum of extended header (including payload), frames, padding

§footer: Footer§id3v1: ID3v1

ID3v1 tag

Implementations§

source§

impl<T> ID3Parser<T>
where T: AsRef<Path>,

source

pub fn new(fp: T) -> Result<Self>

Create a new parser. 传入一个列表,启动多个线程进行解析:怎么返回值?线程切换成本? 用户启动多个线程,每个线程一个ID3Parser 异步?对已经确定的Buffer

Examples found in repository?
examples/runme.rs (line 4)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
fn main() -> std::io::Result<()> {
    // https://drive.google.com/file/d/1fp_TYclIKZAWMwFTnxEEe4PqJCuBqHl4/view?usp=sharing
    let mut id3_parser = ID3Parser::new("云烟成雨.mp3").unwrap();

    id3_parser.parse_id3v1()?;
    // The ID3v1 protocol does not specify the content encoding,
    // which may be UTF-8, GBK or some other encoding,
    // so it is not possible to decode it, so the bytecode is output directly
    println!("{}", id3_parser.id3v1);

    id3_parser.parse_id3v2()?;
    println!("{}", id3_parser.pheader);
    println!("{}", id3_parser.eheader);
    println!("{}", id3_parser.footer);

    // The `get` method is case insensitive,
    // so you're allowed to pass in uppercase or lowercase characters or a mix of upper and lowercase characters,
    // as is the `get_raw` method
    println!("TIT2 = {:?}", id3_parser.get("TIT2").unwrap());
    println!("TALB = {:?}", id3_parser.get("talb").unwrap());
    println!("TPE1 = {:?}", id3_parser.get("tpe1").unwrap());
    println!("TPE2 = {:?}", id3_parser.get("tpe2").unwrap());
    println!("padding size = {}", id3_parser.padding_size);

    // It is not recommended to print the APIC byte sequence because it is really long
    // println!("APIC_raw = {:?}", parser.get_raw("apic").unwrap());

    // Write filename.jpg to the current directory.
    // No need to worry about multiple APIC frames in a file being overwritten by the same name.
    // Naming rules: <filename>_mp3_<picture_type>[_index].jpg
    id3_parser.write_image()?;

    let mut flac_parser = FlacParser::new("云烟成雨.flac").unwrap();
    flac_parser.parse()?;

    // https://www.xiph.org/vorbis/doc/v-comment.html
    // The `get` method is case insensitive
    println!("artist = {:?}", flac_parser.get("artist").unwrap());

    println!("album = {:?}", flac_parser.get("album").unwrap());

    // Get all vorbis comments in the file
    let (k, v) = flac_parser.get_all().unwrap();
    let mut index = 0;
    while index < k.len() {
        println!(
            "vorbis key = {:?}, vorbis comment = {:?}",
            k[index], v[index]
        );
        index += 1;
    }

    // It is not recommended to print the APIC byte sequence because it is really long
    // println!("picture_raw_data = {:?}", flac_parser.picture[0].data);

    println!("md5 = {}", flac_parser.stream_info.md5);

    println!(
        "picture width = {}, picture width = {}, picture type = {:?}",
        flac_parser.picture[0].width,
        flac_parser.picture[0].height,
        flac_parser.picture[0].pic_type
    );

    // This will write image[s] to disk
    // Naming rules: <filename>_flac_<picture_type>[_index].jpg
    flac_parser.write_image()?;

    flac_parser.change_target("千千阙歌.flac");


    let mut ogg_parser = OggParser::new("xhh.ogg");
    ogg_parser.parse()?;
    println!("ogg_vorbis_comment = {:?}", ogg_parser.get_all());
    Ok(())
}
source

pub fn get(&self, query: &str) -> Option<Vec<String>>

Return frame content that after decoding.

All text information frames should call this method, including TXXX.

This method is case insensitive.

Examples found in repository?
examples/runme.rs (line 20)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
fn main() -> std::io::Result<()> {
    // https://drive.google.com/file/d/1fp_TYclIKZAWMwFTnxEEe4PqJCuBqHl4/view?usp=sharing
    let mut id3_parser = ID3Parser::new("云烟成雨.mp3").unwrap();

    id3_parser.parse_id3v1()?;
    // The ID3v1 protocol does not specify the content encoding,
    // which may be UTF-8, GBK or some other encoding,
    // so it is not possible to decode it, so the bytecode is output directly
    println!("{}", id3_parser.id3v1);

    id3_parser.parse_id3v2()?;
    println!("{}", id3_parser.pheader);
    println!("{}", id3_parser.eheader);
    println!("{}", id3_parser.footer);

    // The `get` method is case insensitive,
    // so you're allowed to pass in uppercase or lowercase characters or a mix of upper and lowercase characters,
    // as is the `get_raw` method
    println!("TIT2 = {:?}", id3_parser.get("TIT2").unwrap());
    println!("TALB = {:?}", id3_parser.get("talb").unwrap());
    println!("TPE1 = {:?}", id3_parser.get("tpe1").unwrap());
    println!("TPE2 = {:?}", id3_parser.get("tpe2").unwrap());
    println!("padding size = {}", id3_parser.padding_size);

    // It is not recommended to print the APIC byte sequence because it is really long
    // println!("APIC_raw = {:?}", parser.get_raw("apic").unwrap());

    // Write filename.jpg to the current directory.
    // No need to worry about multiple APIC frames in a file being overwritten by the same name.
    // Naming rules: <filename>_mp3_<picture_type>[_index].jpg
    id3_parser.write_image()?;

    let mut flac_parser = FlacParser::new("云烟成雨.flac").unwrap();
    flac_parser.parse()?;

    // https://www.xiph.org/vorbis/doc/v-comment.html
    // The `get` method is case insensitive
    println!("artist = {:?}", flac_parser.get("artist").unwrap());

    println!("album = {:?}", flac_parser.get("album").unwrap());

    // Get all vorbis comments in the file
    let (k, v) = flac_parser.get_all().unwrap();
    let mut index = 0;
    while index < k.len() {
        println!(
            "vorbis key = {:?}, vorbis comment = {:?}",
            k[index], v[index]
        );
        index += 1;
    }

    // It is not recommended to print the APIC byte sequence because it is really long
    // println!("picture_raw_data = {:?}", flac_parser.picture[0].data);

    println!("md5 = {}", flac_parser.stream_info.md5);

    println!(
        "picture width = {}, picture width = {}, picture type = {:?}",
        flac_parser.picture[0].width,
        flac_parser.picture[0].height,
        flac_parser.picture[0].pic_type
    );

    // This will write image[s] to disk
    // Naming rules: <filename>_flac_<picture_type>[_index].jpg
    flac_parser.write_image()?;

    flac_parser.change_target("千千阙歌.flac");


    let mut ogg_parser = OggParser::new("xhh.ogg");
    ogg_parser.parse()?;
    println!("ogg_vorbis_comment = {:?}", ogg_parser.get_all());
    Ok(())
}
source

pub fn get_raw(&self, query: &str) -> Option<Vec<Vec<u8>>>

Return raw data without decoding.

APIC should call this method, as should SYLT.

SYLT may call the get method in the future.

This method is case insensitive.

source

pub fn parse_id3v1(&mut self) -> Result<()>

Start parsing id3v1.

It is not recommended to call this method,

thinking that the ID3 protocol contains very little information,

unless a very old song.

Examples found in repository?
examples/runme.rs (line 6)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
fn main() -> std::io::Result<()> {
    // https://drive.google.com/file/d/1fp_TYclIKZAWMwFTnxEEe4PqJCuBqHl4/view?usp=sharing
    let mut id3_parser = ID3Parser::new("云烟成雨.mp3").unwrap();

    id3_parser.parse_id3v1()?;
    // The ID3v1 protocol does not specify the content encoding,
    // which may be UTF-8, GBK or some other encoding,
    // so it is not possible to decode it, so the bytecode is output directly
    println!("{}", id3_parser.id3v1);

    id3_parser.parse_id3v2()?;
    println!("{}", id3_parser.pheader);
    println!("{}", id3_parser.eheader);
    println!("{}", id3_parser.footer);

    // The `get` method is case insensitive,
    // so you're allowed to pass in uppercase or lowercase characters or a mix of upper and lowercase characters,
    // as is the `get_raw` method
    println!("TIT2 = {:?}", id3_parser.get("TIT2").unwrap());
    println!("TALB = {:?}", id3_parser.get("talb").unwrap());
    println!("TPE1 = {:?}", id3_parser.get("tpe1").unwrap());
    println!("TPE2 = {:?}", id3_parser.get("tpe2").unwrap());
    println!("padding size = {}", id3_parser.padding_size);

    // It is not recommended to print the APIC byte sequence because it is really long
    // println!("APIC_raw = {:?}", parser.get_raw("apic").unwrap());

    // Write filename.jpg to the current directory.
    // No need to worry about multiple APIC frames in a file being overwritten by the same name.
    // Naming rules: <filename>_mp3_<picture_type>[_index].jpg
    id3_parser.write_image()?;

    let mut flac_parser = FlacParser::new("云烟成雨.flac").unwrap();
    flac_parser.parse()?;

    // https://www.xiph.org/vorbis/doc/v-comment.html
    // The `get` method is case insensitive
    println!("artist = {:?}", flac_parser.get("artist").unwrap());

    println!("album = {:?}", flac_parser.get("album").unwrap());

    // Get all vorbis comments in the file
    let (k, v) = flac_parser.get_all().unwrap();
    let mut index = 0;
    while index < k.len() {
        println!(
            "vorbis key = {:?}, vorbis comment = {:?}",
            k[index], v[index]
        );
        index += 1;
    }

    // It is not recommended to print the APIC byte sequence because it is really long
    // println!("picture_raw_data = {:?}", flac_parser.picture[0].data);

    println!("md5 = {}", flac_parser.stream_info.md5);

    println!(
        "picture width = {}, picture width = {}, picture type = {:?}",
        flac_parser.picture[0].width,
        flac_parser.picture[0].height,
        flac_parser.picture[0].pic_type
    );

    // This will write image[s] to disk
    // Naming rules: <filename>_flac_<picture_type>[_index].jpg
    flac_parser.write_image()?;

    flac_parser.change_target("千千阙歌.flac");


    let mut ogg_parser = OggParser::new("xhh.ogg");
    ogg_parser.parse()?;
    println!("ogg_vorbis_comment = {:?}", ogg_parser.get_all());
    Ok(())
}
source

pub fn parse_id3v2(&mut self) -> Result<()>

Start parsing id3v2.

Examples found in repository?
examples/runme.rs (line 12)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
fn main() -> std::io::Result<()> {
    // https://drive.google.com/file/d/1fp_TYclIKZAWMwFTnxEEe4PqJCuBqHl4/view?usp=sharing
    let mut id3_parser = ID3Parser::new("云烟成雨.mp3").unwrap();

    id3_parser.parse_id3v1()?;
    // The ID3v1 protocol does not specify the content encoding,
    // which may be UTF-8, GBK or some other encoding,
    // so it is not possible to decode it, so the bytecode is output directly
    println!("{}", id3_parser.id3v1);

    id3_parser.parse_id3v2()?;
    println!("{}", id3_parser.pheader);
    println!("{}", id3_parser.eheader);
    println!("{}", id3_parser.footer);

    // The `get` method is case insensitive,
    // so you're allowed to pass in uppercase or lowercase characters or a mix of upper and lowercase characters,
    // as is the `get_raw` method
    println!("TIT2 = {:?}", id3_parser.get("TIT2").unwrap());
    println!("TALB = {:?}", id3_parser.get("talb").unwrap());
    println!("TPE1 = {:?}", id3_parser.get("tpe1").unwrap());
    println!("TPE2 = {:?}", id3_parser.get("tpe2").unwrap());
    println!("padding size = {}", id3_parser.padding_size);

    // It is not recommended to print the APIC byte sequence because it is really long
    // println!("APIC_raw = {:?}", parser.get_raw("apic").unwrap());

    // Write filename.jpg to the current directory.
    // No need to worry about multiple APIC frames in a file being overwritten by the same name.
    // Naming rules: <filename>_mp3_<picture_type>[_index].jpg
    id3_parser.write_image()?;

    let mut flac_parser = FlacParser::new("云烟成雨.flac").unwrap();
    flac_parser.parse()?;

    // https://www.xiph.org/vorbis/doc/v-comment.html
    // The `get` method is case insensitive
    println!("artist = {:?}", flac_parser.get("artist").unwrap());

    println!("album = {:?}", flac_parser.get("album").unwrap());

    // Get all vorbis comments in the file
    let (k, v) = flac_parser.get_all().unwrap();
    let mut index = 0;
    while index < k.len() {
        println!(
            "vorbis key = {:?}, vorbis comment = {:?}",
            k[index], v[index]
        );
        index += 1;
    }

    // It is not recommended to print the APIC byte sequence because it is really long
    // println!("picture_raw_data = {:?}", flac_parser.picture[0].data);

    println!("md5 = {}", flac_parser.stream_info.md5);

    println!(
        "picture width = {}, picture width = {}, picture type = {:?}",
        flac_parser.picture[0].width,
        flac_parser.picture[0].height,
        flac_parser.picture[0].pic_type
    );

    // This will write image[s] to disk
    // Naming rules: <filename>_flac_<picture_type>[_index].jpg
    flac_parser.write_image()?;

    flac_parser.change_target("千千阙歌.flac");


    let mut ogg_parser = OggParser::new("xhh.ogg");
    ogg_parser.parse()?;
    println!("ogg_vorbis_comment = {:?}", ogg_parser.get_all());
    Ok(())
}
source

pub fn change_target(&mut self, new_fp: T)

As the method says.

In addition, its own data will be cleared.

source

pub fn write_image(&self) -> Result<()>

Write APIC frame’s raw to the current directory named with filename.jpg like 云烟成雨.jpg if there is only one APIC frame.

Unless, add a underline followd by a number after the filename start with the second one, like 云烟成雨_1.jpg.

Examples found in repository?
examples/runme.rs (line 32)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
fn main() -> std::io::Result<()> {
    // https://drive.google.com/file/d/1fp_TYclIKZAWMwFTnxEEe4PqJCuBqHl4/view?usp=sharing
    let mut id3_parser = ID3Parser::new("云烟成雨.mp3").unwrap();

    id3_parser.parse_id3v1()?;
    // The ID3v1 protocol does not specify the content encoding,
    // which may be UTF-8, GBK or some other encoding,
    // so it is not possible to decode it, so the bytecode is output directly
    println!("{}", id3_parser.id3v1);

    id3_parser.parse_id3v2()?;
    println!("{}", id3_parser.pheader);
    println!("{}", id3_parser.eheader);
    println!("{}", id3_parser.footer);

    // The `get` method is case insensitive,
    // so you're allowed to pass in uppercase or lowercase characters or a mix of upper and lowercase characters,
    // as is the `get_raw` method
    println!("TIT2 = {:?}", id3_parser.get("TIT2").unwrap());
    println!("TALB = {:?}", id3_parser.get("talb").unwrap());
    println!("TPE1 = {:?}", id3_parser.get("tpe1").unwrap());
    println!("TPE2 = {:?}", id3_parser.get("tpe2").unwrap());
    println!("padding size = {}", id3_parser.padding_size);

    // It is not recommended to print the APIC byte sequence because it is really long
    // println!("APIC_raw = {:?}", parser.get_raw("apic").unwrap());

    // Write filename.jpg to the current directory.
    // No need to worry about multiple APIC frames in a file being overwritten by the same name.
    // Naming rules: <filename>_mp3_<picture_type>[_index].jpg
    id3_parser.write_image()?;

    let mut flac_parser = FlacParser::new("云烟成雨.flac").unwrap();
    flac_parser.parse()?;

    // https://www.xiph.org/vorbis/doc/v-comment.html
    // The `get` method is case insensitive
    println!("artist = {:?}", flac_parser.get("artist").unwrap());

    println!("album = {:?}", flac_parser.get("album").unwrap());

    // Get all vorbis comments in the file
    let (k, v) = flac_parser.get_all().unwrap();
    let mut index = 0;
    while index < k.len() {
        println!(
            "vorbis key = {:?}, vorbis comment = {:?}",
            k[index], v[index]
        );
        index += 1;
    }

    // It is not recommended to print the APIC byte sequence because it is really long
    // println!("picture_raw_data = {:?}", flac_parser.picture[0].data);

    println!("md5 = {}", flac_parser.stream_info.md5);

    println!(
        "picture width = {}, picture width = {}, picture type = {:?}",
        flac_parser.picture[0].width,
        flac_parser.picture[0].height,
        flac_parser.picture[0].pic_type
    );

    // This will write image[s] to disk
    // Naming rules: <filename>_flac_<picture_type>[_index].jpg
    flac_parser.write_image()?;

    flac_parser.change_target("千千阙歌.flac");


    let mut ogg_parser = OggParser::new("xhh.ogg");
    ogg_parser.parse()?;
    println!("ogg_vorbis_comment = {:?}", ogg_parser.get_all());
    Ok(())
}

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for ID3Parser<T>

§

impl<T> !Send for ID3Parser<T>

§

impl<T> !Sync for ID3Parser<T>

§

impl<T> Unpin for ID3Parser<T>
where T: Unpin,

§

impl<T> !UnwindSafe for ID3Parser<T>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.