aboutsummaryrefslogtreecommitdiff
path: root/stream/src
diff options
context:
space:
mode:
Diffstat (limited to 'stream/src')
-rw-r--r--stream/src/stream_info.rs42
1 files changed, 26 insertions, 16 deletions
diff --git a/stream/src/stream_info.rs b/stream/src/stream_info.rs
index c3746c6..288ea5c 100644
--- a/stream/src/stream_info.rs
+++ b/stream/src/stream_info.rs
@@ -7,8 +7,11 @@ use jellybase::{
},
CONF,
};
-use jellyremuxer::metadata::{matroska_metadata, MatroskaMetadata};
-use std::{path::PathBuf, sync::Arc};
+use jellyremuxer::{
+ metadata::{matroska_metadata, MatroskaMetadata},
+ seek_index::get_track_sizes,
+};
+use std::{collections::BTreeMap, path::PathBuf, sync::Arc};
use tokio::{
io::{AsyncWriteExt, DuplexStream},
spawn,
@@ -21,25 +24,30 @@ async fn async_matroska_metadata(path: PathBuf) -> Result<Arc<MatroskaMetadata>>
Ok(spawn_blocking(move || matroska_metadata(&path)).await??)
}
+async fn async_get_track_sizes(path: PathBuf) -> Result<BTreeMap<u64, usize>> {
+ Ok(spawn_blocking(move || get_track_sizes(&path)).await??)
+}
+
pub(crate) struct InternalStreamInfo {
pub paths: Vec<PathBuf>,
pub _metadata: Vec<Arc<MatroskaMetadata>>,
pub track_to_file: Vec<(usize, u64)>,
}
+// TODO cache mem
pub(crate) async fn stream_info(info: Arc<SMediaInfo>) -> Result<(InternalStreamInfo, StreamInfo)> {
- let mut metadata = Vec::new();
- let mut paths = Vec::new();
- for path in &info.files {
- metadata.push(async_matroska_metadata(path.clone()).await?);
- paths.push(path.clone());
- }
let mut tracks = Vec::new();
let mut track_to_file = Vec::new();
-
- for (i, m) in metadata.iter().enumerate() {
- if let Some(t) = &m.tracks {
+ let mut metadata_arr = Vec::new();
+ let mut paths = Vec::new();
+ for (i, path) in info.files.iter().enumerate() {
+ let metadata = async_matroska_metadata(path.clone()).await?;
+ let sizes = async_get_track_sizes(path.clone()).await?;
+ if let Some(t) = &metadata.tracks {
+ let duration = media_duration(&metadata);
for t in &t.entries {
+ let bitrate =
+ sizes.get(&t.track_number).copied().unwrap_or_default() as f64 / duration * 8.;
tracks.push(StreamTrackInfo {
name: None,
kind: match t.track_type {
@@ -48,21 +56,23 @@ pub(crate) async fn stream_info(info: Arc<SMediaInfo>) -> Result<(InternalStream
17 => TrackKind::Subtitle,
_ => todo!(),
},
- formats: stream_formats(t),
+ formats: stream_formats(t, bitrate),
});
track_to_file.push((i, t.track_number));
}
}
+ metadata_arr.push(metadata);
+ paths.push(path.to_owned());
}
let segment = StreamSegmentInfo {
name: None,
- duration: media_duration(&metadata[0]),
+ duration: media_duration(&metadata_arr[0]),
tracks,
};
Ok((
InternalStreamInfo {
- _metadata: metadata,
+ _metadata: metadata_arr,
paths,
track_to_file,
},
@@ -73,12 +83,12 @@ pub(crate) async fn stream_info(info: Arc<SMediaInfo>) -> Result<(InternalStream
))
}
-fn stream_formats(t: &TrackEntry) -> Vec<StreamFormatInfo> {
+fn stream_formats(t: &TrackEntry, remux_bitrate: f64) -> Vec<StreamFormatInfo> {
let mut formats = Vec::new();
formats.push(StreamFormatInfo {
codec: t.codec_id.to_string(),
remux: true,
- bitrate: 10_000_000., // TODO
+ bitrate: remux_bitrate,
containers: {
let mut x = containers_by_codec(&t.codec_id);
// TODO remove this