Embedding Metadata & Posters into Video Files Using tinyMediaManager
Managing a digital video collection isn’t just about keeping files organized - it’s about having rich metadata like titles, genres, descriptions, and artwork that provide a polished media library experience. Tools like tinyMediaManager make it easy to fetch and manage this metadata, but the data is typically saved in external .nfo
and image files.
To embed this metadata directly into the video files, we’ll combine tinyMediaManager with the mighty FFmpeg, using nothing but a post-processing script - and no external tools beyond FFmpeg itself. We’ll also use JMTE templating, a built-in feature of tinyMediaManager, to streamline the process and avoid parsing .nfo
files manually.
This approach works on Windows, macOS, and Linux for tinyMediaManager versions starting from v5.1.7
.
ATTENTION: Attaching metadata alters your video files! Changed video files are detected by the “update data sources” action in tinyMediaManager as new/replaced files!
⚙️ What You’ll Need
- tinyMediaManager v5.1.7+
- FFmpeg (4.3+ is ideal - tinyMediaManager already ships an up to date FFmepg which we will use)
- A terminal or command-line shell
- Basic scripting skills (Bash or Batch)
🧩 What is JMTE?
JMTE stands for Java Minimal Template Engine. It’s a lightweight templating language used in tinyMediaManager to insert metadata variables into scripts, filenames, and post-processing commands.
Instead of parsing .nfo
XML files, tinyMediaManager can inject metadata directly into command-line arguments using placeholders like:
1
2
3
4
5
${movie.title}
${movie.year}
${movie.plot}
${movie.mainVideoFile.file}
${movie.artworkMap.POSTER.file}
This makes scripting faster, simpler, and more reliable.
🛠️ Script Setup
Depending on your system, you need to either use a shellscript (Linux, macOS) or a Windows Batch file/PowerShell script (Windows). You should place the script into the same folder as the ffmpeg
binary is - if you want to use the shipped ffmpeg
, this would be in the addons
folder of your tinyMediaManager installation. The easiest way to find the addons
folder of your installation would be to open tinyMediaManager itself and use the action “Tools -> Open content folder” and locate the subfolder addons
.
🐧 Linux/macOS Shell Script: embed-metadata.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/bin/bash
# Script: embed-metadata.sh
set -e
VIDEO="$1"
TITLE="$2"
YEAR="$3"
PLOT="$4"
POSTER="$5"
if [ -z "$VIDEO" ] || [ ! -f "$VIDEO" ]; then
echo "Error: Video file is missing or does not exist."
exit 1
fi
EXT="${VIDEO##*.}"
EXT_LOWER=$(echo "$EXT" | tr '[:upper:]' '[:lower:]')
case "$EXT_LOWER" in
mp4|mkv)
CAN_EMBED_POSTER=true
;;
mov)
CAN_EMBED_POSTER=false
;;
*)
echo "Error: Unsupported video format '$EXT_LOWER'. Supported formats: mp4, mkv, mov."
exit 1
;;
esac
# Temporary output file
TMP_OUTPUT="${VIDEO}.tmp.${EXT_LOWER}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CMD=("$SCRIPT_DIR/ffmpeg" -y -i "$VIDEO")
if [ "$CAN_EMBED_POSTER" = true ] && [ -f "$POSTER" ]; then
CMD+=(-i "$POSTER" -map 0 -map 1 -disposition:v:1 attached_pic)
else
CMD+=(-map 0)
fi
CMD+=(
-metadata title="$TITLE"
-metadata year="$YEAR"
-metadata comment="$PLOT"
-c copy "$TMP_OUTPUT"
)
# Run FFmpeg command
echo "Running FFmpeg..."
if "${CMD[@]}" > /dev/null 2>&1; then
mv -f "$TMP_OUTPUT" "$VIDEO"
echo "Successfully updated metadata in '$VIDEO'"
else
echo "FFmpeg failed. Original file left untouched."
rm -f "$TMP_OUTPUT"
exit 1
fi
Make it executable:
1
chmod +x /path/to/embed-metadata.sh
🪟 Windows Batch Script: embed-metadata.bat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@echo off
setlocal enabledelayedexpansion
set "VIDEO=%~1"
set "TITLE=%~2"
set "YEAR=%~3"
set "PLOT=%~4"
set "POSTER=%~5"
if not exist "%VIDEO%" (
echo Error: Video file is missing or does not exist.
exit /b 1
)
set "EXT=%~x1"
set "EXT_LOWER=%EXT:.=%"
set "EXT_LOWER=%EXT_LOWER:~1%"
set "EXT_LOWER=%EXT_LOWER:~0,3%"
set "EXT_LOWER=%EXT_LOWER:~0,3%"
if /i "%EXT_LOWER%"=="mp4" (
set "CAN_EMBED_POSTER=true"
) else if /i "%EXT_LOWER%"=="mkv" (
set "CAN_EMBED_POSTER=true"
) else if /i "%EXT_LOWER%"=="mov" (
set "CAN_EMBED_POSTER=false"
) else (
echo Error: Unsupported video format '%EXT_LOWER%'. Supported formats: mp4, mkv, mov.
exit /b 1
)
set "TMP_OUTPUT=%VIDEO%.tmp.%EXT_LOWER%"
set "SCRIPT_DIR=%~dp0"
if "%CAN_EMBED_POSTER%"=="true" if exist "%POSTER%" (
"%SCRIPT_DIR%ffmpeg.exe" -y -i "%VIDEO%" -i "%POSTER%" -map 0 -map 1 -disposition:v:1 attached_pic ^
-metadata title="%TITLE%" -metadata year="%YEAR%" -metadata comment="%PLOT%" -c copy "%TMP_OUTPUT%" >nul 2>&1
) else (
"%SCRIPT_DIR%ffmpeg.exe" -y -i "%VIDEO%" -map 0 ^
-metadata title="%TITLE%" -metadata year="%YEAR%" -metadata comment="%PLOT%" -c copy "%TMP_OUTPUT%" >nul 2>&1
)
if exist "%TMP_OUTPUT%" (
move /Y "%TMP_OUTPUT%" "%VIDEO%" >nul
echo Successfully updated metadata in "%VIDEO%"
) else (
echo FFmpeg failed. Original file left untouched.
exit /b 1
)
🪟 Windows Powershell Script: embed-metadata.ps
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
param (
[string]$Video,
[string]$Title,
[string]$Year,
[string]$Plot,
[string]$Poster
)
if (-not (Test-Path $Video)) {
Write-Error "Error: Video file is missing or does not exist."
exit 1
}
$Ext = [System.IO.Path]::GetExtension($Video).TrimStart('.').ToLower()
switch ($Ext) {
"mp4" { $CanEmbedPoster = $true }
"mkv" { $CanEmbedPoster = $true }
"mov" { $CanEmbedPoster = $false }
default {
Write-Error "Error: Unsupported video format '$Ext'. Supported formats: mp4, mkv, mov."
exit 1
}
}
$TmpOutput = "$Video.tmp.$Ext"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$Args = @("-y", "-i", $Video)
if ($CanEmbedPoster -and (Test-Path $Poster)) {
$Args += @("-i", $Poster, "-map", "0", "-map", "1", "-disposition:v:1", "attached_pic")
} else {
$Args += @("-map", "0")
}
$Args += @(
"-metadata", "title=$Title",
"-metadata", "year=$Year",
"-metadata", "comment=$Plot",
"-c", "copy",
$TmpOutput
)
Write-Host "Running FFmpeg..."
$ffmpeg = Join-Path $ScriptDir "ffmpeg.exe"
$process = Start-Process -FilePath $ffmpeg -ArgumentList $Args -NoNewWindow -Wait -PassThru -RedirectStandardOutput $null -RedirectStandardError $null
if ($process.ExitCode -eq 0 -and (Test-Path $TmpOutput)) {
Move-Item -Force $TmpOutput $Video
Write-Host "Successfully updated metadata in '$Video'"
} else {
Write-Error "FFmpeg failed. Original file left untouched."
if (Test-Path $TmpOutput) {
Remove-Item $TmpOutput -Force
}
exit 1
}
📁 Configure Post-Processing in tinyMediaManager
- Go to Settings → Movies / TV shows → Post-Processing
- Add a new Post-Processing entry:
- Name as you wish (e.g.
Embed metadata
) - Path to the script (absolute path - use the file explorer to find the script in the addons folder)
- Script arguments:
1 2 3 4 5
"${movie.mainVideoFile.file}" "${movie.title}" "${movie.year}" "${movie.plot}" "${movie.artworkMap.POSTER.file}"
- Name as you wish (e.g.
Always test scripts with a sample file before bulk tagging
🧠 Final Thoughts
Embedding metadata directly into your video files means your collection is self-contained, portable, and ready for any media player. By combining tinyMediaManager, JMTE templating, and FFmpeg, you gain an efficient workflow without additional tools or manual steps.
This script-based approach is clean, fast, and platform-independent. It’s a fantastic way to bring professional polish to your personal media collection - fully automated, fully yours.