Fix writing to opus

This commit is contained in:
Serial 2021-04-23 18:09:36 -04:00
parent d0c84cf028
commit 1491ba55f0
2 changed files with 69 additions and 36 deletions

View file

@ -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"]

View file

@ -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)
}