Files
media-batch-tools/README.md
T
2026-06-03 13:29:14 +00:00

108 lines
5.5 KiB
Markdown

# Media Batch Tools
Small Python scripts for organizing photo collections, with videos handled as companion files when they are part of the same folder of photos.
## Scripts
### `photo_metadata.py`
Interactive metadata cleanup for photo collections:
```bash
python3 photo_metadata.py path/to/file/or/directory [...]
```
Directory inputs are scanned recursively. The script reads metadata, asks for the choices it needs, prints a preview, and only then applies changes in place after confirmation.
Current features:
- supports `.jpg`, `.jpeg`, `.heic`, `.arw`, `.mp4`, `.mov`, and `.mts`
- reads and writes metadata through `exiftool` from `PATH`
- optional direct time shifts, such as `+1:30`, `-02:00:00`, or `+1h 2m`
- optional reference-clock correction using a source photo timestamp or filename plus the correct time
- timezone handling for photos and local-time video filenames
- artist/author set, clear, or leave unchanged
- timestamp-based renaming to `YYYYMMDD_HHMMSS.ext`
- video filenames use the beginning timestamp by subtracting rounded duration from the video metadata timestamp
- Sony-style video sidecars like `C0011.MP4` plus `C0011M01.XML` are moved and renamed with the video
- automatic photo burst/HDR grouping per camera
- inferred subsecond metadata for grouped same-second photo bursts
The working directory is determined from the dragged items. A single dragged folder is the working directory. For multiple dragged files/folders, their last common ancestor is the working directory. Automatic burst/HDR group folders are created inside that working directory.
If dragged folders contain files in subdirectories, `photo_metadata.py` asks whether ungrouped files should be moved into the working directory. The default is to leave them in their existing subdirectories.
Reference-clock correction is useful when one photo shows a reliable clock. For example, if `DSC01234.JPG` has camera metadata `2026:06:02 22:10:00`, but the clock in the photo shows `22:13:25`, choose reference mode, enter `DSC01234.JPG` as the source, and enter `22:13:25` as the correct time. The script computes a `+00:03:25` shift and applies that correction to the selected files. If you omit the date in the correct time, the script chooses the date closest to the source timestamp, within 12 hours.
### `grouping.py`
Fast manual grouping for selected files:
```bash
python3 grouping.py path/to/file/or/directory [...]
```
It does not ask questions. It sorts the selected filesystem items by name and moves them into one folder named `[first stem]-[last stem]`.
Manual grouping uses filesystem items, not media-file detection:
- one file creates `[file stem]-[file stem]` and moves that file into it
- one directory acts as if its contents were given; if it contains only one subdirectory, that rule repeats
- one empty directory does nothing
- multiple files/folders are grouped as selected, without flattening folder contents
### `view_metadata.py`
Show all readable metadata for the first file provided:
```bash
python3 view_metadata.py path/to/file/or/directory [...]
```
This script only displays one file. If several files are given, it displays the first one. If a directory is given, it searches recursively and displays the first file it finds.
It runs ExifTool as:
```bash
exiftool -a -u -ee -G0:1 -s file
```
The important choices are:
- `-a` shows duplicate tag names instead of hiding later duplicates.
- `-u` includes unknown tags ExifTool can identify well enough to print.
- `-ee` extracts embedded metadata where ExifTool supports it, which is useful for some video/container formats.
- `-G0:1` shows both the broad metadata container and the more exact location, such as `EXIF:IFD0` or `QuickTime:Track1`.
- `-s` uses compact tag names, which are easier to copy into scripts than the descriptive labels.
The old `-G` style shows broad groups like `EXIF`, `File`, or `QuickTime`. That is readable, but it can hide where inside a container a value came from. Family 1 groups, from `-G1`, show more exact locations like `IFD0`, `ExifIFD`, `MakerNotes`, or `Track1`, but sometimes lose the broader context. `-G0:1` combines both, so it is the most useful default for debugging metadata without changing which normal tags are extracted. The organization option changes labels, not the underlying metadata extraction; `-a` and `-u` are the parts that affect whether duplicate or unknown printed tags are included.
## Requirements
- Python 3.10 or newer
- ExifTool available as `exiftool` on `PATH`
On Debian/Ubuntu-like Linux systems, ExifTool is commonly installed with:
```bash
sudo apt install libimage-exiftool-perl
```
On Windows, install ExifTool and make sure the `exiftool` command is available in a normal terminal.
No virtual environment is required. The scripts use only the Python standard library plus external command-line tools.
## Safety
`photo_metadata.py` edits files in place, but it prints a preview and asks for confirmation before writing metadata or moving files. Test media should be copied to a temporary directory before running destructive checks.
`tests/`, `old/`, and `PLAN.md` are intentionally ignored by git. The `tests/` directory is for reusable source fixtures that should not be modified directly.
## Later Work
Separate video tools may be added later for remuxing, re-encoding, audio extraction/conversion, and timecode handling. Those features are intentionally not mixed into `photo_metadata.py`.
## AI Note
This code was written with AI assistance and should be reviewed and tested before relying on it for important media archives.