{"id":46708414,"url":"https://github.com/giacomopiccinini/rush","last_synced_at":"2026-03-09T08:35:52.591Z","repository":{"id":207578811,"uuid":"715962390","full_name":"giacomopiccinini/rush","owner":"giacomopiccinini","description":"Swiss-army knife for media inspection and manipulation","archived":false,"fork":false,"pushed_at":"2025-05-16T15:00:01.000Z","size":3194,"stargazers_count":11,"open_issues_count":5,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-16T15:46:34.872Z","etag":null,"topics":["cli","data","data-engineering","multimedia","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/giacomopiccinini.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-11-08T07:31:13.000Z","updated_at":"2025-05-16T15:00:02.000Z","dependencies_parsed_at":"2023-12-07T09:23:17.380Z","dependency_job_id":"e3a921aa-6de0-4589-88ad-83f98dccd92f","html_url":"https://github.com/giacomopiccinini/rush","commit_stats":null,"previous_names":["giacomopiccinini/rush"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/giacomopiccinini/rush","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomopiccinini%2Frush","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomopiccinini%2Frush/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomopiccinini%2Frush/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomopiccinini%2Frush/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/giacomopiccinini","download_url":"https://codeload.github.com/giacomopiccinini/rush/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomopiccinini%2Frush/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30287933,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T02:57:19.223Z","status":"ssl_error","status_checked_at":"2026-03-09T02:56:26.373Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","data","data-engineering","multimedia","rust"],"created_at":"2026-03-09T08:35:52.406Z","updated_at":"2026-03-09T08:35:52.581Z","avatar_url":"https://github.com/giacomopiccinini.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rush\n\nA Swiss-army knife CLI tool for media inspection and manipulation, written in Rust.\n\n![](https://github.com/giacomopiccinini/rush/blob/main/assets/rush.gif)\n\n## Table of Contents\n- [Overview](#overview)\n  - [Why rush?](#why-rush?)\n  - [Typical Workflow](#typical-workflow)\n- [Installation](#installation)\n- [Command Categories](#command-categories)\n  - [Audio Commands](#audio-commands)\n  - [Image Commands](#image-commands)\n  - [Video Commands](#video-commands)\n  - [File Commands](#file-commands)\n  - [Table Commands](#table-commands)\n\n## Overview\n\n`rush` is a command-line utility that provides various tools for working with multimedia files and data tables. It's designed to be fast and efficient, leveraging parallel processing where possible. It is capable of handling images, videos, audios, tabular files and (to some extent) \"generic\" files and directories. Restrictions might apply on admissible file formats.\n\n### Why rush?\n\nAs a Machine Learning/Data Engineer, I frequently work with diverse datasets comprising audio files, images, and videos for model training. Common questions that arise include *\"What is the total number of images in the dataset?\"*, *\"What is the combined duration of all videos?\"*, and *\"Are the audio files consistent in their sample rates?\"*.\n\nRush aims to:\n1. Provide comprehensive summaries of file contents and their properties\n2. Enable common file manipulations to ensure dataset consistency\n\n### Typical Workflow\n\nRush exposes a consistent syntax across modalities following the pattern `rush \u003cMEDIA\u003e \u003cCOMMAND\u003e \u003cOPTIONS\u003e`\nTo summarise the imagery in a directory (with all subdirectories included) run\n```bash\nrush image summary photos/\n\n# Total files: 156\n# Unique (height, width) pairs: {(1080, 1920), (800, 600), (3024, 4032)}\n```\nLet's then reshape all of them to a common height-width and store them elsewhere\n```bash\nrush image resize photos/ 1080 1920 reshaped-photos/\n```\nand let's check again the summary\n```bash\nrush image summary reshaped-photos/\n\n# Total files: 156\n# Unique (height, width) pairs: {(1080, 1920)}\n```\n\n## Installation\nAfter cloning the repo, run\n```bash\ncargo install --path .\n```\nBe aware that some extra dependecies are needed, mostly related to FFMpeg and GStreamer. On Debian-like systems, ensure you run first\n```bash\nsudo apt update \u0026\u0026 apt install -y ffmpeg libavformat-dev libavutil-dev libavcodec-dev libavfilter-dev libavdevice-dev libclang-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev\n```\nIf the standard cargo installation fails, please consider using the provided Dockerfile. To build that run\n\n```bash\ndocker build --tag rush .\n```\nNotice, however, that since rush is meant to interact with directories and files on your computer, these are not available straight away to a Docker container running rush. Hence, make sure to mount them before running a command, for instance\n```bash\ndocker run -v \"$(pwd)/test-directory:/app/test-directory\" rush \u003cCOMMAND\u003e /app/test-directory\n```\n## Command Categories\n\n### Audio Commands\n\n#### `audio summary`\nGet metadata about audio files (a single file or a directory).\n\n**Supported Extensions**: `.mp3`, `.wav`, `.ogg`, `.flac`, `.aac`, `.m4a`  \n**Input**: Can be a single file or directory (recursive)\n\n```bash\nrush audio summary \u003ctarget\u003e\n```\n\nExample:\n```bash\nrush audio summary music/\n```\n\nOutput:\n```\nTotal files: 42\nTotal Duration: 02:15:30\nAverage Duration: 193 s\nSample Rates: {44100, 48000} Hz\nChannels: {1, 2}\nBit Depths: {16, 24}\nUnique durations: 42\nMin duration: 120.5 s\nMax duration: 345.2 s\n```\n\n#### `audio split`\nSplit audio files into chunks of specified duration.\n\n**Supported Extensions**: `.wav` only  \n**Input**: Can be a single file or directory (recursive)\n\n```bash\nrush audio split \u003cinput\u003e \u003cchunk_duration\u003e \u003coutput\u003e [--delete-original]\n```\n\nExample:\n```bash\nrush audio split long.wav 30 chunks/ --delete-original\n```\n\nThis will split long.wav into 30-second chunks and save them in the `chunks/` directory. The original `long.wav` file will be deleted.\n\n#### `audio resample`\nChange the sample rate of audio files.\n\n**Supported Extensions**: `.wav` only  \n**Input**: Can be a single file or directory (recursive)\n\n```bash\nrush audio resample \u003cinput\u003e \u003csr\u003e \u003coutput\u003e [--overwrite]\n```\n\nExample:\n```bash\nrush audio resample input.wav 44100 output.wav\n```\n\n#### `audio trim`\nTrim audio files to a specified length.\n\n**Supported Extensions**: `.wav` only  \n**Input**: Can be a single file or directory (recursive)\n\n```bash\nrush audio trim \u003cinput\u003e \u003clength\u003e \u003coutput\u003e [--offset \u003cseconds\u003e] [--overwrite]\n```\n\nExample:\n```bash\nrush audio trim input.wav 60 output.wav --offset 30\n```\n\n### Image Commands\n\n#### `image summary`\nGet metadata about image files.\n\n**Supported Extensions**: `.jpg`, `.jpeg`, `.png`, `.bmp`, `.gif`, `.tiff`  \n**Input**: Can be a single file or directory (recursive)\n\n```bash\nrush image summary \u003ctarget\u003e\n```\n\nExample:\n```bash\nrush image summary photos/\n```\n\nOutput:\n```\nTotal files: 156\nUnique (height, width) pairs: {(1080, 1920), (800, 600), (3024, 4032)}\n```\n\n#### `image resize`\nResize images to specified dimensions.\n\n**Supported Extensions**: `.jpg`, `.jpeg`, `.png`, `.bmp`, `.gif`, `.tiff`  \n**Input**: Can be a single file or directory (recursive)\n\n```bash\nrush image resize \u003cinput\u003e \u003cheight\u003e \u003cwidth\u003e \u003coutput\u003e [--overwrite]\n```\n\nExample:\n```bash\nrush image resize input.jpg 1080 1920 output.jpg\n```\n\n#### `image tessellate`\nSplit images into a grid of smaller images.\n\n**Supported Extensions**: `.jpg`, `.jpeg`, `.png`, `.bmp`, `.gif`, `.tiff`  \n**Input**: Can be a single file or directory (recursive)\n\n```bash\nrush image tessellate \u003cinput\u003e \u003cn_vertical\u003e \u003cn_horizontal\u003e \u003coutput\u003e [--delete-original]\n```\n\nExample:\n```bash\nrush image tessellate photo.jpg 2 3 tiles/\n```\n\nThis splits the image into a 2×3 grid (6 pieces).\n\n#### `image to-landscape`\nRotate images to landscape mode. \n\n**Supported Extensions**: `.jpg`, `.jpeg`, `.png`, `.bmp`, `.gif`, `.tiff`  \n**Input**: Can be a single file or directory (recursive)\n\n```bash\nrush image to-landscape \u003cinput\u003e \u003coutput\u003e [--overwrite]\n```\n\nExample:\n```bash\nrush image to-landscape my-images/ my-images/ --overwrite\n```\n\nThis replaces every image in portrait mode with its rotated version. \n\n#### `image to-portrait`\nRotate images to portrait mode. \n\n**Supported Extensions**: `.jpg`, `.jpeg`, `.png`, `.bmp`, `.gif`, `.tiff`  \n**Input**: Can be a single file or directory (recursive)\n\n```bash\nrush image to-portrait \u003cinput\u003e \u003coutput\u003e [--overwrite]\n```\n\nExample:\n```bash\nrush image to-portrait my-images/ my-images/ --overwrite\n```\n\nThis replaces every image in landscape mode with its rotated version. \n\n### Video Commands\n\n#### `video summary`\nGet metadata about video files.\n\n**Supported Extensions**: `.ts`, `.mp4`, `.mkv`, `.mov`  \n**Input**: Can be a single file or directory (recursive)\n\n```bash\nrush video summary \u003ctarget\u003e\n```\n\nExample:\n```bash\nrush video summary videos/\n```\n\nOutput:\n```\nTotal files: 12\nTotal duration: 3600.5\nUnique durations: {120, 240, 360}\nUnique (height, width) pairs: {(1080, 1920), (720, 1280)}\nUnique FPS: {(30, 1), (60, 1)}\n```\n\n#### `video to-frames`\nExtract frames from a video\n\n**Supported Extensions**: `.ts`, `.mp4`, `.mkv`, `.mov`  \n**Input**: Needs to be a single file\n\n```bash\nrush video to-frames \u003cinput\u003e \u003coutput\u003e\n```\n\nExample:\n```bash\nrush video to-frames video.mp4 frames/\n```\n\n#### `video from-frames`\nCollect frames back into a video\n\n**Supported Extensions**: `.jpg`, `.jpeg`, `.png`\n**Input**: Needs to be a directory\n\n```bash\nrush video from-frames \u003cinput\u003e \u003cfps\u003e \u003coutput\u003e\n```\n\nExample:\n```bash\nrush video from-frames frames/ 30 output.mp4\n```\n\n#### `video duplicates`\nFind duplicated videos in a directory. \n\n**Supported Extensions**: `ts`, `mp4`, `mkv`, `mov`\n**Input**: Needs to be a directory\n\n```bash\nrush video duplicates \u003ctarget\u003e\n```\n\nExample:\n```bash\nrush video duplicates my_videos/\n```\n\n\n### File Commands\n\n#### `file count`\nCount files and directories in a given path.\n\n**Supported Extensions**: All files  \n**Input**: Can be a single file or directory (non-recursive, only immediate children)\n\n```bash\nrush file count \u003ctarget\u003e\n```\n\nExample:\n```bash\nrush file count documents/\n```\n\nOutput:\n```\nFiles: 145\nDirectories: 12\n```\n\n#### `file extension`\nFind and count all the instances of file extensions.\n\n**Supported Extensions**: All files  \n**Input**: Can be a single file or directory (non-recursive, only immediate children)\n\n```bash\nrush file extension \u003ctarget\u003e\n```\n\nExample:\n```bash\nrush file extension documents/\n```\n\n### Table Commands\n\n#### `table schema`\nDisplay the schema of a CSV or Parquet file.\n\n**Supported Extensions**: `.csv`, `.parquet`  \n**Input**: Single file only (directories not supported)\n\n```bash\nrush table schema \u003cinput\u003e\n```\n\nExample:\n```bash\nrush table schema data.csv\n```\n\nOutput:\n```\nSchema:\nname: Name, field: String\nname: Age, field: Int64\nname: Department, field: String\nname: Salary, field: Int64\n```\n\n#### `table summary`\nShow the first five and last five rows of a table. \n\n**Supported Extensions**: `.csv`, `.parquet`  \n**Input**: Single file only (directories not supported)\n\n```bash\nrush table summary \u003cinput\u003e\n```\n\nExample:\n```bash\nrush table summary data.csv\n```\n\n#### `table to-csv`\nConvert a .parquet file to .csv.\n\n**Supported Extensions**: `.parquet`  \n**Input**: Single file only (directories not supported)\n\n```bash\nrush table to-csv \u003cinput\u003e \u003coutput\u003e\n```\n\nExample:\n```bash\nrush table to-csv data.parquet data.csv\n```\n\n#### `table to-parquet`\nConvert a .csv file to .parquet.\n\n**Supported Extensions**: `.csv`\n**Input**: Single file only (directories not supported)\n\n```bash\nrush table to-parquet \u003cinput\u003e \u003coutput\u003e\n```\n\nExample:\n```bash\nrush table to-parquet data.csv data.parquet\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiacomopiccinini%2Frush","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgiacomopiccinini%2Frush","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiacomopiccinini%2Frush/lists"}