diff options
Diffstat (limited to 'remuxer')
| -rw-r--r-- | remuxer/src/demuxers/mod.rs | 1 | ||||
| -rw-r--r-- | remuxer/src/lib.rs | 1 | ||||
| -rw-r--r-- | remuxer/src/muxers/matroska.rs | 51 | ||||
| -rw-r--r-- | remuxer/src/muxers/mod.rs | 26 | ||||
| -rw-r--r-- | remuxer/src/muxers/mpeg4.rs | 37 | 
5 files changed, 73 insertions, 43 deletions
| diff --git a/remuxer/src/demuxers/mod.rs b/remuxer/src/demuxers/mod.rs index f001250..597bf4a 100644 --- a/remuxer/src/demuxers/mod.rs +++ b/remuxer/src/demuxers/mod.rs @@ -40,6 +40,7 @@ pub fn create_demuxer(container: ContainerFormat, reader: Box<dyn ReadSeek>) ->      match container {          ContainerFormat::Matroska | ContainerFormat::Webm => Box::new(MatroskaDemuxer::new(reader)),          ContainerFormat::Flac => Box::new(FlacDemuxer::new(reader)), +        ContainerFormat::Mpeg4 => todo!(),      }  }  pub fn create_demuxer_autodetect( diff --git a/remuxer/src/lib.rs b/remuxer/src/lib.rs index 13ae06f..306121b 100644 --- a/remuxer/src/lib.rs +++ b/remuxer/src/lib.rs @@ -15,4 +15,5 @@ pub enum ContainerFormat {      Matroska,      Webm,      Flac, +    Mpeg4,  } diff --git a/remuxer/src/muxers/matroska.rs b/remuxer/src/muxers/matroska.rs index 47210c9..c2f22e7 100644 --- a/remuxer/src/muxers/matroska.rs +++ b/remuxer/src/muxers/matroska.rs @@ -8,15 +8,25 @@ use crate::muxers::FragmentMuxer;  use anyhow::Result;  use std::io::Write;  use winter_ebml::{EbmlHeader, EbmlToVec}; -use winter_matroska::{Cluster, Info, MatroskaFile, Segment, Tracks}; +use winter_matroska::{MatroskaFile, Segment}; + +fn write_fragment_shared(out: &mut dyn Write, mut segment: Segment, webm: bool) -> Result<()> { +    segment.info.muxing_app = +        concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")).to_string(); +    if webm { +        if let Some(tracks) = &mut segment.tracks { +            for track in &mut tracks.entries { +                if let Some(video) = &mut track.video { +                    video.colour = None; +                    video.projection = None; +                    video.display_unit = 0; // pixels +                    video.display_width = Some(video.pixel_width); +                    video.display_height = Some(video.pixel_height); +                } +            } +        } +    } -fn write_fragment_shared( -    out: &mut dyn Write, -    info: Info, -    tracks: Tracks, -    cluster: Cluster, -    webm: bool, -) -> Result<()> {      let file = MatroskaFile {          ebml_header: EbmlHeader {              ebml_version: 1, @@ -28,12 +38,7 @@ fn write_fragment_shared(              doc_type_read_version: 2,              ..Default::default()          }, -        segment: Segment { -            info, -            tracks: Some(tracks), -            clusters: vec![cluster], -            ..Default::default() -        }, +        segment,      };      out.write_all(&file.to_vec())?;      Ok(()) @@ -41,23 +46,13 @@ fn write_fragment_shared(  pub struct MatroskaFragmentMuxer;  impl FragmentMuxer for MatroskaFragmentMuxer { -    fn write_fragment( -        out: &mut dyn Write, -        info: Info, -        tracks: Tracks, -        cluster: Cluster, -    ) -> Result<()> { -        write_fragment_shared(out, info, tracks, cluster, false) +    fn write_fragment(out: &mut dyn Write, segment: Segment) -> Result<()> { +        write_fragment_shared(out, segment, false)      }  }  pub struct WebmFragmentMuxer;  impl FragmentMuxer for WebmFragmentMuxer { -    fn write_fragment( -        out: &mut dyn Write, -        info: Info, -        tracks: Tracks, -        cluster: Cluster, -    ) -> Result<()> { -        write_fragment_shared(out, info, tracks, cluster, true) +    fn write_fragment(out: &mut dyn Write, segment: Segment) -> Result<()> { +        write_fragment_shared(out, segment, true)      }  } diff --git a/remuxer/src/muxers/mod.rs b/remuxer/src/muxers/mod.rs index 8752373..ae544eb 100644 --- a/remuxer/src/muxers/mod.rs +++ b/remuxer/src/muxers/mod.rs @@ -5,36 +5,32 @@  */  pub mod matroska; +pub mod mpeg4;  use crate::{      ContainerFormat, -    muxers::matroska::{MatroskaFragmentMuxer, WebmFragmentMuxer}, +    muxers::{ +        matroska::{MatroskaFragmentMuxer, WebmFragmentMuxer}, +        mpeg4::Mpeg4FragmentMuxer, +    },  };  use anyhow::Result;  use std::io::Write; -use winter_matroska::{Cluster, Info, Tracks}; +use winter_matroska::Segment;  pub trait FragmentMuxer { -    fn write_fragment( -        out: &mut dyn Write, -        info: Info, -        tracks: Tracks, -        cluster: Cluster, -    ) -> Result<()>; +    fn write_fragment(out: &mut dyn Write, segment: Segment) -> Result<()>;  }  pub fn write_fragment(      container: ContainerFormat,      out: &mut dyn Write, -    info: Info, -    tracks: Tracks, -    cluster: Cluster, +    segment: Segment,  ) -> Result<()> {      match container { -        ContainerFormat::Matroska => { -            MatroskaFragmentMuxer::write_fragment(out, info, tracks, cluster) -        } -        ContainerFormat::Webm => WebmFragmentMuxer::write_fragment(out, info, tracks, cluster), +        ContainerFormat::Matroska => MatroskaFragmentMuxer::write_fragment(out, segment), +        ContainerFormat::Webm => WebmFragmentMuxer::write_fragment(out, segment), +        ContainerFormat::Mpeg4 => Mpeg4FragmentMuxer::write_fragment(out, segment),          _ => unimplemented!(),      }  } diff --git a/remuxer/src/muxers/mpeg4.rs b/remuxer/src/muxers/mpeg4.rs new file mode 100644 index 0000000..437f117 --- /dev/null +++ b/remuxer/src/muxers/mpeg4.rs @@ -0,0 +1,37 @@ +/* +    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) 2025 metamuffin <metamuffin.org> +*/ + +use crate::muxers::{FragmentMuxer, matroska::MatroskaFragmentMuxer}; +use anyhow::Result; +use std::{ +    io::{Cursor, Write, copy}, +    process::{Command, Stdio}, +    thread::spawn, +}; +use winter_matroska::Segment; + +pub struct Mpeg4FragmentMuxer; +impl FragmentMuxer for Mpeg4FragmentMuxer { +    fn write_fragment(out: &mut dyn Write, segment: Segment) -> Result<()> { +        let mut mk_frag = Vec::new(); +        MatroskaFragmentMuxer::write_fragment(&mut mk_frag, segment)?; + +        let mut child = Command::new("ffmpeg") +            .args( +                "-hide_banner -f matroska -i pipe:0 -c copy -f mp4 -movflags frag_keyframe+empty_moov pipe:1" +                    .split(" "), +            ) +            .stdin(Stdio::piped()) +            .stdout(Stdio::piped()) +            .spawn()?; + +        let mut stdin = child.stdin.take().unwrap(); +        let mut stdout = child.stdout.take().unwrap(); +        spawn(move || copy(&mut Cursor::new(mk_frag), &mut stdin)); +        copy(&mut stdout, out)?; +        Ok(()) +    } +} | 
