use revelo_core::stream::{StreamCollection, StreamKind};
use revelo_dispatcher::detect;
use revelo_parsers_tag::parse_tags;
pub use revelo_core;
pub use revelo_dispatcher;
pub use revelo_parsers_tag;
pub type MediaFile<'a> = revelo_core::FileAnalyze<'a>;
pub struct Metadata {
streams: StreamCollection,
}
impl Metadata {
pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
let parser = detect(bytes)?;
let mut fa = MediaFile::new(bytes);
parser(&mut fa);
parse_tags(&mut fa);
Some(Metadata { streams: fa.streams().clone() })
}
pub fn from_file(path: &str) -> Option<Self> {
let bytes = std::fs::read(path).ok()?;
Self::from_bytes(&bytes)
}
pub fn streams(&self) -> &StreamCollection {
&self.streams
}
fn stream_iter(&self, kind: StreamKind, pos: usize) -> impl Iterator<Item = (&str, &str)> {
self.streams
.stream(kind, pos)
.into_iter()
.flat_map(|s| s.iter().map(|(k, v)| (k.as_ref(), v.as_ref())))
}
pub fn into_streams(self) -> StreamCollection {
self.streams
}
pub fn general(&self) -> impl Iterator<Item = (&str, &str)> {
self.stream_iter(StreamKind::General, 0)
}
pub fn video(&self) -> impl Iterator<Item = (&str, &str)> {
self.stream_iter(StreamKind::Video, 0)
}
pub fn audio(&self) -> impl Iterator<Item = (&str, &str)> {
self.stream_iter(StreamKind::Audio, 0)
}
pub fn text(&self) -> impl Iterator<Item = (&str, &str)> {
self.stream_iter(StreamKind::Text, 0)
}
pub fn image(&self) -> impl Iterator<Item = (&str, &str)> {
self.stream_iter(StreamKind::Image, 0)
}
pub fn exif(&self) -> impl Iterator<Item = (&str, &str)> {
self.stream_iter(StreamKind::Exif, 0)
}
pub fn iptc(&self) -> impl Iterator<Item = (&str, &str)> {
self.stream_iter(StreamKind::Iptc, 0)
}
pub fn xmp(&self) -> impl Iterator<Item = (&str, &str)> {
self.stream_iter(StreamKind::Xmp, 0)
}
}