Giter Site home page Giter Site logo

mp4-rust's Introduction

mp4

MP4 Reader and Writer in Rust πŸ¦€

mp4 is a Rust library to read and write ISO-MP4 files. This package contains MPEG-4 specifications defined in parts:

https://crates.io/crates/mp4

Crates.io Crates.io Docs Rust

Example

use std::fs::File;
use std::io::{BufReader};
use mp4::{Result};

fn main() -> Result<()> {
    let f = File::open("tests/samples/minimal.mp4").unwrap();
    let size = f.metadata()?.len();
    let reader = BufReader::new(f);

    let mp4 = mp4::Mp4Reader::read_header(reader, size)?;

    // Print boxes.
    println!("major brand: {}", mp4.ftyp.major_brand);
    println!("timescale: {}", mp4.moov.mvhd.timescale);

    // Use available methods.
    println!("size: {}", mp4.size());

    let mut compatible_brands = String::new();
    for brand in mp4.compatible_brands().iter() {
        compatible_brands.push_str(&brand.to_string());
        compatible_brands.push_str(",");
    }
    println!("compatible brands: {}", compatible_brands);
    println!("duration: {:?}", mp4.duration());

    // Track info.
    for track in mp4.tracks().values() {
        println!(
            "track: #{}({}) {} : {}",
            track.track_id(),
            track.language(),
            track.track_type()?,
            track.box_type()?,
        );
    }
    Ok(())
}

See examples/ for more examples.

Install

cargo add mp4

or add to your Cargo.toml:

mp4 = "0.14.0"

Documentation

Development

Requirements

Build

cargo build

Lint and Format

cargo clippy --fix
cargo fmt --all

Run Examples

  • mp4info
cargo run --example mp4info <movie.mp4>
  • mp4dump
cargo run --example mp4dump <movie.mp4>

Run Tests

cargo test

With print statement output.

cargo test -- --nocapture

Run Cargo fmt

Run fmt to catch formatting errors.

rustup component add rustfmt
cargo fmt --all -- --check

Run Clippy

Run Clippy tests to catch common lints and mistakes.

rustup component add clippy
cargo clippy --no-deps -- -D warnings

Run Benchmark Tests

cargo bench

View HTML report at target/criterion/report/index.html

Generate Docs

cargo docs

View at target/doc/mp4/index.html

Web Assembly

See the mp4-inspector project as a reference for using this library in Javascript via Web Assembly.

Related Projects

License

MIT

mp4-rust's People

Contributors

ahkrr avatar alfg avatar andreytkachenko avatar ctopher avatar data-retriever avatar dcnick3 avatar emkman99 avatar ian-spoonradio avatar jensenn avatar jessa0 avatar linusu avatar nemosupremo avatar nintha avatar nlfiedler avatar oftheforest avatar probablykasper avatar ririsoft avatar rolleifx avatar serial-ata avatar st3iny avatar tamdik avatar udoprog avatar unipro avatar w-flo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

mp4-rust's Issues

AV1 support?

Is there a plan to support AV1? If not, I would be happy to work on it.

Writing is_sync doesn't work properly

Hi! I'm trying to generate a video from a set of static images with this library and the x264 library. I noticed that no matter what I set is_sync in Mp4Sample to, all frames are always end up having is_sync: true.

I think it might be related to the implementation here. If I change the code to this:

fn update_sync_samples(&mut self, is_sync: bool) {
    if let Some(ref mut stss) = self.trak.mdia.minf.stbl.stss {
        if !is_sync {
            return;
        }

        stss.entries.push(self.sample_id);
    } else {
        let mut stss = StssBox::default();
        for i in 1..=self.trak.mdia.minf.stbl.stsz.sample_count {
            stss.entries.push(i);
        }
        self.trak.mdia.minf.stbl.stss = Some(stss);
    };
}

The is_sync value is written properly. I'm not quite sure what the code is supposed to be doing, so I'm not sure if this breaks other cases.

To reproduce the issue, you can use the mp4copy example to copy an mp4 file, and then use the mp4sample example to observe that all video frames are suddenly sync.

Tracks are not required to be ordered by track id in the MOOV box

Trying to decode such a file currently panics on this assertion:
https://github.com/alfg/mp4-rust/blob/master/src/reader.rs#L69

image

There's two possible solutions I can imagine:

  1. Sort the tracks after reading them - this does however mean that there must be a hard requirement in the spec that track ids are contiguous.
  2. Maintain a separate indexing from track_id to index to allow fns such as sample_count which uses the track_id to work like a HashMap<u32, usize>.

