diff --git a/examples/remux.rs b/examples/remux.rs new file mode 100644 index 0000000..abe260a --- /dev/null +++ b/examples/remux.rs @@ -0,0 +1,58 @@ +extern crate ffmpeg_next as ffmpeg; + +use std::env; + +use ffmpeg::{codec, encoder, format, log, media, Rational}; + +fn main() { + let input_file = env::args().nth(1).expect("missing input file"); + let output_file = env::args().nth(2).expect("missing output file"); + + ffmpeg::init().unwrap(); + log::set_level(log::Level::Warning); + + let mut ictx = format::input(&input_file).unwrap(); + let mut octx = format::output(&output_file).unwrap(); + + let mut stream_mapping = vec![0; ictx.nb_streams() as _]; + let mut ist_time_bases = vec![Rational(0, 1); ictx.nb_streams() as _]; + let mut ost_index = 0; + for (ist_index, ist) in ictx.streams().enumerate() { + let ist_medium = ist.codec().medium(); + if ist_medium != media::Type::Audio + && ist_medium != media::Type::Video + && ist_medium != media::Type::Subtitle + { + stream_mapping[ist_index] = -1; + continue; + } + stream_mapping[ist_index] = ost_index; + ist_time_bases[ist_index] = ist.time_base(); + ost_index += 1; + let mut ost = octx.add_stream(encoder::find(codec::Id::None)).unwrap(); + ost.set_parameters(ist.parameters()); + // We need to set codec_tag to 0 lest we run into incompatible codec tag + // issues when muxing into a different container format. Unfortunately + // there's no high level API to do this (yet). + unsafe { + (*ost.parameters().as_mut_ptr()).codec_tag = 0; + } + } + + octx.set_metadata(ictx.metadata().to_owned()); + octx.write_header().unwrap(); + + for (stream, mut packet) in ictx.packets() { + let ist_index = stream.index(); + let ost_index = stream_mapping[ist_index]; + if ost_index < 0 { + continue; + } + let ost = octx.stream(ost_index as _).unwrap(); + packet.rescale_ts(ist_time_bases[ist_index], ost.time_base()); + packet.set_position(-1); + packet.write_interleaved(&mut octx).unwrap(); + } + + octx.write_trailer().unwrap(); +}