Skip to content

Instantly share code, notes, and snippets.

@cleverdevil
Last active January 5, 2025 19:43
Show Gist options
  • Save cleverdevil/3517f75cca4f94bc4256a8f3ab007156 to your computer and use it in GitHub Desktop.
Save cleverdevil/3517f75cca4f94bc4256a8f3ab007156 to your computer and use it in GitHub Desktop.
Dolby Vision Tagger for Plex
'''
Dolby Vision Tagger for Plex
============================
This script walks your Plex server's libraries and tags Dolby Vision Profile
and Enhancement Layer details by attaching a label. The label will be of
format:
Dolby Vision P{profile number} {enhancement layer}
For example, a video with DV P7 FEL would receive the label:
Dolby Vision P7 FEL
Optionally, the script will attach a general "Dolby Vision" label in addition
to the detailed label.
In order to use the script you need to set configuration variables:
Plex Token:
https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/
Plex Server URL:
If run on your Plex server, you can usually use the default, http://127.0.0.1:32400
Binaries Path
The full path to the directory containing your `ffmpeg6` and `dovi_tool`
binaries. You can find `dovi_tool` here: https://github.com/quietvoid/dovi_tool
General Label
True if you want to tag all Dolby Vision videos with a general 'Dolby
Vision' label, otherwise False
This script requires a Python 3.7+ environment with the `plexapi` library
installed and has only been tested on Linux, specifically on a Synology NAS
running DSM7.
'''
import os
import pathlib
import subprocess
import json
from plexapi.server import PlexServer
# Configuration - Set your values here
PLEX_TOKEN = 'xxxxx-xxxxx-xxxxxx'
PLEX_SERVER_URL = 'http://127.0.0.1:32400'
BINARIES_PATH = '/path/to/binaries'
LIBRARIES = ['Movies']
GENERAL_LABEL = True
# Open Plex API and prepare for tagging
plex = PlexServer(PLEX_SERVER_URL, PLEX_TOKEN)
binaries = pathlib.Path(BINARIES_PATH)
# Loop through library sections as specified in our configuration
for library in LIBRARIES:
# Get reference to the library with the specified name
videos = plex.library.section(library)
# Iterate through all videos in the library section and tag them
for video in videos.all():
# First, run `ffmpeg6` on the file, extracting the first second
# of the video to stdout, capturing the output
path = video.locations[0]
ffmpeg = [
binaries / 'ffmpeg6',
'-i', f'{path}', '-c:v', 'copy', '-to', '1', '-f', 'hevc', '-y', '-'
]
ffmpeg_result = subprocess.run(ffmpeg, capture_output=True)
# Feed the output from `ffmpeg6` into `dovi_tool` to extract the RPU
dovi_tool = [binaries / 'dovi_tool', 'extract-rpu', '-', '-o', '/tmp/RPU.bin']
dovi_result = subprocess.run(dovi_tool, input=ffmpeg_result.stdout, capture_output=True)
# If the file does not have Dolby Vision, skip it
if dovi_result.returncode != 0:
continue
# Extract Dolby Vision detail from the RPU file
dovi_tool = [binaries / 'dovi_tool', 'info', '-i', '/tmp/RPU.bin', '-f', '0']
dovi_result = subprocess.run(dovi_tool, capture_output=True)
# If we are unable to extract any detail, skip the file
if dovi_result.returncode != 0:
continue
# Get the output from `dovi_tool` and parse it
output = dovi_result.stdout.decode('utf-8')
metadata = json.loads(output.split('\n', 1)[1])
# Collect any existing labels attached to the video in Plex
labels = [l.tag.lower() for l in video.labels]
# Identify Dolby Vision Profile number and Enhancement Layer type, if any
dv_profile = metadata['dovi_profile']
dv_el_type = metadata.get('el_type', '')
# Generate the label for this profile and enhancement layer
label = f'Dolby Vision P{dv_profile} {dv_el_type}'.strip()
# Attach the label to the video if necessary
if label.lower() not in labels:
print(f'Tagging {video.title} -> {label}')
video.addLabel(label)
# Attach the general label to the video if necessary
if GENERAL_LABEL and 'dolby vision' not in labels:
print(f'Tagging {video.title} -> Dolby Vision')
video.addLabel('Dolby Vision')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment