A versatile tool to fix, organize, and maintain your home media library.
- Smart Organization: Automatically organize photos and videos by date from EXIF data
- Duplicate Detection: Find and remove duplicate media files
- Tag Management: Add, remove, and search media files by custom tags
- AI-Powered Classification:
- Face detection and recognition, tagging photos with names
- Age, gender, emotion detection
- Content classification (NSFW detection)
- EXIF Management: View, set, and modify EXIF metadata
- File Validation: Detect corrupted media files
- Flexible Configuration: Customizable organization patterns and rules
Table of Contents:
-
Install Home Media Organizer with
pip install home-media-organizer
-
(Optional) Install exiftool for EXIF related operations.
-
(Optional) Install ffmpeg with
conda install ffmpeg -c conda-forge
or some other methods suitable for your environment. This tool is only used to validate if your mp4/mpg files are playable using command
hmo validate
. -
(Optional) Create a configuration file
~/.home-media-organizer/config.toml
that reflect the configuration of your home media library. These options define default parameters for thehmo
commands. Adding them to a configuration file greatly simplifies the use ofhmo
.
[default]
search-paths = ['/Volumes/NAS/incoming', '/Volumes/NAS/MyPictures']
media-root = '/Volumes/NAS/MyPictures'
[rename]
format = '%Y%m%d_%H%M%S'
[organize]
dir-pattern = '%Y/%Y-%m'
album-sep = '-'
[cleanup]
file_types = [
"*.MOI",
"*.PGI",
".LRC",
"*.THM",
"Default.PLS",
".picasa*.ini",
"Thumbs.db",
"*.ini",
"*.bat",
"autprint*"
]
See Configuration file for details.
- Start using Home Media Organizer
hmo -h
For details usages of each command, please visit Home Media Organizer Documentation.
hmo list 2020 --file-types '*.jpg'
will print the name of all files under directory 2020
, with a message showing the number of files at the end. Note that
- If
2020
is not under the current directory, it will be searched from--search-paths
. --file-types
is a file pattern, so you can use options such as--file-types '202012*.jpg'
to list all files starting with202012
.
hmo rename incoming_folder
will
- Retrieve the datatime information of all media files under
incoming_folder
- Calculate canonical names for each file according to a
--format
specification, which is usually specified in the configuration files. - Rename files interactively or in batch mode if
--yes
is specified.
Note that
--format
uses patterns defined by Python datetime module. For example,%Y%m%d_%H%M%S
rename files to names such as20201225_212917.jpg
.
It is sometimes desired to add some suffix to filenames, for example to show who took the pictures, which camera was used, where the picture was taken. This can be achieved by
hmo rename incoming_folder --suffix=-kat
which renames files to 20201225_212917-kat.jpg
.
hmo
organize files according to media_root
and dir-pattern
. If you have dir-pattern
defined as %Y/%Y-%m
,
hmo organize incoming_folder
will move files under incoming_folder
to /path/to/library/2020/2020-12/
.
If you would like to put the files into an album-specific folder, you can use
hmo organize incoming_folder --album hawaii
to move files to paths such as /path/to/library/2020/2020-12-hawaii/
.
The album name is appended to dir-pattern
with a dash ( album-sep="-"
, default). You can set album-sep="/"
if you would like albums to be organized as /path/to/library/2020/2020-12/hawaii/
.
hmo dedup 2024
will find duplicated files under directory 2024
and ask you which copy you would like to keep. If you run in batch mode
hmo dedup 2024 --yes
The command will keep the file with the longest paths, under the assumption that the file with longer path contains more information (suffix, album etc.).
Note that hmo dedup
checks file contents so files with different filenames but the same contents are considered as duplicates.
To find out the emotions of people in the photos, you first need to annotate all pictures with appropriate tags, with command
hmo classify 2025 --models emotion --yes
This command will tag all photos with faces with emotions such as angry
, fear
, neutral
, sad
, and happy
. With tags assigned to these photos, you can count the number of happy
photos with command
hmo list 2025 --with-tags happy | wc -l
and compare that to the results with
hmo list 2025 --with-tags sad | wc -l
Following the same idea, you can assign photos with tags such as baby
, toddler
, and adult
using the age
model and list photos with sad adults using
hmo classify 2025 --models age emotion -y
hmo list 2025 --with-tags 'sad AND adult'
Note that
sad AND adult
is needed because--with-tags sad adult
will list all photos withsad
oradult
tags.- If you want to see how this command works, find a picture and run the classifier with
-v
(verbose) option.
hmo classify 2025/2025-01/20250117_123847.jpg --model emotion -v
This step is actually recommended because some models may require additional downloads and dependencies (e.g. emotion:deepface:dlib
needs a separate installation of dlib
), so it is best to test a model before apply it to a large number of files.
Your library contains tens of thousands of photos and it is challenging to find ones with you, your wife, or your children. Face recognition can be used to address this issue by tagging photos with names.
To start tagging all photos with you, you need to find a few reference photos, preferably portraits that clearly show your facial characteristics. You should first try to see if hmo
considers them the same person, using command
hmo set-tags 2020/20200102_123847.jpg --tags John --if-similar-to 2020/20200305_023047.jpg
and adjust threshold
(default to 0.8) if necessary
hmo set-tags 2020/20200102_123847.jpg --tags John --if-similar-to 2020/20200305_023047.jpg --threshold 0.70
You then let hmo
identify photo with faces resemble one of these photos, using command
hmo set-tags 2020 --tags John --if-similar-to 2020/20200102_123847.jpg 2020/20200305_023047.jpg --yes --threshold 0.70
If you are unsatisfied with the command, you can run
hmo remove-tags 2020 --tags John
to remove the tags and try different reference photos and threshold. Otherwise, enjoy an easy way to find all your photos
hmo list 2020 --with-tags 'John AND happy'
You may have a separate copy of files, for example, files backed up to DVD or some other media, or files dumped from your camera a while ago, and you would like to know if any files have been changed, removed, or if they have been properly organized into your home library.
Such problems involves the comparison between two sets of files and are performed by command hmo compare
. This command accepts parameters such as --A-and-B
, --A-only
, --B-only
, and --A-or-B
where A
refers to the targets of hmo compare
command and B
refers to the files or directories after parameter --B-only
.
For example
hmo compare 2025 --B-only my_local_directory
list files under my_local_directory
that are not under 2025
. This command compares based on the content of the files so it does not matter if the files have been renamed before copying into 2025
.
If you would like to include files that have been renamed as --B-only
, use the --by
option:
hmo compare 2025 --B-only my_local_directory --by name_and_content
If you would like to see how the files have been mapped between two sets of files, you can do something like
hmo compare 2025 --A-and-B my_local_directory
The output will be similar to
2025/20250102_020305.jpg=my_local_directory/IMG_4885.jpg
For files that do not have date related EXIF information, PLEX server will use file modify date to organize them. When you check the EXIF information of a file using hmo
, this information is shown as metadata File:FileModifyDate
, and you can use the same hmo shift-exif
and hmo set-exif
interface to modify this information.
For example, if you a video about your wedding that happened last year does not come with any EXIF information,
> hmo show-exif wedding.mpg --keys '*Date'
{
"File:FileModifyDate": "2020:01:18 10:13:33-06:00",
"File:FileAccessDate": "2020:01:18 10:13:33-06:00",
"File:FileInodeChangeDate": "2025:01:19 10:48:00-06:00"
}
You can set the modified date as follows:
> hmo shift-exif wedding.mpg --keys File:FileModifyDate --year=-1 --month 3
> hmo show-exif wedding.mpg --keys '*Date'
{
"File:FileModifyDate": "2019:04:18 10:13:33-05:00",
"File:FileAccessDate": "2019:04:18 10:13:33-05:00",
"File:FileInodeChangeDate": "2025:01:19 10:50:23-06:00"
}
However, file modify date is NOT part of the file content. If you copy the file to another location, the new file will have a new modified date and you may need to run the hmo set-exif --from-filename
again.
hmo backup
andhmo restore
to backup lirary to other (cloud) storages.- Add a
--copy
mode to make sure that the source files will not be changed or moved duringhmo rename
orhme organize
. - Improve data detection from media files without EXIF information to handle more types of medias.
- Support for music and movies?
This package was created with Cookiecutter and the fedejaure/cookiecutter-modern-pypackage project template.