Shaka Packager: DASH and HLS Packaging With CENC Encryption
A media packaging and development framework for VOD and Live DASH and HLS applications, supporting Common Encryption for Widevine and other DRM Systems.
At a glance
- What is it?
- Shaka Packager is a C++ tool and SDK that turns mezzanine media into DASH or HLS streams, with or without Common Encryption. It is the right tool when your problem is manifest structure and DRM signalling, not transcoding.
- Who is it for?
- Adopt Shaka Packager if you already have encoded renditions and need DASH or HLS manifests plus CENC or SAMPLE-AES encryption, and you are comfortable driving a command line or linking the SDK. Do not adopt it as a transcoder: the README's codec table describes input and output containers, not encoding.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 39 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Shaka Packager actually solves, and for whom
Streaming a video file is not the same as serving one. A player needs a manifest that lists representations, segment boundaries, codec strings and, if the content is protected, the information needed to request a licence. Shaka Packager exists to produce that structure. The README describes it as "a tool and a media packaging SDK for DASH and HLS packaging and encryption" that "can prepare and package media content for online streaming."
That sentence defines the audience narrowly. You are expected to arrive with encoded media: H264, H265, VP8, VP9, AV1, AAC, AC3, EAC3, Opus, FLAC and others appear in the README's codec table with an I for input. The tool repackages and, optionally, encrypts. It does not decide bitrates for you, and nothing in the README suggests it encodes from a camera original.
The second audience is developers embedding packaging in a larger pipeline. The repository ships an include/ directory and a link-test/ directory, which is what an SDK distribution looks like: headers plus a test that links against the library. If you are building a transcoding farm or a VOD ingest service, the command line binary is probably enough. If you are building a product where packaging is a step inside your own process, the SDK path is the reason to choose this over a shell script wrapper.
Live is explicitly in scope alongside VOD. That matters because live packaging has different failure characteristics: a segmenter that buffers a whole file is useless when the source is a growing stream. The README states support for both without elaborating on the live pipeline, so treat live as documented but not detailed here.
The mechanism: demux, repackage, encrypt, write manifests
The repository layout tells you most of the architecture. The packager/ directory holds the source for the packager binary, the mpd_generator binary and the pssh-box.py script. The include/ directory holds the public headers. The Dockerfile builds exactly those artifacts and copies three of them into the runtime image: packager, mpd_generator and pssh-box.py.
The presence of mpd_generator as a separate binary is the interesting detail. It implies a two-stage workflow is possible: one stage produces media segments, a second stage generates or regenerates the MPD. That is useful when segment files are produced by something else, or when you need to rebuild a manifest without re-running the whole packaging job.
The pssh-box.py script, together with the pssh-box-protos directory the Dockerfile copies beside it, is about Protection System Specific Header boxes. Those are the boxes that carry DRM system identifiers and data inside an ISO-BMFF file. A Python script with protobuf definitions for PSSH generation means you can construct or inspect PSSH data outside the main packaging run, which is what you want when debugging why a particular player refuses to request a licence.
Encryption coverage in the README is split across two axes. Key systems are Widevine, PlayReady, FairPlay and Marlin, with the last three marked by a footnote reading "Limited support." Encryption standards are CENC and SAMPLE-AES. That footnote is the most important qualifier on the page: the README does not define what limited means for each system, so if your requirement is PlayReady or FairPlay, the README alone will not tell you whether your case is covered.
Containers are ISO-BMFF, WebM, MPEG2-TS, WVM and packed audio. Codec support is not uniform across them. VP8 and VP9 appear as both input and output for ISO-BMFF and WebM, but not for MPEG2-TS. Opus in ISO-BMFF carries its own footnote calling the support experimental. Those asymmetries are the real specification of what you can build.
Installing Shaka Packager on Linux, macOS or Windows
The README lists three routes: Docker, prebuilt binaries from the release page, and building from source. Docker instructions live in a separate document at docs/source/docker_instructions.md, and build instructions at docs/source/build_instructions.md. The README does not itself contain the platform-specific install commands, so the honest statement is that the project points you to those two files.
The repository's own Dockerfile shows what a container build does. It starts from alpine:3.19, installs build-base, cmake, git, ninja and python3, configures with CMake using the Ninja generator and CMAKE_BUILD_TYPE=Debug, then builds in parallel:
RUN cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -G Ninja
RUN cmake --build build/ --config Debug --parallelThe final image is a second alpine:3.19 stage that installs only libstdc++ and python3, and copies packager, mpd_generator and pssh-box.py into /usr/bin/. If you build your own image from this Dockerfile, note that it compiles a Debug build. That is a development image, not a tuned production one, and the file makes no claim otherwise.
For a first real use, the README's tutorial index is the place to start: it links to tutorials under docs on the project site. What the README does document concretely is the codec matrix, so the first thing to check before running anything is whether your input codec and container combination appears with an I. AVC in ISO-BMFF and MPEG2-TS qualifies. HEVC in WebM does not.
One practical warning about naming. The binary is called packager, and the Dockerfile places it at /usr/bin/packager inside the image. If you build locally, the path is build/packager/packager relative to the repository root, as the COPY line in the Dockerfile shows. A shell that cannot find packager is a PATH problem, not a missing build.
Where Shaka Packager is the wrong tool
The clearest boundary is transcoding. Nothing in the README describes encoding from an uncompressed or high-bitrate source into delivery renditions. The codec table marks codecs as input or output for containers, which is a statement about demuxing and muxing, not about rate control, scene analysis or perceptual quality. If your pipeline starts with a ProRes master, Shaka Packager is not the first stage.
The second boundary is DRM systems outside the well-supported set. Widevine is listed without a footnote. PlayReady, FairPlay and Marlin each carry the "Limited support" marker. The README does not enumerate what is missing for those systems, so a team that needs FairPlay for an Apple ecosystem cannot conclude from this page that the requirement is met. That is a documentation gap, and it is the kind of gap that costs a sprint to discover late.
The third boundary is subtitles. WebVTT input and output are both marked Y, and WebVTT in MP4 is output-only with a link to an open issue. TTML input is restricted: it is supported only as pass-through with TTML output, and only for DASH. DVB-SUB and Teletext are input-only, and Teletext points at another open issue. If your subtitles arrive as TTML and you need HLS output, the README's own footnote says that combination is not what this does.
Finally, the README does not document rollback, version pinning policy or migration between major versions. For a tool that writes files consumed by production players, that silence is worth weighing. The CHANGELOG.md file at the repository root is where release history lives, and it is the file to read before upgrading.
Shaka Packager compared with FFmpeg for packaging work
The common alternative for this job is FFmpeg, which also writes DASH and HLS output. The difference in approach is one of scope. FFmpeg is a transcoder that also packages; Shaka Packager is a packager that also handles encryption and manifest generation. If you need to decode, filter and re-encode, FFmpeg is the tool and Shaka Packager is not in the conversation. If you already have encoded renditions and your problem is manifest correctness and DRM signalling, the two overlap only partially.
On encryption, the README positions Shaka Packager around CENC and SAMPLE-AES with Widevine, PlayReady, FairPlay and Marlin, plus the pssh-box.py utility for PSSH handling. That combination, an SDK plus a PSSH tool, is aimed at teams integrating with a licence server rather than at one-off command line jobs.
On formats, the README's matrix is explicit about which codec and container pairs are supported in each direction. That explicitness is the useful part. A tool that lists I and O per cell tells you where it will refuse before you spend an afternoon on it. If your pipeline is WebM with VP9, both directions are listed. If it is MPEG2-TS with VP8, the README shows no support at all.
A second alternative worth naming is the player side of the same project family. Shaka Player is listed in the README as a DASH and HLS player on the web, alongside dash.js, hls.js and ExoPlayer. Those are not packaging alternatives; they are what you test your output against. If you are choosing a packager, the fact that a reference player from the same organisation exists is a practical debugging advantage, because manifest quirks have a known consumer to check against.
Maintenance, releases and the licence question
The repository is not archived, and the last push was on 2026-08-21. Recent releases are v3.9.1 on 2026-07-15, v3.9.2 on 2026-07-17 and v3.9.3 on 2026-07-27. The presence of .release-please-config.json and .release-please-manifest.json at the repository root indicates release automation is configured, which is consistent with three patch releases inside a fortnight.
On upgrade cost, one concrete statement is supported: CHANGELOG.md exists at the root and is the record of what changed between versions. The README does not describe a compatibility policy for the command line interface or for the SDK headers in include/. That means an upgrade that touches either is something you verify against the changelog rather than against a documented guarantee.
The licence field is reported as NOASSERTION, which means the automated licence detection did not classify it. A LICENSE file exists at the repository root, and so does a chromium-LICENSE file, which suggests the codebase carries more than one licence text. Do not treat the NOASSERTION value as either permission or restriction. Read the LICENSE and chromium-LICENSE files directly, and if you are redistributing the binary or linking the SDK into a product, that is a question for your own legal review, not something this article can settle.
One more cost worth naming: the Dockerfile's builder stage uses CMAKE_BUILD_TYPE=Debug. Anyone shipping the project's own container image as-is is shipping a debug build. Building with a different CMAKE_BUILD_TYPE is a change you make yourself, and the README does not walk through it.
Editorial conclusion
Adopt Shaka Packager if you already have encoded renditions and need DASH or HLS manifests plus CENC or SAMPLE-AES encryption, and you are comfortable driving a command line or linking the SDK. Do not adopt it as a transcoder: the README's codec table describes input and output containers, not encoding. Before committing, verify that your specific codec and subtitle combination appears as both I and O in the README tables, and confirm your DRM vendor's requirements against the encryption flags in the documentation rather than assuming Widevine, PlayReady and FairPlay behave identically.
Frequently asked questions
What is Shaka Packager used for?
It prepares and packages media content for online streaming as DASH or HLS, and can encrypt that content using CENC or SAMPLE-AES with Widevine and other DRM systems. It handles both video-on-demand and live.
How do I install Shaka Packager?
The README lists three routes: use Docker, following the instructions in docs/source/docker_instructions.md, download prebuilt binaries from the release page, or build from source using the build instructions document. The README does not include the platform-specific commands itself.
How do I install Shaka Packager on Windows?
Windows is listed among the supported platforms, and the README offers prebuilt binaries from the release page as one of the ways to get the tool. It does not give a Windows-specific install procedure, so the release assets and the build instructions document are the two places to look.
How do I use Shaka Packager?
You supply encoded media and the tool repackages it into DASH or HLS, optionally encrypting it and generating the manifest. The README points to a tutorials index on the project documentation site for worked examples, and the codec table tells you which input and output combinations are supported.
What is the difference between Shaka Packager and FFmpeg?
FFmpeg is a transcoder that also packages, while Shaka Packager is described in the README as a packaging and encryption tool and SDK, so it expects already-encoded input. Its emphasis is on DASH and HLS manifests plus CENC and SAMPLE-AES encryption with Widevine, PlayReady, FairPlay and Marlin.
What can I use as an alternative to Shaka Packager?
FFmpeg also produces DASH and HLS output, but it approaches the job as a transcoder rather than a dedicated packager. The choice depends on whether you arrive with encoded renditions and need manifest and DRM handling, or whether you still need to encode.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/shaka-project-shaka-packager)