mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-03 16:41:26 +01:00
added android client
This commit is contained in:
1 parent
8b95cf7a05
commit
6db6909824
73 files changed
+9234
-106
No files matched your search
@@ -39,7 +39,7 @@ pub use error::{Error, Result};
|
||||
/// returns it and `StreamSource::open` takes it — and taking a dependency on the
|
||||
/// whole SDK for a newtype is not a reasonable price for that.
|
||||
pub use proton_sdk::ids::NodeUid;
|
||||
pub use reader::{LibraryOpener, RevisionBlocks};
|
||||
pub use reader::{FileBlocks, LibraryOpener, RevisionBlocks};
|
||||
pub use ring::{DEFAULT_RING_BYTES, RingStats};
|
||||
pub use source::{RevisionOpener, StreamConfig, StreamSource};
|
||||
pub use stream::{DEFAULT_READAHEAD_BLOCKS, StreamStats, VideoStream};
|
||||
@@ -8,6 +8,7 @@
|
||||
//! one, and the caching layer above would then hold neither of them whole.
|
||||
//! Aligning here means each block is fetched, decrypted and cached exactly once.
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
@@ -63,6 +64,51 @@ impl BlockSource for RevisionBlocks {
|
||||
}
|
||||
}
|
||||
|
||||
/// A fully-downloaded revision. It uses the same block seam as Proton so mpv
|
||||
/// can seek normally without a second playback path.
|
||||
pub struct FileBlocks {
|
||||
revision_id: String,
|
||||
path: PathBuf,
|
||||
sizes: Vec<u64>,
|
||||
map: BlockMap,
|
||||
}
|
||||
impl FileBlocks {
|
||||
pub fn new(revision_id: String, path: PathBuf, sizes: Vec<u64>) -> Self {
|
||||
let map = BlockMap::new(&sizes);
|
||||
Self {
|
||||
revision_id,
|
||||
path,
|
||||
sizes,
|
||||
map,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[async_trait]
|
||||
impl BlockSource for FileBlocks {
|
||||
fn revision_id(&self) -> &str {
|
||||
&self.revision_id
|
||||
}
|
||||
fn block_sizes(&self) -> &[u64] {
|
||||
&self.sizes
|
||||
}
|
||||
async fn read_block(&self, index: usize) -> Result<Vec<u8>> {
|
||||
use tokio::io::{AsyncReadExt, AsyncSeekExt};
|
||||
let (start, size) = match (self.map.start_of(index), self.map.size_of(index)) {
|
||||
(Some(a), Some(b)) => (a, b),
|
||||
_ => {
|
||||
return Err(Error::NotFound(format!(
|
||||
"offline block {index} is past the end"
|
||||
)));
|
||||
}
|
||||
};
|
||||
let mut file = tokio::fs::File::open(&self.path).await?;
|
||||
file.seek(std::io::SeekFrom::Start(start)).await?;
|
||||
let mut data = vec![0; size as usize];
|
||||
file.read_exact(&mut data).await?;
|
||||
Ok(data)
|
||||
}
|
||||
}
|
||||
|
||||
/// Opens revisions out of the configured shares.
|
||||
pub struct LibraryOpener {
|
||||
library: Arc<pstr_core::SharedLibrary>,
|
||||
|
||||
@@ -121,6 +121,10 @@ struct Inner {
|
||||
}
|
||||
|
||||
impl VideoStream {
|
||||
/// Build a seekable stream from complete local content.
|
||||
pub fn offline(uid: NodeUid, blocks: SharedBlocks, ring_bytes: u64) -> Self {
|
||||
Self::new(uid, blocks, Arc::new(BlockRing::new(ring_bytes)), None, 0)
|
||||
}
|
||||
pub(crate) fn new(
|
||||
uid: NodeUid,
|
||||
blocks: SharedBlocks,
|
||||
|
||||
Reference in new issue
Block a user