Post processing scripts to augment the Plex Media Server DVR functionality.
PMS (Plex Media Server) includes DVR functionality for PlexPass subscribers. Typically DVR tuners in Plex capture and store the native broacast file format. In ATSC 1.0 broadcast region(s) this probably means MPEG2/TS files. These files, MPEG2 in particular, take up more storage space compared to H264 or H265 at the same (subjective) quality.
PMS offers a POSTPROCESSING step that allows for modification of the captured video file prior to it being added to the PMS library. This provides a good opportunity to recompress (or perform other operations on) the fat broadcast file.
The scripts in this repository are designed to be copied to your Plex server and specified in the global DVR settings POSTPROCESSING field. Only one script may be used, as-is, by PMS. Multiple scripts could be chained by a parent script -- that is outside the scope of this repository.
Converts the captured file (tested w/ MPEG2/AC3) to a lower bit-rate H264/AAC file. The script uses a default bitrate calculation based on the frame size and frame rate. It also encodes the source audio stream into a stereo AAC stream with a DPLII mix (Dolby ProLogic compatible device required for multi-channel sound). NVDEC/NVENC hardware acceleration will be used if supported by the system (if nVidia HW transcoding works in Plex, it will probably work here). Optional commercial detection can be enabled. Finally, when the file is done being processed, the original is deleted and the transcoded file is added to the PMS library.
This script uses the PMS built-in Plex executables. It does not require the installation of any additional video encoders.
No environment variables are required for operation. However, some encoding defaults can be overriden by the following environment variables:
AACRATE
- AAC audio bitrate in Kb/s (default: 192)VBRMULT
- Average video bitrate multiplier. Setting to 2.0 will double the average bitrate. 0.5 will cut the bitrate in half.(default: 1.0)TMPFOLDER
- Temporary location for in-process transcoding (default: '/tmp')PPFORMAT
- Output file format. Either 'mp4' or 'mkv'. 'mp4' supports FFMPEG faststart flag. (default: 'mp4')ONLYMPEG2
- Set to 'true' to limit transcoding to 'mpeg2video' source content. (default: 'false')TRANSCODE
- Set to 'false' to skip the video transcoding step. (default: 'true')COMCHAP
- Set to 'true' to scan for commercials and add chapters to the video. Does not alter the video. (default: 'false')FFMPEGLIBS
- Set to a folder that contains (at any depth) the libmpeg2video_decoder.so
library. If not specified, will try a couple standard locations. (default: '')LOGLEVEL
- Controls how much of the encoding process is logged. 0
=none, 1
=STDOUT msgs, 2
=STDOUT+STDERR for debugging. Logs are placed in /tmp
. (default: '1')COPYAUDIO
- Allows the original audio to be copied from the source instead of converted to AAC. (default: 'false')/config/Library/Application Support/Plex Media Server/Scripts/
)
chmod +x transcode_internal.sh
)transcode_internal.sh
as the postprocessing script nameWhen the PMS DVR finishes a recording it will call this script with the recently recorded filename as the only parameter. This script will attempt to transcode the recorded file into the configured file format (see above).
TEMPFOLDER
.When the PMS DVR finishes a recording it will call this script with the recently recorded filename as the only parameter. This script will attempt to scan the source file for commercials. If found, chapter indicators will be added to the file.
NOTE: Chapter thumbnails may not be generated until the daily scheduled task is run, even on servers set to update thumbnails on library update.
Beauty is in the eye of the beholder, thus the appropriate bitrate for video encoding is very subjective. Goals with the default settings in this script are as follows:
From eyeball analysis of the resulting files, a target average video bitrate of ~4,000 Kbps for 1280x720@60fps was found to meet the above goals. From that a very simple calculation was derived to try and achieve a similar quality standard at a predictable file size. In essence, the formula determines a per-pixel bitrate:
WIDTH HEIGHT FRAMERATE == PIXELS_PER_SECOND
PIXELS_PER_SECOND BITRATE_CONSTANT = AVERAGE_BITRATE*
By default, the BITRATE_CONSTANT is 0.000072 Kb, or in other words, each pixel is alloted 0.000072 Kb per second. The following table illustrates the calculated bitrates for standard ATSC video formats:
Width | Height | FPS | Pixels per second | Bitrate (Kbps) |
---|---|---|---|---|
704 | 480 | 29.97 | 10127462.4 | 729 |
1280 | 720 | 59.94 | 55240704 | 3977 |
1920 | 1080 | 29.97 | 62145792 | 4474 |
The BITRATE_CONSTANT can be overidden by setting the PPSRATE
environment variable (default: 0.000072). However, small changes to that number can have drastic downstream consequences. Instead, consider setting the VBRMULT
(default: 1.0) environment variable to add a multiplier to the final bitrate calculation (see above).
But why not just use x264's CQP (Constant Quantization Parameter) encoding? If only I could. There exists two main reasons constant quality encoding is not used:
While your actual results will vary, in general the speed of your transcodes depends on how fast your disks, cpu, memory, and nvidia hardware are. You can also tailor this script (via the environment variables) to skip some steps to increase transcode speed:
TMPFOLDER="/my/ssd/drive"
. This script creates a remuxed MKV temp file and otherwise does a lot of disk IO.COMCHAP="false"
. Commercial scanning will not use nvidia hardware so must run in software, on your CPU.COPYAUDIO="false"
. Converting audio to AAC must run in software on your CPU. For some video sizes, this causes the GPU (NVENC) to wait for audio processing.The following chart compares transcoding times between NVENC and x264 as well as between AAC conversion and direct AC3 stream copies (i.e., no audio conversion).
The GPU can really tear through 480i content when it doesn't have to wait on AAC conversion. However, at higher resolutions, while GPU is faster than CPU the AAC conversion makes less of a impact.
Encoding with NVENC can be convenient for its filesize and speed, but may not be desirable for its image quality. More recent NVENC implemenatations (like in the RTX line of cards) may improve quality over previous implementations (GTX), however it is generally understood that software encoding (x264) yields the better quality results (per bit).
NOTE: In the context of this script, MPEG2 reppresents the reference video quality. It is the best possible video quality and is what x264 and NVENC results should be compared against.
Roughly speaking, when deciding which encoder to use, you can choose 2 of the following:
Encoder | Speed | Quality | File Size | Notes |
---|---|---|---|---|
MPEG2 (no encoding) | X | X | This is the source material. No re-encodong. Best (original) quality. | |
x264 (CPU encoding) | X | X | Software encoding using the CPU. | |
NVENC (GPU encoding) | X | X | NVIDIA h.264 encoding using the GPU. |
This script uses NVENC if it finds properly configured NVIDIA drivers. Otherwise, it will fallback to x264.