Choosing the right media tools for web workflows
Preparing media for the web usually means changing file characteristics like bitrate or resolution, and knowing which tool handles which task can be intimidating. Two command-line utilities cover most needs: Shaka Packager and FFmpeg. They complement each other well—neither alone can perform every operation required to get media ready for web playback.
Shaka Packager functions as both a library and a command-line tool. It handles packaging for the two dominant streaming protocols, DASH and HLS, and supports common encryption and Widevine DRM for live streams and video-on-demand. FFmpeg, meanwhile, excels at recording, converting, and streaming. Alternatives exist—GUI apps like Miro, HandBrake, and VLC, plus cloud services such as Zencoder, Amazon Elastic Encoder, and Google Transcoder API—but these two remain the most common and powerful choices for scripted workflows.
Using Shaka Packager's command pattern
A typical Shaka Packager invocation follows this structure:
packager stream_descriptor [stream_descriptor-2 [stream_descriptor-n]] [flags]
This simplified pattern differs from what packager -help returns, but it's easier to reason about and matches the official documentation. Note the multiple stream_descriptor entries: you can manipulate audio and video streams independently in a single command.
Consider a basic use case that inspects file properties:
packager stream_descriptor [stream_descriptor-n] [flags]
packager input=glocken.mp4 --dump_stream_info
That yields output like this:
File "glocken.mp4":
Found 2 stream(s).
Stream [0] type: Video
codec_string: avc1.640028
time_scale: 30000
duration: 300300 (10.0 seconds)
is_encrypted: false
codec: H264
width: 1920
height: 1080
pixel_aspect_ratio: 1:1
trick_play_factor: 0
nalu_length_size: 4
Stream [1] type: Audio
codec_string: mp4a.40.2
time_scale: 48000
duration: 481280 (10.0 seconds)
is_encrypted: false
codec: AAC
sample_bits: 16
num_channels: 2
sampling_frequency: 48000
language: eng
seek_preroll_ns: 20833
Watch for the characteristics discussed in Media file basics. Full HD dimensions show up correctly here, and the codecs—AAC audio and H264 video—are the preferred pair for their containers. Also note the numeric stream identifiers, which become important when you need to target audio or video separately.
Bitrate is conspicuously absent from this output. When that value is required, FFmpeg is the better instrument.
FFmpeg's option positioning matters
The core FFmpeg command takes this shape:
ffmpeg [GeneralOptions] [InputFileOptions] -i input [OutputFileOptions] output
Like Shaka Packager, FFmpeg handles multiple streams. Its options carry context-sensitive meanings: placement within the command changes how they affect the output. Keep that in mind when reviewing FFmpeg answers on Stack Overflow.
Here's the parallel example that reports file details:
ffmpeg [GeneralOptions] [InputFileOptions] -i input [OutputFileOptions] output
ffmpeg -i glocken.mp4
Beyond the requested information, this command prints an error message, shown below. It's technically incorrect usage, but deliberate—we use it specifically because it surfaces the data we want.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'glocken.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.17.100
Duration: 00:01:47.53, start: 0.000000, bitrate: 10715 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc), 1920x1080, 10579 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
At least one output file must be specified
Standing up both tools with Docker
Installing both utilities manually is possible, but Docker offers a faster path. Set up a directory structure that keeps large media files out of the Docker build context, since oversized files would slow down image rebuilds later.
- Create a project directory, e.g.,
media-tools. - Inside it, create
docker/andmedia/. Themediadirectory holds the files you'll operate on; theDockerfilegoes indocker/. - Write the Dockerfile at
media-tools/docker/Dockerfile:
FROM google/shaka-packager:release-v2.4.3 as packager
FROM jrottenberg/ffmpeg:4.3.2-alpine38
COPY --from=packager /usr/bin /usr/bin
ENTRYPOINT ["sh"]
- Build the image:
docker build -t media-tools ./docker
- Launch an interactive shell; the command differs per OS:
Linux:
docker run -w /media -v ${PWD}/media:/media -it --rm media-tools /media #
Windows:
docker run -w /media -v %cd%/media:/media -it --rm media-tools /media #
Inside the running container, verify the installation with ffmpeg -version and packager --version:
/media # ffmpeg -version
ffmpeg version 4.3.2 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 6.4.0 (Alpine 6.4.0)
configuration: --disable-debug --disable-doc --disable-ffplay --enable-shared --enable-avresample --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-gpl --enable-libass --enable-fontconfig --enable-libfreetype --enable-libvidstab --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libxcb --enable-libx265 --enable-libxvid --enable-libx264 --enable-nonfree --enable-openssl --enable-libfdk_aac --enable-postproc --enable-small --enable-version3 --enable-libbluray --enable-libzmq --extra-libs=-ldl --prefix=/opt/ffmpeg --enable-libopenjpeg --enable-libkvazaar --enable-libaom --extra-libs=-lpthread --enable-libsrt --enable-libaribb24 --extra-cflags=-I/opt/ffmpeg/include --extra-ldflags=-L/opt/ffmpeg/lib
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
/media # packager --version
packager version v2.4.3-dd9870075f-release
These two tools give you a solid foundation for web media work. From here, the next step is understanding Media streaming basics.



