mirror of
https://github.com/alfg/mp4-rust.git
synced 2025-04-15 08:14:15 +00:00
.
This commit is contained in:
parent
b388238837
commit
c032eef329
7 changed files with 46 additions and 40 deletions
|
@ -5,7 +5,8 @@ use std::io::{self, BufReader, BufWriter};
|
|||
use std::path::Path;
|
||||
|
||||
use mp4::{
|
||||
AacConfig, AvcConfig, HevcConfig, MediaConfig, MediaType, Mp4Config, OpusConfig, Result, TrackConfig, TtxtConfig, Vp9Config
|
||||
AacConfig, AvcConfig, HevcConfig, MediaConfig, MediaType, Mp4Config, OpusConfig, Result,
|
||||
TrackConfig, TtxtConfig, Vp9Config,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
@ -61,7 +62,7 @@ fn copy<P: AsRef<Path>>(src_filename: &P, dst_filename: &P) -> Result<()> {
|
|||
bitrate: track.bitrate(),
|
||||
profile: track.audio_profile()?,
|
||||
freq_index: track.sample_freq_index()?,
|
||||
chan_conf: track.channel_config()?
|
||||
chan_conf: track.channel_config()?,
|
||||
}),
|
||||
MediaType::OPUS => MediaConfig::OpusConfig(OpusConfig {
|
||||
bitrate: track.bitrate(),
|
||||
|
|
|
@ -737,4 +737,4 @@ mod tests {
|
|||
chan_conf: 6, // FiveOne
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ impl Default for OpusBox {
|
|||
}
|
||||
|
||||
impl OpusBox {
|
||||
|
||||
pub fn new(config: &OpusConfig) -> Self {
|
||||
Self {
|
||||
channel_count: config.chan_conf as u16,
|
||||
|
|
|
@ -47,8 +47,7 @@ impl StsdBox {
|
|||
size += mp4a.box_size();
|
||||
} else if let Some(ref opus) = self.opus {
|
||||
size += opus.box_size();
|
||||
}
|
||||
else if let Some(ref tx3g) = self.tx3g {
|
||||
} else if let Some(ref tx3g) = self.tx3g {
|
||||
size += tx3g.box_size();
|
||||
}
|
||||
size
|
||||
|
@ -154,7 +153,7 @@ impl<W: Write> WriteBox<&mut W> for StsdBox {
|
|||
mp4a.write_box(writer)?;
|
||||
} else if let Some(ref tx3g) = self.tx3g {
|
||||
tx3g.write_box(writer)?;
|
||||
}else if let Some(ref opus) = self.opus {
|
||||
} else if let Some(ref opus) = self.opus {
|
||||
opus.write_box(writer)?;
|
||||
}
|
||||
|
||||
|
|
39
src/track.rs
39
src/track.rs
|
@ -218,7 +218,7 @@ impl Mp4Track {
|
|||
Err(Error::BoxInStblNotFound(self.track_id(), BoxType::EsdsBox))
|
||||
}
|
||||
} else if let Some(ref opus) = self.trak.mdia.minf.stbl.stsd.opus {
|
||||
if let Some(ref dops ) = opus.dops_box {
|
||||
if let Some(ref dops) = opus.dops_box {
|
||||
ChannelConfig::try_from(dops.output_channel_count)
|
||||
} else {
|
||||
Err(Error::BoxInStblNotFound(self.track_id(), BoxType::DopsBox))
|
||||
|
@ -667,6 +667,7 @@ pub(crate) struct Mp4TrackWriter {
|
|||
|
||||
samples_per_chunk: u32,
|
||||
duration_per_chunk: u32,
|
||||
offset: u64,
|
||||
}
|
||||
|
||||
impl Mp4TrackWriter {
|
||||
|
@ -929,25 +930,35 @@ impl Mp4TrackWriter {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn update_offset(&mut self, offset: u64) -> Result<()> {
|
||||
self.offset = offset;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn write_end<W: Write + Seek>(&mut self, writer: &mut W) -> Result<TrakBox> {
|
||||
return self.write_end_with_offset(writer, 0);
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn write_end_with_offset<W: Write + Seek>(&mut self, writer: &mut W, offset: u64) -> Result<TrakBox> {
|
||||
pub(crate) fn write_end_with_offset<W: Write + Seek>(
|
||||
&mut self,
|
||||
writer: &mut W,
|
||||
offset: u64,
|
||||
) -> Result<TrakBox> {
|
||||
self.write_chunk(writer)?;
|
||||
|
||||
let max_sample_size = self.max_sample_size();
|
||||
self.trak.edts = Some(EdtsBox { elst: Some(ElstBox {
|
||||
version: 1,
|
||||
flags: 0,
|
||||
entries: vec![ElstEntry {
|
||||
segment_duration: self.trak.mdia.mdhd.duration,
|
||||
media_time: offset,
|
||||
media_rate: 1,
|
||||
media_rate_fraction: 0,
|
||||
}],
|
||||
})});
|
||||
self.trak.edts = Some(EdtsBox {
|
||||
elst: Some(ElstBox {
|
||||
version: 1,
|
||||
flags: 0,
|
||||
entries: vec![ElstEntry {
|
||||
segment_duration: self.trak.mdia.mdhd.duration,
|
||||
media_time: (offset * self.trak.mdia.mdhd.timescale as u64) / 1_000_000,
|
||||
media_rate: 1,
|
||||
media_rate_fraction: 0,
|
||||
}],
|
||||
}),
|
||||
});
|
||||
if let Some(ref mut mp4a) = self.trak.mdia.minf.stbl.stsd.mp4a {
|
||||
if let Some(ref mut esds) = mp4a.esds {
|
||||
esds.es_desc.dec_config.buffer_size_db = max_sample_size;
|
||||
|
@ -963,4 +974,4 @@ impl Mp4TrackWriter {
|
|||
|
||||
Ok(self.trak.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -231,7 +231,8 @@ pub enum MediaType {
|
|||
VP9,
|
||||
AAC,
|
||||
OPUS,
|
||||
TTXT}
|
||||
TTXT,
|
||||
}
|
||||
|
||||
impl fmt::Display for MediaType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
@ -784,4 +785,4 @@ impl<'a, T: Metadata<'a>> Metadata<'a> for Option<T> {
|
|||
fn summary(&self) -> Option<Cow<str>> {
|
||||
self.as_ref().and_then(|t| t.summary())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ pub struct Mp4Writer<W> {
|
|||
mdat_pos: u64,
|
||||
timescale: u32,
|
||||
duration: u64,
|
||||
offsets: Vec<u64>,
|
||||
}
|
||||
|
||||
impl<W> Mp4Writer<W> {
|
||||
|
@ -74,6 +75,7 @@ impl<W: Write + Seek> Mp4Writer<W> {
|
|||
BoxHeader::new(BoxType::WideBox, HEADER_SIZE).write(&mut writer)?;
|
||||
|
||||
let tracks = Vec::new();
|
||||
let offsets = Vec::new();
|
||||
let timescale = config.timescale;
|
||||
let duration = 0;
|
||||
Ok(Self {
|
||||
|
@ -82,6 +84,7 @@ impl<W: Write + Seek> Mp4Writer<W> {
|
|||
mdat_pos,
|
||||
timescale,
|
||||
duration,
|
||||
offsets,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -92,6 +95,15 @@ impl<W: Write + Seek> Mp4Writer<W> {
|
|||
Ok(track_id)
|
||||
}
|
||||
|
||||
pub fn update_offset(&mut self, track_index: u32, offset_us: u64) -> Result<()> {
|
||||
if let Some(track) = self.tracks.get_mut(track_index as usize) {
|
||||
track.update_offset(offset_us)?
|
||||
} else {
|
||||
return Err(Error::TrakNotFound(track_index));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_durations(&mut self, track_dur: u64) {
|
||||
if track_dur > self.duration {
|
||||
self.duration = track_dur;
|
||||
|
@ -146,21 +158,4 @@ impl<W: Write + Seek> Mp4Writer<W> {
|
|||
moov.write_box(&mut self.writer)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_end_with_offset(&mut self, offset: u64) -> Result<()> {
|
||||
let mut moov = MoovBox::default();
|
||||
|
||||
for track in self.tracks.iter_mut() {
|
||||
moov.traks.push(track.write_end_with_offset(&mut self.writer,offset)?);
|
||||
}
|
||||
self.update_mdat_size()?;
|
||||
|
||||
moov.mvhd.timescale = self.timescale;
|
||||
moov.mvhd.duration = self.duration;
|
||||
if moov.mvhd.duration > (u32::MAX as u64) {
|
||||
moov.mvhd.version = 1
|
||||
}
|
||||
moov.write_box(&mut self.writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue