mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-12-12 13:42:34 +00:00
Fix writing to opus
This commit is contained in:
parent
d0c84cf028
commit
1491ba55f0
2 changed files with 69 additions and 36 deletions
|
@ -4,7 +4,7 @@ version = "0.1.1"
|
|||
authors = ["Serial <69764315+Serial-ATA@users.noreply.github.com>", "Tianyi <ShiTianyi2001@outlook.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Fork of https://github.com/TianyiShi2001/audiotags, adding support for more file types and (optionally) duration"
|
||||
description = "Unified IO for different types of audio metadata"
|
||||
repository = "https://github.com/Serial-ATA/lofty-rs"
|
||||
keywords = ["tags", "audio", "metadata"]
|
||||
categories = ["accessibility", "multimedia::audio"]
|
||||
|
|
|
@ -53,26 +53,61 @@ where
|
|||
Ok(c.into_inner())
|
||||
}
|
||||
|
||||
struct Page {
|
||||
pub size_idx: usize,
|
||||
pub content: Vec<u8>,
|
||||
pub header_type: u8,
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
}
|
||||
|
||||
pub(crate) fn opus<T>(mut data: T, packet: &[u8]) -> Result<Vec<u8>>
|
||||
where
|
||||
T: Read + Seek,
|
||||
{
|
||||
let mut beginning_sig = [0; 4];
|
||||
data.read_exact(&mut beginning_sig)?;
|
||||
fn read_page<V>(mut data: V) -> Result<Page>
|
||||
where
|
||||
V: Read + Seek,
|
||||
{
|
||||
let mut sig = [0; 4];
|
||||
data.read_exact(&mut sig)?;
|
||||
|
||||
if &beginning_sig != b"OggS" {
|
||||
return Err(Error::UnknownFormat);
|
||||
if &sig != b"OggS" {
|
||||
return Err(Error::UnknownFormat);
|
||||
}
|
||||
|
||||
let mut info = [0; 2];
|
||||
data.read_exact(&mut info)?;
|
||||
|
||||
let header_type = info[1];
|
||||
|
||||
let mut page = [0; 21];
|
||||
data.read_exact(&mut page)?;
|
||||
|
||||
let size_idx = data.seek(SeekFrom::Current(0))? as usize;
|
||||
|
||||
let mut segment_table = vec![0; page[20] as usize];
|
||||
data.read_exact(&mut segment_table)?;
|
||||
|
||||
let start = data.seek(SeekFrom::Current(0))? as usize;
|
||||
|
||||
let mut content = vec![0; segment_table.iter().map(|&b| b as usize).sum()];
|
||||
data.read_exact(&mut content)?;
|
||||
|
||||
let end = data.seek(SeekFrom::Current(0))? as usize;
|
||||
|
||||
Ok(Page {
|
||||
size_idx,
|
||||
content,
|
||||
header_type,
|
||||
start,
|
||||
end,
|
||||
})
|
||||
}
|
||||
|
||||
let mut first_page = [0; 23];
|
||||
data.read_exact(&mut first_page)?;
|
||||
|
||||
let mut segment_table = vec![0; first_page[22] as usize];
|
||||
data.read_exact(&mut segment_table)?;
|
||||
|
||||
let mut head = vec![0; segment_table.iter().map(|&b| b as usize).sum()];
|
||||
data.read_exact(&mut head)?;
|
||||
let first_page = read_page(&mut data)?;
|
||||
|
||||
let head = first_page.content;
|
||||
let (ident, head) = head.split_at(8);
|
||||
|
||||
if ident != b"OpusHead" {
|
||||
|
@ -87,40 +122,38 @@ where
|
|||
data.read_exact(&mut channel_mapping)?;
|
||||
}
|
||||
|
||||
let mut sig = [0; 4];
|
||||
data.read_exact(&mut sig)?;
|
||||
|
||||
if &sig != b"OggS" {
|
||||
return Err(Error::UnknownFormat);
|
||||
}
|
||||
|
||||
let mut second_page = [0; 23];
|
||||
data.read_exact(&mut second_page)?;
|
||||
|
||||
let size_pos = data.seek(SeekFrom::Current(0))? as usize;
|
||||
|
||||
let mut segment_table = vec![0; second_page[22] as usize];
|
||||
data.read_exact(&mut segment_table)?;
|
||||
|
||||
let start = data.seek(SeekFrom::Current(0))? as usize;
|
||||
|
||||
let mut tags = vec![0; segment_table.iter().map(|&b| b as usize).sum()];
|
||||
data.read_exact(&mut tags)?;
|
||||
|
||||
let end = data.seek(SeekFrom::Current(0))? as usize;
|
||||
let second_page = read_page(&mut data)?;
|
||||
let tags = second_page.content;
|
||||
let size_pos = second_page.size_idx;
|
||||
let start = second_page.start;
|
||||
let end = second_page.end;
|
||||
|
||||
if &tags[0..8] != b"OpusTags" {
|
||||
return Err(Error::UnknownFormat);
|
||||
}
|
||||
|
||||
let last_len = (packet.len() % 255) as u8;
|
||||
let needed = (packet.len() / 255) + 1;
|
||||
|
||||
let mut segments = Vec::with_capacity(needed);
|
||||
|
||||
for i in 0..needed {
|
||||
if i + 1 < needed {
|
||||
segments.push(255)
|
||||
} else {
|
||||
segments.push(last_len)
|
||||
}
|
||||
}
|
||||
|
||||
data.seek(SeekFrom::Start(0))?;
|
||||
|
||||
let mut content = Vec::new();
|
||||
data.read_to_end(&mut content)?;
|
||||
|
||||
content.splice(start..end, packet.to_vec());
|
||||
content.insert(size_pos, (packet.len() % 255) as u8);
|
||||
content.remove(size_pos + 1);
|
||||
content.insert(size_pos - 1, needed as u8);
|
||||
content.remove(size_pos);
|
||||
content.splice(size_pos..start, segments);
|
||||
|
||||
Ok(content)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue