diff options
author | metamuffin <metamuffin@disroot.org> | 2023-01-26 21:45:29 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-01-26 21:45:29 +0100 |
commit | 04e3ebfdda613be0e58290a49536116cc57ad147 (patch) | |
tree | f694064c74e35ddb49fd900a83885e5874a78448 | |
parent | c715d411f465ef742ba76866dfb177f71598b69c (diff) | |
download | jellything-04e3ebfdda613be0e58290a49536116cc57ad147.tar jellything-04e3ebfdda613be0e58290a49536116cc57ad147.tar.bz2 jellything-04e3ebfdda613be0e58290a49536116cc57ad147.tar.zst |
mhh
-rw-r--r-- | matroska/src/bin/mkvdump.rs | 6 | ||||
-rw-r--r-- | matroska/src/write.rs | 11 | ||||
-rw-r--r-- | remuxer/src/lib.rs | 83 | ||||
-rw-r--r-- | server/Cargo.toml | 3 | ||||
-rw-r--r-- | server/src/main.rs | 4 | ||||
-rw-r--r-- | server/src/routes/stream.rs | 3 | ||||
-rw-r--r-- | server/src/routes/ui/account/session.rs | 5 |
7 files changed, 84 insertions, 31 deletions
diff --git a/matroska/src/bin/mkvdump.rs b/matroska/src/bin/mkvdump.rs index 10c697a..ba05c19 100644 --- a/matroska/src/bin/mkvdump.rs +++ b/matroska/src/bin/mkvdump.rs @@ -14,9 +14,9 @@ fn main() -> anyhow::Result<()> { while let Some(tag) = r.next() { let tag = tag?; match tag { - MatroskaTag::SimpleBlock(_) => (), - MatroskaTag::Block(_) => (), - _ => eprintln!("{} {tag:?}", r.position), + MatroskaTag::SimpleBlock(_) => (), // println!("{} SimpleBlock", r.position), + MatroskaTag::Block(_) => (), // println!("{} Block", r.position), + _ => println!("{} {tag:?}", r.position), } } Ok(()) diff --git a/matroska/src/write.rs b/matroska/src/write.rs index ee1c44c..8c1e7bb 100644 --- a/matroska/src/write.rs +++ b/matroska/src/write.rs @@ -26,6 +26,10 @@ impl EbmlWriter { Ok(()) } + pub fn position(&self) -> usize { + self.position + } + pub fn write_padding(&mut self, position: usize) -> Result<()> { let mut size = position - self.position; match size { @@ -62,14 +66,17 @@ impl EbmlWriter { if i > (1 << 56) - 1 { bail!("vint does not fit"); } + self.write_vint_len(i, Self::vint_length(i)) + } + pub fn vint_length(v: u64) -> usize { let mut len = 1; while len <= 8 { - if i < (1 << ((7 * len) - 1)) { + if v < (1 << ((7 * len) - 1)) { break; } len += 1; } - self.write_vint_len(i, len) + len } pub fn write_vint_len(&mut self, i: u64, len: usize) -> Result<()> { let mut bytes = i.to_be_bytes(); diff --git a/remuxer/src/lib.rs b/remuxer/src/lib.rs index 91c913a..1dfbacd 100644 --- a/remuxer/src/lib.rs +++ b/remuxer/src/lib.rs @@ -114,11 +114,18 @@ impl RemuxerContext { .collect(); output.write_tag(&MatroskaTag::Tracks(Master::Collected(tracks_header)))?; + struct ClusterLayout { + position: usize, + timestamp: u64, + blocks: Vec<(usize, BlockIndex)>, + } + let segment_layout = { - let mut pts = 0; - let mut cluster_pts = pts + 2_000; + let mut cluster_pts = 0; let mut clusters = vec![]; let mut cluster = vec![]; + let mut gp = 0usize; // cluster position (in the segment) + let mut p = 0usize; // block position (in the cluster) loop { let mut best_block = BlockIndex { pts: u64::MAX, @@ -135,14 +142,32 @@ impl RemuxerContext { }; } inputs[best_index].temp_index += 1; - pts = best_block.pts; - if pts > cluster_pts + 2_000 { - clusters.push(std::mem::replace(&mut cluster, vec![])); - cluster_pts = pts; + if best_block.pts > cluster_pts + 2_000 { + let cluster_content_size = 1 // timestamp tag + + 1 // timestamp tag size + + EbmlWriter::vint_length(cluster_pts as u64) // timestamp tag value + + p; + let cluster_header_size = 4 // tag length + + EbmlWriter::vint_length(cluster_content_size as u64)// size varint + + cluster_content_size; + clusters.push(ClusterLayout { + position: gp, + timestamp: cluster_pts, + blocks: std::mem::replace(&mut cluster, vec![]), + }); + + cluster_pts = best_block.pts; + gp += p + cluster_header_size; + p = 0; } - if pts == u64::MAX { + if best_block.pts == u64::MAX { break; } + p += 1; // simpleblock tag + p += EbmlWriter::vint_length(1 + 2 + 1 + best_block.size as u64); // simpleblock size vint + p += 1 + 2 + 1; // block {tracknum, pts_off, flags} + // TODO does not work, if more than 127 tracks are present + p += best_block.size; // block payload cluster.push((best_index, best_block)) } info!("segment layout computed ({} clusters)", clusters.len()); @@ -183,28 +208,32 @@ impl RemuxerContext { for (cluster_index, cluster) in segment_layout.into_iter().enumerate() { info!( - "writing cluster {cluster_index} with {} blocks", - cluster.len() + "writing cluster {cluster_index} (pts_base={}) with {} blocks", + cluster.timestamp, + cluster.blocks.len() + ); + debug!( + "calculation was {} bytes off", + cluster.position as i64 - output.position() as i64 ); - for (block_index, iblock) in cluster { + let mut cluster_blocks = vec![MatroskaTag::Timestamp(cluster.timestamp as u64)]; + for (block_index, iblock) in cluster.blocks { let kn = &mut ks[block_index]; let mut block = kn .peek .replace(kn.stream.next()?) .expect("source file too short"); - assert_eq!(iblock.size, block.block.data.len(), "seek index is wrong"); + assert_eq!(iblock.size, block.inner.data.len(), "seek index is wrong"); assert_eq!(iblock.pts, block.pts(), "seek index is wrong"); - let pts = block.pts(); - block.block.track = kn.mapped; - block.block.timestamp_off = 0; - let buf = block.block.dump(); - output.write_tag(&MatroskaTag::Cluster(Master::Collected(vec![ - MatroskaTag::Timestamp(pts), - MatroskaTag::SimpleBlock(buf), - ])))?; + block.inner.track = kn.mapped; + block.inner.timestamp_off = (iblock.pts - cluster.timestamp).try_into().unwrap(); + debug!("n={} tso={}", block.inner.track, block.inner.timestamp_off); + let buf = block.inner.dump(); + cluster_blocks.push(MatroskaTag::SimpleBlock(buf)) } + output.write_tag(&MatroskaTag::Cluster(Master::Collected(cluster_blocks)))?; } output.write_tag(&MatroskaTag::Segment(Master::End))?; Ok(()) @@ -213,7 +242,7 @@ impl RemuxerContext { struct AbsoluteBlock { pts_base: u64, - block: Block, + inner: Block, } struct SegmentExtractIter<'a> { @@ -224,7 +253,7 @@ struct SegmentExtractIter<'a> { impl AbsoluteBlock { pub fn pts(&self) -> u64 { - self.block.timestamp_off as u64 + self.pts_base + self.inner.timestamp_off as u64 + self.pts_base } } @@ -272,16 +301,20 @@ impl SegmentExtractIter<'_> { let block = Block::parse(&block.unwrap())?; if block.track == self.extract { trace!("block: track={} tso={}", block.track, block.timestamp_off); - self.emission_queue - .push_back(AbsoluteBlock { pts_base, block }); + self.emission_queue.push_back(AbsoluteBlock { + pts_base, + inner: block, + }); } } MatroskaTag::SimpleBlock(buf) => { let block = Block::parse(&buf)?; if block.track == self.extract { trace!("block: track={} tso={}", block.track, block.timestamp_off); - self.emission_queue - .push_back(AbsoluteBlock { pts_base, block }); + self.emission_queue.push_back(AbsoluteBlock { + pts_base, + inner: block, + }); } } _ => warn!("(rsc) tag ignored: {item:?}"), diff --git a/server/Cargo.toml b/server/Cargo.toml index 458f48d..a3214fa 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -26,3 +26,6 @@ markup = "0.13.1" sled = "0.34.7" typed-sled = "0.2.3" + +[features] +bypass-auth = []
\ No newline at end of file diff --git a/server/src/main.rs b/server/src/main.rs index 3d08d24..00543ce 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -26,6 +26,10 @@ fn rocket() -> _ { .filter_level(log::LevelFilter::Info) .parse_env("LOG") .init(); + + #[cfg(feature = "bypass-auth")] + warn!("authentification bypass enabled"); + let remuxer = RemuxerContext::new(); let library = Library::open(&CONF.library_path).unwrap(); let database = Database::open(&CONF.database_path).unwrap(); diff --git a/server/src/routes/stream.rs b/server/src/routes/stream.rs index eb7bc13..469ad07 100644 --- a/server/src/routes/stream.rs +++ b/server/src/routes/stream.rs @@ -3,7 +3,7 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2023 metamuffin <metamuffin.org> */ -use super::ui::error::MyError; +use super::ui::{account::session::Session, error::MyError}; use crate::library::Library; use anyhow::{anyhow, Context, Result}; use jellyremuxer::RemuxerContext; @@ -37,6 +37,7 @@ pub fn stream_uri(path: &PathBuf, tracks: &Vec<u64>, webm: bool) -> String { #[get("/stream/<path..>?<tracks>&<webm>")] pub fn r_stream( + _sess: Session, path: PathBuf, webm: Option<bool>, tracks: String, diff --git a/server/src/routes/ui/account/session.rs b/server/src/routes/ui/account/session.rs index ed40d83..3457d41 100644 --- a/server/src/routes/ui/account/session.rs +++ b/server/src/routes/ui/account/session.rs @@ -6,6 +6,7 @@ use crate::{ database::{Database, User}, routes::ui::error::MyError, + CONF, }; use anyhow::anyhow; use rocket::{ @@ -20,11 +21,15 @@ pub struct Session { impl Session { pub async fn from_request_ut(req: &Request<'_>) -> Result<Self, MyError> { + #[cfg(not(feature = "bypass-auth"))] let cookie = req .cookies() .get_private("user") .ok_or(anyhow!("login required"))?; + #[cfg(not(feature = "bypass-auth"))] let username = cookie.value(); + #[cfg(feature = "bypass-auth")] + let username = CONF.admin_username.to_string(); let db = req.guard::<&State<Database>>().await.unwrap(); let user = db |