Converting media files — and adjusting individual stream characteristics within them — is handled by two command-line tools: Shaka Packager and FFmpeg. The two are not interchangeable feature-for-feature. Where a procedure has no equivalent in one of them, that's noted below.
Most of the commands shown here would normally be combined into a single invocation — setting a bitrate at the same time as converting a file, for instance. They're written separately here purely for clarity.
Inspecting a file
Both tools can report the characteristics of the streams inside a media file, though their output for the same input differs.
With Shaka Packager:
packager input=glocken.mp4 --dump_stream_info
This produces output like:
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
With FFmpeg:
ffmpeg -i glocken.mp4
This produces output like:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'glocken.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.83.100
Duration: 00:00:10.03, start: 0.000000, bitrate: 8063 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc), 1920x1080, 7939 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, 127 kb/s (default)
Metadata:
handler_name : SoundHandler
At least one output file must be specified
Splitting and rejoining streams
Shaka Packager requires demuxing before it will convert files, and demuxing is likewise required when working with media frameworks.
Demuxing
MP4
packager input=myvideo.mp4,stream=video,output=myvideo_video.mp4
packager input=myvideo.mp4,stream=audio,output=myvideo_audio.m4a
Or:
packager \
input=myvideo.mp4,stream=video,output=myvideo_video.mp4 \
input=myvideo.mp4,stream=audio,output=myvideo_audio.m4a
WebM
packager \
input=myvideo.webm,stream=video,output=myvideo_video.webm \
input=myvideo.webm,stream=audio,output=myvideo_audio.webm
The same separation in FFmpeg, for MP4:
ffmpeg -i myvideo.mp4 -vcodec copy -an myvideo_video.mp4
ffmpeg -i myvideo.mp4 -acodec copy -vn myvideo_audio.m4a
and for WebM:
ffmpeg -i myvideo.webm -vcodec copy -an myvideo_video.webm
ffmpeg -i myvideo.webm -acodec copy -vn myvideo_audio.webm
Remuxing
Putting audio and video back into a single container is occasionally necessary, particularly when a media framework isn't in use. FFmpeg handles this well; Shaka Packager does not currently support it.
ffmpeg -i myvideo_video.webm -i myvideo_audio.webm -c copy myvideo.webm
Altering stream characteristics
Bitrate
FFmpeg can set the bitrate during conversion to .mp4 or .webm.
ffmpeg -i myvideo.mov -b:v 350K myvideo.mp4
ffmpeg -i myvideo.mov -vf setsar=1:1 -b:v 350K myvideo.webm
Resolution
ffmpeg -i myvideo.webm -s 1920x1080 myvideo_1920x1080.webm
Changing the container format
Because Shaka Packager can't process .mov files, it can't convert from that format; FFmpeg can.
.mov to .mp4
ffmpeg -i myvideo.mov myvideo.mp4
.mov to .webm
ffmpeg -i myvideo.mov myvideo.webm
Keyframes for A/V sync
Inserting keyframes keeps audio and video in sync during playback.
ffmpeg -i myvideo.mp4 -keyint_min 150 -g 150 -f webm -vf setsar=1:1 out.webm
MP4/H.264
ffmpeg -i myvideo.mp4 -c:v libx264 -c:a copy myvideo.mp4
Audio for an MP4
ffmpeg -i myvideo.mp4 -c:v copy -c:a aac myvideo.mp4
WebM/VP9
ffmpeg -i myvideo.webm -v:c libvpx-vp9 -v:a copy myvideo.webm
Audio for a WebM
ffmpeg -i myvideo.webm -v:c copy -v:a libvorbis myvideo.webm
ffmpeg -i myvideo.webm -v:c copy -v:a libopus myvideo.webm
Streaming output
Two streaming protocols are covered here. Dynamic Adaptive Streaming over HTTP (DASH) is an adaptive bitrate, web-standards-based technique for video-on-demand. HTTP Live Streaming (HLS) is Apple's standard for live streaming and video-on-demand on the web.
DASH
The following generates a Media Presentation Description (MPD) output file from the audio and video streams.
packager \
input=myvideo.mp4,stream=audio,output=myvideo_audio.mp4 \
input=myvideo.mp4,stream=video,output=myvideo_video.mp4 \
--mpd_output myvideo_vod.mpd
HLS
These examples produce an M3U8 output file — a UTF-8 encoded multimedia playlist — from the audio and video streams.
ffmpeg -i myvideo.mp4 -c:a copy -b:v 8M -c:v copy -f hls \
-hls_time 10 -hls_list_size 0 myvideo.m3u8
Or:
packager \
'input=myvideo.mp4,stream=video,segment_template=output$Number$.ts,playlist_name=video_playlist.m3u8' \
'input=myvideo.mp4,stream=audio,segment_template=output_audio$Number$.ts,playlist_name=audio_playlist.m3u8,hls_group_id=audio,hls_name=ENGLISH' \
--hls_master_playlist_output="master_playlist.m3u8"



