/* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2024 metamuffin */ pub mod extract; pub mod import; pub mod remux; pub mod seek_index; pub mod segment_extractor; pub mod snippet; pub mod trim_writer; pub use remux::remux_stream_into; pub use snippet::write_snippet_into; use jellycommon::{SourceTrack, SourceTrackKind}; use jellymatroska::{Master, MatroskaTag}; pub fn ebml_header(webm: bool) -> MatroskaTag { MatroskaTag::Ebml(Master::Collected(vec![ MatroskaTag::EbmlVersion(1), MatroskaTag::EbmlReadVersion(1), MatroskaTag::EbmlMaxIdLength(4), MatroskaTag::EbmlMaxSizeLength(8), MatroskaTag::DocType(if webm { "webm".to_string() } else { "matroska".to_string() }), MatroskaTag::DocTypeVersion(4), MatroskaTag::DocTypeReadVersion(2), ])) } pub fn ebml_segment_info(title: String, duration: f64) -> MatroskaTag { MatroskaTag::Info(Master::Collected(vec![ MatroskaTag::TimestampScale(1_000_000), MatroskaTag::Duration(duration * 1000.0), MatroskaTag::Title(title), MatroskaTag::MuxingApp("jellyremux".to_string()), MatroskaTag::WritingApp("jellything".to_string()), ])) } pub fn ebml_track_entry( number: u64, track: &SourceTrack, codec_private: Option>, ) -> MatroskaTag { let mut els = vec![ MatroskaTag::TrackNumber(number), MatroskaTag::TrackUID(number), MatroskaTag::FlagLacing(0), MatroskaTag::Language(track.language.clone()), MatroskaTag::CodecID(track.codec.clone()), ]; if let Some(d) = &track.default_duration { els.push(MatroskaTag::DefaultDuration(*d)); } match track.kind { SourceTrackKind::Video { width, height, fps: _, } => { els.push(MatroskaTag::TrackType(1)); els.push(MatroskaTag::Video(Master::Collected(vec![ MatroskaTag::PixelWidth(width), MatroskaTag::PixelHeight(height), ]))) } SourceTrackKind::Audio { channels, sample_rate, bit_depth, } => { els.push(MatroskaTag::TrackType(2)); els.push(MatroskaTag::Audio(Master::Collected(vec![ MatroskaTag::SamplingFrequency(sample_rate), MatroskaTag::Channels(channels.try_into().unwrap()), ]))); els.push(MatroskaTag::BitDepth(bit_depth.try_into().unwrap())); } SourceTrackKind::Subtitles => { els.push(MatroskaTag::TrackType(17)); } } if let Some(d) = &codec_private { els.push(MatroskaTag::CodecPrivate(d.clone())); } MatroskaTag::TrackEntry(Master::Collected(els)) }