1
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
use std::io::Read;
pub use error::ParseError;
pub use error::Result;
use std::fs::File;
use std::path::Path;
use std::io::BufReader;
mod error;
mod read_ext;
mod opus_header_structs;
pub use opus_header_structs::*;
mod ogg_page;
use ogg_page::*;
#[cfg(test)]
mod tests;
#[derive(Debug)]
pub struct OpusHeaders {
pub id: IdentificationHeader,
pub comments: CommentHeader,
}
pub fn parse_from_path<P: AsRef<Path>>(path: P) -> Result<OpusHeaders> {
parse_from_file(&File::open(path)?)
}
pub fn parse_from_file(file: &File) -> Result<OpusHeaders> {
parse_from_read(BufReader::new(file))
}
pub fn parse_from_read<T: Read>(mut reader: T) -> Result<OpusHeaders> {
let first_ogg_page = OggPage::parse(&mut reader)?;
let id = IdentificationHeader::parse(&first_ogg_page.payload[..])?;
let mut comment_pages = vec![];
comment_pages.push(OggPage::parse(&mut reader)?);
loop {
let next_page = OggPage::parse(&mut reader)?;
if next_page.header_type == 0x01 {
comment_pages.push(next_page);
} else {
break;
}
}
let comment_len = comment_pages.iter().map(|p| p.payload.len()).sum();
let mut comment_bytes = Vec::with_capacity(comment_len);
for mut page in comment_pages {
comment_bytes.append(&mut page.payload);
}
let co = CommentHeader::parse(&comment_bytes[..])?;
Ok(OpusHeaders { id, comments: co })
}