Personally I'd go for option 2.

Private API

Hi, I was curious why pretty much all of the boxes are private. It makes this library annoying to use when writing a remuxer into MP4 or (FMP4).
I am trying to take a raw FLV stream and generate fragmented MP4 segments, basically i want to construct the boxes and use this library to serialize them into binary. However this library makes that impossible due to the private modifiers on all the mp4 boxes.

Wondering if this was intentional or if it was just an oversight.

Your library is great btw and I would love to use it!

How to write frames Vec<u8> in a loop

I have a frame that contains the image from a webcam in MJPG format using the rscam library. I want to keep writing these "images" to an mp4 until some stop that needs to be defined. The source code I have right now is in the repository https://github.com/milovanderlinden/multicam where multiple cameras in multiple threads write to a jpeg file. I am basicaly looking for a way to replace writing to jpeg with writing to mp4.

extern crate eye;
extern crate rscam;
extern crate mp4;

use eye::prelude::*;
use mp4::{Mp4Config, Mp4Writer};
use rscam::{Camera, Config};
use std::{fs, io::{Write, Cursor}, thread, time};
// Initialize the camera reader
let device_uri = "v4l:///dev/video0" // This gets generated by a loop using eye
let mut _device = _device_uri.replace("v4l://", "");
let mut _file_name = format!("{}.jpeg", _device.replace("/", "_"));
let mut camera = Camera::new(&_device_uri.replace("v4l://", ""))
    .expect("Failed to open video device");
// TODO: Initialize the video writer
let config = Mp4Config {
    major_brand: str::parse("isom").unwrap(),
    minor_version: 512,
    compatible_brands: vec![
        str::parse("isom").unwrap(),
        str::parse("iso2").unwrap(),
        str::parse("avc1").unwrap(),
        str::parse("mp41").unwrap(),
    ],
    timescale: 1000,
};
        
let mut _data = Cursor::new(Vec::<u8>::new());
let mut writer = Mp4Writer::write_start(_data, &config).expect("Could not write to mp4");

// Start the camera
camera
    .start(&Config {
        interval: (1, 30), // 30 fps.
        resolution: (1280, 720),
        format: b"MJPG",
        ..Default::default()
    })
    .unwrap();
// Grab the frames and write them to a file
loop {
    let frame = camera.capture().unwrap();
    println!("{} - {} => {}",frame.get_timestamp(), _device, _file_name);
    let frame_vec = (&frame[..].to_vec());
    println!("{:?}", _data);
    let mut _file = fs::File::create(&_file_name).unwrap();
    _file.write_all(&frame[..]).unwrap();
}

I just cannot wrap my head around getting this fixed. I will publish my entire project to github later, so if you need more information about how this works, let me know.

Bad box header causing read_header dead-looping.

