A C++ library for reading Presentation Graphics Stream (PGS) subtitles.
Check out the documentation here.
- CMake 3.15 or newer
- C++ compiler with native C++14 support
- GCC 5 or newer
- Clang 3.4 or newer
- Others not tested but potentially usable: https://en.cppreference.com/w/cpp/compiler_support#cpp14
- Everything in previous section
- GTest
- GraphicsMagick with Magick++
- OpenMP
- Navigate to project directory.
- Make a build directory and change directory into it.
mkdir buildcd build
cmake -DCMAKE_BUILD_TYPE=Release ..
makecmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=on ..
makeThe library tests rely on having 2 valid, binary PGS files in the ./test/res directory. One should be named subs.sup, and the other should be named subs_short.sup. As the names imply, subs_short.sup is an abbreviated version of subs.sup.
Getting valid PGS data requires having a legally-obtained copy of a Blu-ray disc ripped to your computer storage. You can use MakeMKV to create an MKV file containing any part of the Blu-ray data you want including the subtitles (as PGS data streams). To make the rest of the process easier, it's best to select only one subtitle stream.
After MakeMKV has finished processing the file, you can use FFmpeg to exract the subtitle stream into its own file.
For example:
ffmpeg -i '<extracted_file>.mkv' -vn -an -c:s copy '<subtitle_file>.sup'Copy or move the extracted file to the project's ./test/res/ directory and rename it to subs.sup.
From here, you may either make a copy of subs.sup and name it subs_short.sup or use a hex editor to create a shorter version of the file that is properly formatted. The main consideration to keep in mind is that the library currently expects proper formatting for the end of the file.
The end of any PGS stream or section will be denoted as such:
| Magic Number (2 bytes) | Decode timestamp (4 bytes) | Presentation timestamp (4 bytes) | Segment type flag (1 byte) | Segment Size (2 bytes) |
|---|---|---|---|---|
| "PG" | 32-bit value | 32-bit value | 0x80 (END flag) | 0x00 0x00 |
It is best to seek to between 2-3 megabytes into the file, find the closest END section as described above, and remove all data after the END section.
Save this new file as <project_dir>/test/res/subs_short.sup.
Pgs++ can be packed for various OSes to make system and project integration easier.
Currently, Pgs++ has support for building native RPM packages on any architecture provided it has the following packages along with the minimum requirements listed here:
- rpm-build
- rpmlint
- python
- coreutils
- diffutils
- patch
- rpmdevtools
To install all base requirements on Fedora, CentOS 8, and RedHat Enterprise Linux 8, use the following command:
dnf install gcc cmake rpm-build rpm-devel rpmlint python bash coreutils diffutils patch rpmdevtoolsPgs++ uses CMake to generate an RPM SPEC file based on the template located in <project_dir>/dist/redhat. To have CMake generate the file, simply create a fresh build directory or use one configured for a release build, enter it, and run CMake from there.
Example:
mkdir build-rpm && cd build-rpm
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=off -DEXPORT_HEADERS=on ..or
cd build-release
cmake ..At this point a new SPEC file will have been created at <project_dir>/dist/redhat/pgs++.spec. Take note of this location for the next step.
If you have not created RPM packages before, use the following command to generate the required directories in your HOME directory:
rpmdev-setuptreeFrom here, either copy the generated SPEC file from the previous step to $HOME/rpmbuild/SPECS/ or create a symlink in the same directory.
Open a terminal in $HOME/rpmbuild/SPECS/ and enter the following command to download the required sources to $HOME/rpmbuild/SOURCES/:
spectool -g -R pgs++.specNext, run the following command to build the code and generate the RPM packages:
rpmbuild -bb pgs++.specIf the command is successful, a freshly-generated set of Pgs++ packages will be waiting at $HOME/rpmbuild/RPMS/