aboutsummaryrefslogtreecommitdiff
path: root/remuxer/src/muxers
diff options
context:
space:
mode:
Diffstat (limited to 'remuxer/src/muxers')
-rw-r--r--remuxer/src/muxers/matroska.rs51
-rw-r--r--remuxer/src/muxers/mod.rs26
-rw-r--r--remuxer/src/muxers/mpeg4.rs37
3 files changed, 71 insertions, 43 deletions
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(())
+ }
+}