I have a surveillance footage that has a size zero BoxHeader, which causes dead-looping in reader.rs line 30 "while current < size ..."
suggest:
while current < size {
// Get box header.
let header = BoxHeader::read(&mut reader)?;
let BoxHeader { name, size: s } = header;
if s == 0 {
break;
}

question: MOV Quicktime and MP4 metadata

Hello everyone, and happy 2022.

I have just a question, it is not an issue at all.

I have a lot of .MP4 videos which originated from Android phones.
Also, I have equally large number of .MOV files which originated from Apple iPhones (Quicktime?).

I am after video date/time creation and GPS Location coordinates for MOV files and MP4 files.

Can you please advise if there is a Rust crate to extract the video metadata from MOV and MP4 files ?

I have tried code sample on both MP4 and MOV, it worked (it extracted date, in Unix/MP4-epoch format integer?).

I could not find anywhere how to extract the GPS latitude/longitude coordinates from either MP4 or MOV files.

I used exifdata command line utility to obtain the date/time and GPS latitude & longitude, so I do know they are stored in my files. I wanted access to metadata directly from Rust program, not from command line utility.

I thank you very much in advance.

Minimize assertions in production code

In other words, do not cause the client application to panic just because it attempted to process a wonky file. See issue #43 for an example of this. There are only a few places where the non-test code is using an assertion, and most of them can be changed to return an Error as the function already returns a Result. Some, however, are not as straightforward, so some additional thought and discussion is probably in order.

Usable in web assembly?

Is this crate usable in web assembly target? I want to build player for M4A ALAC encoded files.

Publish nested types

Hey there,

The top level box types from the mp4box module are public: MoovBox, MoofBox, MdatBox. However, with the exception of EMsgBox, none of the nested types are public. This makes it difficult to initialize these structs.

For example, here's my awful code to fragment a MoovBox:

// We need to create a brand new moov atom for each track.
let mut toov = mp4::MoovBox{
  mvhd: moov.mvhd.clone(),
  meta: moov.meta.clone(),
  mvex: Some(Default::default()),
  traks: vec![trak.clone()],
  udta: moov.udta.clone(),
};

// TODO someone who knows Rust, please double check that I'm not dumb.
// MvexBox and TrexBox are not exported by the mp4 crate, so we have to construct them using Default.
toov.mvex.as_mut().map(|mvex| {
  mvex.trex = Default::default();
  mvex.trex.track_id = track_id;
});

If these types didn't derive Default, I'm not even sure that it would be possible to set them. Could you export these nested types, or change the mp4box box so it uses pub instead of pub(crate)?

How to convert PNG images to mp4?

I looked at the mp4copy.rs example, but I don't understand how to convert a collection of PNG images to an mp4 file. please help me!

Some box fields are larger in version 1 than version 0.

I have yet to find a video that is using version 1 boxes, but I came across the fact that several fields (e.g. creation time) are double the size if the box is version 1 instead of version 0. I want to address this, but first I want to find a spec to make sure I'm not missing anything. So far I found creation time, modification time, and duration in the mvhd, tkhd, and mdhd boxes.

Standard / Reference for this repo

Hey everyone!

I'm currently working on adding a Timed Metadata Track feature to this project and have been referring to the Apple QTFF documentation. However, I've noticed some inconsistencies (e.g. between the Apple Doc and MinfBox implementation in crate) between this document and the current state of the repo.

I saw in the README that the project references the ISO standards (that links to Wikipedia, which doesn't provide much useful information), which are often behind a paywall and thus not readily accessible for reference. Could you please provide some information about documents or resources that were referenced while developing this repo? It will be very helpful for aligning my work with this project.:)

Regards,
WERDXZ

PS: I'm using this repo for the QuickTime MOV part of creating Apple's Live Photo in rust, and here is a reference for it.

VmhdBox flags issue

I have run into an issue trying to play H.264-encoded .mp4 files created with this crate on Android. After researching the issue and comparing files generated by both mp4-rust and ffmpeg, I found that the vmhd box flags parameter needs to be set to 1 for proper playback on Android.

I have implemented a fix by implementing Default::default() for VmhdBox with flags set to 1 and will post a PR.

Support more audio object formats

Currently, these are the only audio object formats mp4-rust supports:

AacMain
AacLowComplexity
AacScalableSampleRate
AacLongTermPrediction

The MPEG-4 Wikipedia article lists 46 audio object types. Would be great to support all of them

`BoxNotFound(moov)` error in `mp4::Mp4Reader::read_header`

.m4a files saved by QuickTime Player result in a BoxNotFound(moov) error when running mp4::Mp4Reader::read_header.

The file can be played in QuickTime Player, Chrome and VLC just fine.

The moov doesn't seem to be missing:
image

And output from ffprobe seems ok:

  Metadata:
    major_brand     : M4A
    minor_version   : 0
    compatible_brands: M4A mp42isom
    creation_time   : 2021-01-31T05:24:23.000000Z
    iTunSMPB        :  00000000 00000840 00000240 00000000007CA580 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  Duration: 00:03:05.23, start: 0.047891, bitrate: 127 kb/s
    Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 126 kb/s (default)
    Metadata:
      creation_time   : 2021-01-31T05:24:23.000000Z
      handler_name    : Core Media Audio

Here's the m4a file:

Simbai.Elke.Bay.-.Energy.mp4

Getting a reader for track data

I'm trying to pass the aac data from an m4a file to an aac decoder. To do that, I need a reader with R: Read + Seek. Is there any easy way to get that using mp4-rust?

Streaming reads

Hi! Thanks for writing this lib!

Have you thought about the case of streaming reads? It seems the API is centered around Mp4Reader::read_sample(track_id, sample_id) which in turn delegates to Track::read_sample. Reading the code it seems the latter assumes a reader.seek(SeekFrom::Start(sample_offset))?;

With very large files, or continuous TS-streams, it's not necessarily practical to assume the whole things can be wrapped in a BufReader.

Would it be possible to extend the API somehow to have more of a "read-next-sample-whatever-it-is" approach? Happy to contribute a PR.

Example for fMP4

Hi there!
It seems, by looking at the code, that fragmented mp4 boxes are supported. Do you happen to have an example by chance? Or would this need something more to be implemented?
Thanks!

Error in mp4sample example

Hi there,
I think the mp4sample is a little out-of-date.
The expected input as printed is ./mp4sample <track_id> <filename>. In reality, the example only uses the filename, and expects it at args[1], not args[2].

-        println!("Usage: mp4sample <track_id> <filename>");
+        println!("Usage: mp4sample <filename>");

Really useful crate, thanks!

Add video encoding example.

I don't know exactly how to fill in the fields of the structures. It would be good to know the basic combination of version, SPS, PPS which works in most cases. And what the Bytes should look like, raw bytes of frame in the R8G8B8A8 format i hope.

Support for Annex B as well as AVCC

Does this lib support both? For me it's not entirely clear from the docs whether it can do Annex B. A cursory search in the source code, I do find AvccBox, but nothing talking about Annex B.

How to write fmp4?

Hello,

I am currently researching your Rust library and have come across the read_fragment_header() function in the Reader. However, I noticed that there doesn’t seem to be a corresponding function in the Writer for writing the header data.

Could you please provide some guidance on how to use the Writer to write the corresponding data? Is there a specific function or method that I should use, or is this functionality integrated into another function?

Thank you for your time and assistance.

Error: BoxNotFound(hdlr): Not found hdlr

I'm getting this error using videos recoded from phone camera or screen recording -> BoxNotFound(hdlr)
This error doesn't appear when i'm using videos downloaded from social networks or other platfroms.

Ocurs using mp4 = "0.13.0" but read_header works in mp4 = "0.12.0" with all kind of mp4 videos.

let f = std::fs::File::open(temp_file.path()).unwrap();
let size = f.metadata()?.len();
let reader = BufReader::new(f);

let mp4 = mp4::Mp4Reader::read_header(reader, size)?; // -> the error ocurs here 

Question: is HvcCBox complete?

I'm trying to write hevc from an rtsp stream to an mp4 file. The HvcCBox struct only has configuration_version but shouldn't it include some of the other parameters in HEVCDecoderConfigurationRecord like the vps, sps and pps nal units?:

aligned(8) class HEVCDecoderConfigurationRecord {
    unsigned int(8) configurationVersion = 1;
    unsigned int(2) general_profile_space;
    unsigned int(1) general_tier_flag;
    unsigned int(5) general_profile_idc;
    unsigned int(32) general_profile_compatibility_flags;
    unsigned int(48) general_constraint_indicator_flags;
    unsigned int(8) general_level_idc;
    bit(4) reserved = β€˜1111’b;
    unsigned int(12) min_spatial_segmentation_idc;
    bit(6) reserved = β€˜111111’b;
    unsigned int(2) parallelismType;
    bit(6) reserved = β€˜111111’b;
    unsigned int(2) chromaFormat;
    bit(5) reserved = β€˜11111’b;
    unsigned int(3) bitDepthLumaMinus8;
    bit(5) reserved = β€˜11111’b;
    unsigned int(3) bitDepthChromaMinus8;
    bit(16) avgFrameRate;
    bit(2) constantFrameRate;
    bit(3) numTemporalLayers;
    bit(1) temporalIdNested;
    unsigned int(2) lengthSizeMinusOne;
    unsigned int(8) numOfArrays;
    for (j=0; j < numOfArrays; j++) {
        bit(1) array_completeness;
        unsigned int(1) reserved = 0;Ο€βˆ
        unsigned int(6) NAL_unit_type;
        unsigned int(16) numNalus;
        for (i=0; i< numNalus; i++) {
            unsigned int(16) nalUnitLength;
            bit(8*nalUnitLength) nalUnit;
        }
    }
}

When I tried to view the boxes using an mp4 box viewer, it reported that it was missing PPS.

Support for Event message box ('emsg')

As per ISO_IEC_23009-1_2019 (DASH):

The Event Message box ('emsg') provides signalling for generic events related to the media presentation time.

If you want, I will make a PR.

A missing ESDS box is now treated as an error, but why?

Updated to the 0.5.1 release and one of my tests are failing because the test file is missing the ESDS box. The result is an error of type InvalidData with the message "esds not found". The 0.4 release did not treat this condition as an error (or maybe that version never looked for this box type before), but now the 0.5.1 release is failing for me on some files because this box is missing. Is that really an error condition?

AvcConfig Usage

Hi there!

I am trying to combine a .png image and .m4a audio file and am not sure what is required for pic_param_set/seq_param_set. Could you possibly provide a pointer please?

PS - I assume the image/audio data is added to the resulting mp4 via the mp4_writer.write_sample function?

Thanks!

cannot pass cargo clippy under rustc 1.63.0

~/dev/rust/mp4-rust$ cargo clippy
warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:12:30
|
12 | #[derive(Debug, Clone, Copy, PartialEq, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= note: #[warn(clippy::derive_partial_eq_without_eq)] on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:33:30
|
33 | #[derive(Debug, Clone, Copy, PartialEq, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:54:30
|
54 | #[derive(Debug, Clone, Copy, PartialEq, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:89:19
|
89 | #[derive(Default, PartialEq, Clone, Copy, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:168:30
|
168 | #[derive(Debug, Clone, Copy, PartialEq)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:226:30
|
226 | #[derive(Debug, Clone, Copy, PartialEq)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:280:17
|
280 | #[derive(Debug, PartialEq, Clone, Copy)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:319:17
|
319 | #[derive(Debug, PartialEq, Clone, Copy)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:466:17
|
466 | #[derive(Debug, PartialEq, Clone, Copy)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:525:17
|
525 | #[derive(Debug, PartialEq, Clone, Copy)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:567:17
|
567 | #[derive(Debug, PartialEq, Clone, Default)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:575:17
|
575 | #[derive(Debug, PartialEq, Clone, Default)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:581:17
|
581 | #[derive(Debug, PartialEq, Clone, Default)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/types.rs:606:17
|
606 | #[derive(Debug, PartialEq, Clone, Default)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/avc1.rs:265:24
|
265 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/co64.rs:7:24
|
7 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/ctts.rs:26:24
|
26 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/data.rs:10:24
|
10 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/dinf.rs:199:24
|
199 | #[derive(Debug, Clone, PartialEq, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/elst.rs:16:24
|
16 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/emsg.rs:9:24
|
9 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/hev1.rs:156:24
|
156 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/mdhd.rs:8:24
|
8 | #[derive(Debug, Clone, PartialEq, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/mehd.rs:7:24
|
7 | #[derive(Debug, Clone, PartialEq, Serialize, Default)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/mfhd.rs:7:24
|
7 | #[derive(Debug, Clone, PartialEq, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/mp4a.rs:461:24
|
461 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/mp4a.rs:553:24
|
553 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/stco.rs:7:24
|
7 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/stsc.rs:26:24
|
26 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/stss.rs:7:24
|
7 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/stsz.rs:7:24
|
7 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/stts.rs:26:24
|
26 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/tfhd.rs:7:24
|
7 | #[derive(Debug, Clone, PartialEq, Serialize, Default)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/tkhd.rs:54:24
|
54 | #[derive(Debug, Clone, PartialEq, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/trex.rs:7:24
|
7 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/trun.rs:7:24
|
7 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/tx3g.rs:18:24
|
18 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/vmhd.rs:15:24
|
15 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/vpcc.rs:5:24
|
5 | #[derive(Debug, Clone, PartialEq, Default, Serialize)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

warning: you are deriving PartialEq and can implement Eq
--> src/mp4box/mod.rs:118:31
|
118 | #[derive(Clone, Copy, PartialEq)]
| ^^^^^^^^^ help: consider deriving Eq as well: PartialEq, Eq
...
144 | / boxtype! {
145 | | FtypBox => 0x66747970,
146 | | MvhdBox => 0x6d766864,
147 | | MfhdBox => 0x6d666864,
... |
197 | | DescBox => 0x64657363
198 | | }
| |_- in this macro invocation
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
= note: this warning originates in the macro boxtype (in Nightly builds, run with -Z macro-backtrace for more info)

warning: mp4 (lib) generated 40 warnings
Finished dev [unoptimized + debuginfo] target(s) in 0.03s

~/dev/rust/mp4-rust$ rustc --version
rustc 1.63.0 (4b91a6ea7 2022-08-08)

Q: how should unknown boxes be handled?

First, thank you for writing this and making it available. I'm hoping to use it to get the creation time from mp4 files, but I'm running into an issue. It seems that the files produced by iOS contain a box that this crate does not recognize. When that happens, it breaks out of the loop in read_boxes() and subsequently misses reading the other boxes (in particular the moov box that has the creation time).

My question is, what would be the right thing to do? Just set start to size - HEADER_SIZE and carry on (except when size is zero, of course), or something else? I made that change locally and it was able to carry on and find a moov box, which is promising.

By the way, the box type in question was a "wide" box. Not quite sure what that is.

P.S. If this approach sounds reasonable, I can submit a pull request.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.