Media Encoding¶
Shaka Packager does not do transcoding internally. The contents need to be pre-encoded before passing to Shaka Packager.
General guidelines of how contents should be encoded¶
Encode multiple bitrates or resolutions of the same content. Shaka Packager can then package the content into DASH / HLS formats, allowing different bitrates of the content to be served for different network conditions, achieving adaptive bitrate streaming.
Not a must, but the multibirate content is recommended to have aligned GOPs across the different bitrate streams. This makes bitrate switching easier and smoother.
We recommend setting GOP size to 5s or less. The streams are usually switchable only at GOP boundaries. A smaller GOP size results in faster switching when network condition changes.
In the same stream, the bitrate should be more or less the same in the inter-GOP level.
Sample commands to generate multi-bitrate content¶
Let us say we have a 1080p original content original.mp4 containing an audio track in AAC and a video track in H264. The frame rate is 24. We want to encode the contents into four resolutions: 360p, 480p, 720p and 1080p with GOP size 72, i.e. 3 seconds.
We use ffmpeg here, which is a common tool used for transcoding.
H264 encoding¶
360p:
$ ffmpeg -i original.mp4 -c:a copy \ -vf "scale=-2:360" \ -c:v libx264 -profile:v baseline -level:v 3.0 \ -x264-params scenecut=0:open_gop=0:min-keyint=72:keyint=72 \ -minrate 600k -maxrate 600k -bufsize 600k -b:v 600k \ -y h264_baseline_360p_600.mp4
480p:
$ ffmpeg -i original.mp4 -c:a copy \ -vf "scale=-2:480" \ -c:v libx264 -profile:v main -level:v 3.1 \ -x264-params scenecut=0:open_gop=0:min-keyint=72:keyint=72 \ -minrate 1000k -maxrate 1000k -bufsize 1000k -b:v 1000k \ -y h264_main_480p_1000.mp4
720p:
$ ffmpeg -i original.mp4 -c:a copy \ -vf "scale=-2:720" \ -c:v libx264 -profile:v main -level:v 4.0 \ -x264-params scenecut=0:open_gop=0:min-keyint=72:keyint=72 \ -minrate 3000k -maxrate 3000k -bufsize 3000k -b:v 3000k \ -y h264_main_720p_3000.mp4
1080p:
$ ffmpeg -i original.mp4 -c:a copy \ -vf "scale=-2:1080" \ -c:v libx264 -profile:v high -level:v 4.2 \ -x264-params scenecut=0:open_gop=0:min-keyint=72:keyint=72 \ -minrate 6000k -maxrate 6000k -bufsize 6000k -b:v 6000k \ -y h264_high_1080p_6000.mp4
VP9 encoding¶
The audio is encoded into opus.
360p:
$ ffmpeg -i original.mp4 \ -strict -2 -c:a opus \ -vf "scale=-2:360" \ -c:v libvpx-vp9 -profile:v 0 \ -keyint_min 72 -g 72 \ -tile-columns 4 -frame-parallel 1 -speed 1 \ -auto-alt-ref 1 -lag-in-frames 25 \ -b:v 300k \ -y vp9_360p_300.webm
480p:
$ ffmpeg -i original.mp4 \ -strict -2 -c:a opus \ -vf "scale=-2:480" \ -c:v libvpx-vp9 -profile:v 0 \ -keyint_min 72 -g 72 \ -tile-columns 4 -frame-parallel 1 -speed 1 \ -auto-alt-ref 1 -lag-in-frames 25 \ -b:v 500k \ -y vp9_480p_500.webm
720p:
$ ffmpeg -i original.mp4 \ -strict -2 -c:a opus \ -vf "scale=-2:720" \ -c:v libvpx-vp9 -profile:v 0 \ -keyint_min 72 -g 72 \ -tile-columns 4 -frame-parallel 1 -speed 1 \ -auto-alt-ref 1 -lag-in-frames 25 \ -b:v 1500k \ -y vp9_720p_1500.webm
1080p:
$ ffmpeg -i original.mp4 \ -strict -2 -c:a opus \ -vf "scale=-2:1080" \ -c:v libvpx-vp9 -profile:v 0 \ -keyint_min 72 -g 72 \ -tile-columns 4 -frame-parallel 1 -speed 1 \ -auto-alt-ref 1 -lag-in-frames 25 \ -b:v 3000k \ -y vp9_1080p_3000.webm