From be5c296fe8b566c2fdf399fd3f2fd7dd50c512ee Mon Sep 17 00:00:00 2001 From: yinguobing Date: Fri, 9 Aug 2024 10:14:42 +0800 Subject: [PATCH] Release 0.1.0 --- Cargo.toml | 24 ++++++++++++++ README.md | 32 ++++++++++++++++++- src/main.rs | 92 ++++++++++++++++++++++++++++++----------------------- 3 files changed, 108 insertions(+), 40 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cf291e0..7404f81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [package] name = "mcap-extractor" +description = "A simple MCAP extractor" version = "0.1.0" edition = "2021" @@ -14,3 +15,26 @@ zstd = "0.13.2" openh264 = "0.6.1" indicatif = { version = "0.17.8", features = ["rayon"] } image = "0.25.2" + +# To package a DEB package +[package.metadata.deb] +maintainer = "Yin Guobing " +copyright = "2024, Yin Guobing " +license-file = ["LICENSE", "4"] +extended-description = """\ +A simple MCAP extractor.""" +depends = "$auto" +section = "utility" +priority = "optional" +assets = [ + [ + "target/release/mcap-extractor", + "usr/bin/", + "755", + ], + [ + "README.md", + "usr/share/doc/mcap-extractor/README", + "644", + ], +] diff --git a/README.md b/README.md index 2628996..9338aab 100644 --- a/README.md +++ b/README.md @@ -1 +1,31 @@ -# mcap-extractor \ No newline at end of file +# mcap-extractor +This is a tool to extract data from MCAP files. + +## Features +- Extract raw H.264 data and frames from a MCAP file. +- Support sliced MCAP files. + +## Usage +Extract raw H.264 data and frames from a MCAP file. +```bash +mcap-extractor -i /path/to/mcap/dir -o /path/to/output --topic="your_h264_topic" +``` + +## Build +Build the binary +```bash +cargo build --release +``` + +Build the deb package if you want to share it with others +```bash +cargo deb +``` + +## Installation +Download the latest release from the [releases page](https://github.com/yinguobing/mcap-extractor/releases). + +Install using `dpkg`: +```bash +sudo dpkg -i mcap-extractor__amd64.deb +``` diff --git a/src/main.rs b/src/main.rs index 1f92821..4273ec4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,7 +43,7 @@ impl std::fmt::Display for Topic { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, - "id: {}, {}, msgs: {}, {}", + "{}, {}, msgs: {}, {}", self.id, self.name, self.msg_count, self.description ) } @@ -100,7 +100,7 @@ fn main() { // Safety first if !args.input.exists() { - println!("Directory not found: {:?}", args.input.as_os_str()); + println!("Input directory not found: {:?}", args.input.as_os_str()); return; } @@ -133,45 +133,59 @@ fn main() { bar.enable_steady_tick(Duration::from_millis(100)); // Any extracting jobs? - if let Some(topic) = args.topic { - println!("Extracting: {}", topic); - // Create output directory. Using topic name as directory path. - let mut output_dir = args - .output_dir - .clone() - .unwrap_or(std::env::current_dir().unwrap()); - let sub_dir = PathBuf::from(topic.trim_start_matches('/')); - output_dir.push(sub_dir); - if fs::create_dir_all(&output_dir).is_err() { - println!("Failed to create output directory: {:?}", output_dir); - return; - }; - println!("- Output directory: {:}", output_dir.display()); - - println!("- Extracing H.264..."); - let mut parser = h264::Parser::new(&output_dir); - let mut counter = 0; - for file in files.iter() { - let mut fd = fs::File::open(file).unwrap(); - let mut buf = Vec::new(); - fd.read_to_end(&mut buf).unwrap(); - let stream = mcap::MessageStream::new(&buf) - .unwrap() - .filter(|x| x.as_ref().is_ok_and(|x| x.channel.topic == topic)); - for message in stream { - let message = message.unwrap(); - parser.accumulate(&message); - counter += 1; - bar.set_message(format!("{} {}", topic, counter.to_string())); - } + let Some(topic_name) = args.topic else { + println!("No topic specified. Use `--topic` to set topic."); + return; + }; + + // Topic name valid? + let Some(topic_name) = topics.iter().find_map(|t| { + if t.name == topic_name { + Some(topic_name.clone()) + } else { + None } - bar.finish(); + }) else { + println!("Topic not found: {}", topic_name); + return; + }; + println!("Extracting: {}", topic_name); + + // Create output directory. Using topic name as directory path. + let mut output_dir = args + .output_dir + .clone() + .unwrap_or(std::env::current_dir().unwrap()); + let sub_dir = PathBuf::from(topic_name.trim_start_matches('/')); + output_dir.push(sub_dir); + if fs::create_dir_all(&output_dir).is_err() { + println!("Failed to create output directory: {:?}", output_dir); + return; + }; + println!("- Output directory: {:}", output_dir.display()); - // Dump frames - println!("- Extracing camera frames..."); - parser.dump_frames(); - } else { - println!("No topics specified."); + println!("- Extracing H.264..."); + let mut parser = h264::Parser::new(&output_dir); + let mut counter = 0; + for file in files.iter() { + let mut fd = fs::File::open(file).unwrap(); + let mut buf = Vec::new(); + fd.read_to_end(&mut buf).unwrap(); + let stream = mcap::MessageStream::new(&buf) + .unwrap() + .filter(|x| x.as_ref().is_ok_and(|x| x.channel.topic == topic_name)); + for message in stream { + let message = message.unwrap(); + parser.accumulate(&message); + counter += 1; + bar.set_message(format!("{} {}", topic_name, counter.to_string())); + } } + bar.finish(); + + // Dump frames + println!("- Extracing frames..."); + parser.dump_frames(); + println!("Done."); }