- Fixed 4 broken markdown links (bad relative paths in See Also sections) - Corrected n8n port binding to 127.0.0.1:5678 (matches actual deployment) - Updated SnapRAID article with actual majorhome paths (/majorRAID, disk1-3) - Converted 67 Obsidian wikilinks to relative markdown links or plain text - Added YAML frontmatter to 35 articles missing it entirely - Completed frontmatter on 8 articles with missing fields Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5.1 KiB
title, domain, category, tags, status, created, updated
| title | domain | category | tags | status | created | updated | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Plex 4K Codec Compatibility (Apple TV) | streaming | plex |
|
published | 2026-04-02 | 2026-04-02 |
Plex 4K Codec Compatibility (Apple TV)
4K content on YouTube is delivered in AV1 or VP9 — neither of which the Plex app on Apple TV can direct play. This forces Plex to transcode, and most home server CPUs can't transcode 4K in real time. The fix is converting to HEVC before Plex ever sees the file.
Codec Compatibility Matrix
| Codec | Apple TV (Plex direct play) | YouTube 4K | Notes |
|---|---|---|---|
| H.264 (AVC) | ✅ | ❌ (max 1080p) | Most compatible, but no 4K |
| HEVC (H.265) | ✅ | ❌ | Best choice: 4K compatible, widely supported |
| VP9 | ❌ | ✅ | Google's royalty-free codec, forces transcode |
| AV1 | ❌ | ✅ | Best compression, requires modern hardware to decode |
Target format: HEVC. Direct plays on Apple TV, supports 4K/HDR, and modern hardware can encode it quickly.
Why AV1 and VP9 Cause Problems
When Plex can't direct play a file it transcodes it on the server. AV1 and VP9 decoding is CPU-intensive — most home server CPUs can't keep up with 4K60 in real time. Intel Quick Sync (HD 630 era) supports VP9 hardware decode but not AV1. AV1 hardware support requires 11th-gen Intel or RTX 30-series+.
Batch Converting Existing Files
For files already in your Plex library, use this script to find all AV1/VP9 files and convert them to HEVC via VAAPI (Intel Quick Sync):
#!/bin/bash
VAAPI_DEV=/dev/dri/renderD128
PLEX_DIR="/plex/plex"
LOG="/root/av1_to_hevc.log"
TMPDIR="/tmp/av1_convert"
mkdir -p "$TMPDIR"
echo "=== AV1→HEVC batch started $(date) ===" | tee -a "$LOG"
find "$PLEX_DIR" -iname "*.mp4" -o -iname "*.mkv" | while IFS= read -r f; do
codec=$(mediainfo --Inform='Video;%Format%' "$f" 2>/dev/null)
[ "$codec" != "AV1" ] && [ "$codec" != "VP9" ] && continue
echo "[$(date +%H:%M:%S)] Converting: $(basename "$f")" | tee -a "$LOG"
tmp="${TMPDIR}/$(basename "${f%.*}").mp4"
ffmpeg -hide_banner -loglevel error \
-vaapi_device "$VAAPI_DEV" \
-i "$f" \
-vf 'format=nv12,hwupload' \
-c:v hevc_vaapi \
-qp 22 \
-c:a copy \
-movflags +faststart \
"$tmp"
if [ $? -eq 0 ] && [ -s "$tmp" ]; then
mv "$tmp" "${f%.*}_hevc.mp4"
rm -f "$f"
else
rm -f "$tmp"
echo " FAILED — original kept." | tee -a "$LOG"
fi
done
Run in a tmux session so it survives SSH disconnect:
tmux new-session -d -s av1-convert '/root/av1_to_hevc.sh'
tail -f /root/av1_to_hevc.log
After completion, trigger a Plex library scan to pick up the renamed files.
Automating Future Downloads (yt-dlp)
Prevent the problem at the source with a post-download conversion hook.
1. Create the conversion script
Save to /usr/local/bin/yt-dlp-hevc-convert.sh:
#!/bin/bash
INPUT="$1"
VAAPI_DEV=/dev/dri/renderD128
LOG=/var/log/yt-dlp-convert.log
[ -z "$INPUT" ] && exit 0
[ ! -f "$INPUT" ] && exit 0
CODEC=$(mediainfo --Inform='Video;%Format%' "$INPUT" 2>/dev/null)
if [ "$CODEC" != "AV1" ] && [ "$CODEC" != "VP9" ]; then
exit 0
fi
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Converting ($CODEC): $(basename "$INPUT")" >> "$LOG"
TMPOUT="${INPUT%.*}_hevc_tmp.mp4"
ffmpeg -hide_banner -loglevel error \
-vaapi_device "$VAAPI_DEV" \
-i "$INPUT" \
-vf 'format=nv12,hwupload' \
-c:v hevc_vaapi \
-qp 22 \
-c:a copy \
-movflags +faststart \
"$TMPOUT"
if [ $? -eq 0 ] && [ -s "$TMPOUT" ]; then
mv "$TMPOUT" "${INPUT%.*}.mp4"
[ "${INPUT%.*}.mp4" != "$INPUT" ] && rm -f "$INPUT"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] OK: $(basename "${INPUT%.*}.mp4")" >> "$LOG"
else
rm -f "$TMPOUT"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] FAILED — original kept: $(basename "$INPUT")" >> "$LOG"
fi
chmod +x /usr/local/bin/yt-dlp-hevc-convert.sh
2. Configure yt-dlp
~/.config/yt-dlp/config:
--remote-components ejs:github
--format bestvideo+bestaudio
--merge-output-format mp4
--output /plex/plex/%(title)s.%(ext)s
--write-auto-subs
--embed-subs
--exec /usr/local/bin/yt-dlp-hevc-convert.sh {}
With this config, yt-dlp <URL> downloads the best available quality (including 4K AV1/VP9), then immediately converts any AV1 or VP9 output to HEVC before Plex indexes it.
[!note] The
--format bestvideo+bestaudioselector gets true 4K from YouTube (served as AV1 or VP9). The hook converts it to HEVC. Without the hook, usingbestvideo[ext=mp4]would cap downloads at 1080p since YouTube only serves H.264 up to 1080p.
Enabling Hardware Transcoding in Plex
Even with automatic conversion in place, enable hardware acceleration in Plex as a fallback for any files that slip through:
Plex Web → Settings → Transcoder → "Use hardware acceleration when available"
This requires Plex Pass. On Intel systems with Quick Sync, VP9 will hardware transcode even without pre-conversion. AV1 will still fall back to CPU on pre-Alder Lake hardware.