diff --git a/docs/source/tutorials/basic_usage.md b/docs/source/tutorials/basic_usage.md new file mode 100644 index 0000000000..259df894e8 --- /dev/null +++ b/docs/source/tutorials/basic_usage.md @@ -0,0 +1,61 @@ +# Basic Usage + +## Getting help + +```shell +$ packager --help +``` + +## Media file analysis + +Shaka Packager can be used to inspect the content of a media file and dump basic +stream information. + +```shell +$ packager input=some_content.mp4 --dump_stream_info +``` + +The output looks like: + +```shell +File "some_content.mp4": +Found 2 stream(s). +Stream [0] type: Video + codec_string: avc1.4d001e + time_scale: 24000 + duration: 3002000 (125.1 seconds) + is_encrypted: false + codec: H264 + width: 720 + height: 360 + pixel_aspect_ratio: 8:9 + trick_play_factor: 0 + nalu_length_size: 4 + +Stream [1] type: Audio + codec_string: mp4a.40.2 + time_scale: 44100 + duration: 5517311 (125.1 seconds) + is_encrypted: false + codec: AAC + sample_bits: 16 + num_channels: 2 + sampling_frequency: 44100 + language: eng +``` + +## Basic transmuxing + +Shaka Packager can be used to extract streams, optionally transmuxes the streams +from one container format to another container format. + +Here is a simple command that extracts video and audio from the input file: + +```shell +$ packager in=some_content.mp4,stream=video,out=video.mp4 \ + in=some_content.mp4,stream=audio,out=audio.mp4 +``` + +Shaka Packager is also capable of more complex tasks, such as applying +encryption, packaging contents to DASH or HLS formats, etc. Refer +:doc:`tutorials`. diff --git a/docs/source/tutorials/dash.rst b/docs/source/tutorials/dash.rst new file mode 100644 index 0000000000..92f1e86a74 --- /dev/null +++ b/docs/source/tutorials/dash.rst @@ -0,0 +1,63 @@ +DASH +==== + +Dynamic Adaptive Streaming over HTTP (DASH) is an adaptive bitrate streaming +technique that enables high quality streaming of media content over HTTP. + +Shaka Packager supports DASH content packaging. This tutorial covers DASH +packaging of VOD content without encryption. For live content packaging, see +:doc:`live`; for content encryption, see :doc:`drm`. + +Synopsis +-------- + +:: + + $ packager {stream_descriptor} [stream_descriptor] ... \ + --mpd_output {manifest output path} \ + [Other DASH options] \ + [Other options, e.g. DRM options, HLS options] + +See `DASH options`_ for the available DASH related options. + +.. note:: + + DASH and HLS options can both be specified to output DASH and HLS manifests + at the same time. Note that it works only for MP4 outputs. + +Examples +-------- + +The examples below uses the H264 streams created in :doc:`encoding`. It can be +applied to VP9 in the same way. + +* on-demand:: + + $ packager \ + in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4 \ + in=h264_baseline_360p_600.mp4,stream=video,output=h264_360p.mp4 \ + in=h264_main_480p_1000.mp4,stream=video,output=h264_480p.mp4 \ + in=h264_main_720p_3000.mp4,stream=video,output=h264_720p.mp4 \ + in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p.mp4 \ + --mpd_output h264.mpd + +The above packaging command creates five single track fragmented mp4 streams +(4 video, 1 audio) and a manifest, which describes the streams. + +* static-live:: + + $ packager \ + 'in=h264_baseline_360p_600.mp4,stream=audio,init_segment=audio_init.mp4,segment_template=audio_$Number$.m4s' \ + 'in=h264_baseline_360p_600.mp4,stream=video,init_segment=h264_360p_init.mp4,segment_template=h264_360p_$Number$.m4s' \ + 'in=h264_main_480p_1000.mp4,stream=video,init_segment=h264_480p_init.mp4,segment_template=h264_480p_$Number$.m4s' \ + 'in=h264_main_720p_3000.mp4,stream=video,init_segment=h264_720p_init.mp4,segment_template=h264_720p_$Number$.m4s' \ + 'in=h264_main_1080p_6000.mp4,stream=video,init_segment=h264_1080p_init.mp4,segment_template=h264_1080p_$Number$.m4s' \ + --generate_static_mpd --mpd_output h264.mpd + +The above packaging command creates five groups of segments (each with an init +segment and a series of media segments) for the five streams and a manifest, +which describes the streams. + +.. include:: /options/dash_options.rst + +.. include:: /options/segment_template_formatting.rst diff --git a/docs/source/tutorials/drm.rst b/docs/source/tutorials/drm.rst new file mode 100644 index 0000000000..c3b2d971b4 --- /dev/null +++ b/docs/source/tutorials/drm.rst @@ -0,0 +1,9 @@ +DRM +=== + +.. toctree:: + :maxdepth: 2 + + /tutorials/raw_key.rst + /tutorials/widevine.rst + /tutorials/playready.rst diff --git a/docs/source/tutorials/encoding.rst b/docs/source/tutorials/encoding.rst new file mode 100644 index 0000000000..c25e5a5fbb --- /dev/null +++ b/docs/source/tutorials/encoding.rst @@ -0,0 +1,124 @@ +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 \ + -x264opts 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 \ + -x264opts 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 \ + -x264opts 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 main -level:v 4.2 \ + -x264opts scenecut=0:open_gop=0:min-keyint=72:keyint=72 \ + -minrate 6000k -maxrate 6000k -bufsize 6000k -b:v 6000k \ + -y h264_main_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 diff --git a/docs/source/tutorials/ffmpeg_piping.rst b/docs/source/tutorials/ffmpeg_piping.rst new file mode 100644 index 0000000000..2625f8d943 --- /dev/null +++ b/docs/source/tutorials/ffmpeg_piping.rst @@ -0,0 +1,56 @@ +ffmpeg piping +============= + +We can use *ffmpeg* to redirect / pipe input not supported by *packager* +to *packager*, for example, input from webcam devices. The example below uses +webcam input device. The concept depicted here can be applied to +other *ffmpeg* supported capture device. + +ffmpeg camera capture +--------------------- + +Refer to `ffmpeg Capture/Webcam `_ +on how to use *ffmpeg* to capture webmcam inputs. + +The examples below assumes Mac OS X 10.7 (Lion) or later. It is similar on +other platforms. Refer to the above link for details. + +Create pipe +----------- + +We use pipe to connect *ffmpeg* and *packager*:: + + $ mkfifo pipe1 + +Encoding / capture command +-------------------------- + +The below command captures from the default audio / video devices on the +machine:: + + $ ffmpeg -f avfoundation -i "default" -f mpegts pipe: > pipe1 + +The command starts only after packager starts. + +.. note:: + + After encoding starts, monitor encoding speed carefully. It should always be + 1x and above. If not, adjust the encoding parameters to recude it. + +Packaging command (DASH) +------------------------ + +:: + + $ packager \ + 'in=pipe1,stream=audio,init_segment=live_cam_audio.mp4,segment_template=live_cam_audio_$Number$.m4s' \ + 'in=pipe1,stream=video,init_segment=live_cam_video.mp4,segment_template=live_cam_video_$Number$.m4s' \ + --mpd_output live_cam.mpd \ + --io_block_size 65536 + +.. note:: + + Option -io_block_size 65536 tells packager to use an io_block_size of 65K + for threaded io file. This is necessary as reading from pipe blocks until + the specified number of bytes, which is specified in io_block_size for + threaded io file, thus the value of io_block_size cannot be too large. diff --git a/docs/source/tutorials/hls.rst b/docs/source/tutorials/hls.rst new file mode 100644 index 0000000000..4baba4672c --- /dev/null +++ b/docs/source/tutorials/hls.rst @@ -0,0 +1,87 @@ +HLS +=== + +HTTP Live Streaming (also known as HLS) is an HTTP-based media streaming +communications protocol implemented by Apple Inc. as part of its QuickTime, +Safari, OS X, and iOS software. It resembles MPEG-DASH in that it works by +breaking the overall stream into a sequence of small HTTP-based file downloads, +each download loading one short chunk of an overall potentially unbounded +transport stream. As the stream is played, the client may select from a number +of different alternate streams containing the same material encoded at a variety +of data rates, allowing the streaming session to adapt to the available data +rate. At the start of the streaming session, HLS downloads an extended M3U +playlist containing the metadata for the various sub-streams which are +available. + +Shaka Packager supports HLS content packaging. This tutorial covers HLS +packaging of VOD content without encryption. For live content packaging, see +:doc:`live`; for content encryption, see :doc:`drm`. + +Synopsis +-------- + +:: + + $ packager {stream_descriptor with HLS specific descriptors} \ + [stream_descriptor with HLS specific descriptors] ... \ + --hls_master_playlist_output {master playlist output path} \ + [Other HLS options] \ + [Other options, e.g. DRM options, DASH options] + +See `HLS specific stream descriptor fields`_ for the available HLS specific +stream descriptor fields. + +See `HLS options`_ for the available HLS related options. + +.. note:: + + DASH and HLS options can both be specified to output DASH and HLS manifests + at the same time. Note that it works only for MP4 outputs. + +Examples +--------- + +The examples below uses the H264 streams created in :doc:`encoding`. + +* TS output:: + + $ packager \ + 'in=h264_baseline_360p_600.mp4,stream=audio,output=audio_$Number$.ts,playlist_name=audio.m3u8,hls_group_id=audio,hls_name=ENGLISH' \ + 'in=h264_baseline_360p_600.mp4,stream=video,output=h264_360p_$Number$.ts,playlist_name=h264_360p.m3u8' \ + 'in=h264_main_480p_1000.mp4,stream=video,output=h264_480p_$Number$.ts,playlist_name=h264_480p.m3u8' \ + 'in=h264_main_720p_3000.mp4,stream=video,output=h264_720p_$Number$.ts,playlist_name=h264_720p.m3u8' \ + 'in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p_$Number$.ts,playlist_name=h264_1080p.m3u8' \ + --hls_master_playlist_output h264_master.m3u8 + +The above packaging command creates five single track TS streams +(4 video, 1 audio) and a manifest, which describes the streams. + +* MP4 output is also supported:: + + $ packager \ + 'in=h264_baseline_360p_600.mp4,stream=audio,init_segment=audio_init.mp4,segment_template=audio_$Number$.m4s,playlist_name=audio.m3u8,hls_group_id=audio,hls_name=ENGLISH' \ + 'in=h264_baseline_360p_600.mp4,stream=video,init_segment=h264_360p_init.mp4,segment_template=h264_360p_$Number$.m4s,playlist_name=h264_360p.m3u8' \ + 'in=h264_main_480p_1000.mp4,stream=video,init_segment=h264_480p_init.mp4,segment_template=h264_480p_$Number$.m4s,playlist_name=h264_480p.m3u8' \ + 'in=h264_main_720p_3000.mp4,stream=video,init_segment=h264_720p_init.mp4,segment_template=h264_720p_$Number$.m4s,playlist_name=h264_720p.m3u8' \ + 'in=h264_main_1080p_6000.mp4,stream=video,init_segment=h264_1080p_init.mp4,segment_template=h264_1080p_$Number$.m4s,playlist_name=h264_1080p.m3u8' \ + --hls_master_playlist_output h264_master.m3u8 + +* Single file MP4 output is also supported:: + + $ packager \ + in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4,playlist_name=audio.m3u8,hls_group_id=audio,hls_name=ENGLISH \ + in=h264_baseline_360p_600.mp4,stream=video,output=h264_360p.mp4,playlist_name=h264_360p.m3u8 \ + in=h264_main_480p_1000.mp4,stream=video,output=h264_480p.mp4,playlist_name=h264_480p.m3u8 \ + in=h264_main_720p_3000.mp4,stream=video,output=h264_720p.mp4,playlist_name=h264_720p.m3u8 \ + in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p.mp4,playlist_name=h264_1080p.m3u8 \ + --hls_master_playlist_output h264_master.m3u8 + +The above packaging command creates five groups of streams (each with an init +segment and a series of media segments) and a manifest, which describes the +streams. + +.. include:: /options/hls_stream_descriptors.rst + +.. include:: /options/hls_options.rst + +.. include:: /options/segment_template_formatting.rst diff --git a/docs/source/tutorials/live.rst b/docs/source/tutorials/live.rst new file mode 100644 index 0000000000..d38f013904 --- /dev/null +++ b/docs/source/tutorials/live.rst @@ -0,0 +1,46 @@ +Live +==== + +A typical live source is UDP multicast, which is the only live protocol +packager supports directly right now. + +.. include:: /options/udp_file_options.rst + +Pipe through FFmpeg +------------------- + +For other unsupported protocols, you can use FFmpeg to pipe the input. +See :doc:`ffmpeg_piping` for details. + +Examples +-------- + +The command is similar to the on-demand, see :doc:`dash` and :doc:`hls`. + +Here are some examples. + +* DASH:: + + $ packager \ + 'in=udp://225.1.1.8:8001?interface=172.29.46.122,stream=audio,init_segment=audio_init.mp4,segment_template=audio_$Number$.m4s' \ + 'in=udp://225.1.1.8:8001?interface=172.29.46.122,stream=video,init_segment=h264_360p_init.mp4,segment_template=h264_360p_$Number$.m4s' \ + 'in=udp://225.1.1.8:8002?interface=172.29.46.122,stream=video,init_segment=h264_480p_init.mp4,segment_template=h264_480p_$Number$.m4s' \ + 'in=udp://225.1.1.8:8003?interface=172.29.46.122,stream=video,init_segment=h264_720p_init.mp4,segment_template=h264_720p_$Number$.m4s' \ + 'in=udp://225.1.1.8:8004?interface=172.29.46.122,stream=video,init_segment=h264_1080p_init.mp4,segment_template=h264_1080p_$Number$.m4s' \ + --mpd_output h264.mpd + + +* HLS:: + + $ packager \ + 'in=udp://225.1.1.8:8001?interface=172.29.46.122,stream=audio,init_segment=audio_init.mp4,segment_template=audio_$Number$.m4s,playlist_name=audio.m3u8,hls_group_id=audio,hls_name=ENGLISH' \ + 'in=udp://225.1.1.8:8001?interface=172.29.46.122,stream=video,init_segment=h264_360p_init.mp4,segment_template=h264_360p_$Number$.m4s,playlist_name=h264_360p.m3u8' \ + 'in=udp://225.1.1.8:8002?interface=172.29.46.122,stream=video,init_segment=h264_480p_init.mp4,segment_template=h264_480p_$Number$.m4s,playlist_name=h264_480p.m3u8' \ + 'in=udp://225.1.1.8:8003?interface=172.29.46.122,stream=video,init_segment=h264_720p_init.mp4,segment_template=h264_720p_$Number$.m4s,playlist_name=h264_720p.m3u8' \ + 'in=udp://225.1.1.8:8004?interface=172.29.46.122,stream=video,init_segment=h264_1080p_init.mp4,segment_template=h264_1080p_$Number$.m4s,playlist_name=h264_1080p.m3u8' \ + --hls_master_playlist_output h264_master.m3u8 + +.. note:: + + Packager does not support removing old segments internally. The user is + resposible for setting up a cron job to do so. diff --git a/docs/source/tutorials/playready.rst b/docs/source/tutorials/playready.rst new file mode 100644 index 0000000000..59eaa6dfc9 --- /dev/null +++ b/docs/source/tutorials/playready.rst @@ -0,0 +1,4 @@ +Playready +========= + +To be completed. diff --git a/docs/source/tutorials/raw_key.rst b/docs/source/tutorials/raw_key.rst new file mode 100644 index 0000000000..a477d04d58 --- /dev/null +++ b/docs/source/tutorials/raw_key.rst @@ -0,0 +1,86 @@ +Raw key +======= + +*Packager* allows encrypting contents with raw key. + +Synopsis +-------- + +:: + + $ packager {stream_descriptor} [stream_descriptor] ... \ + --enable_fixed_key_encryption \ + --key_id --key \ + [--pssh ] \ + [Other options, e.g. DASH options, HLS options] + +Custom PSSH(s) can be provided in *--pssh*. If absent, +`v1 common PSSH box `_ is generated. + +Examples +-------- + +The examples below uses the H264 streams created in :doc:`encoding`. Here are examples with DASH. It can be applied to HLS in a similar way. + +Common PSSH:: + + $ packager \ + in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4 \ + in=h264_baseline_360p_600.mp4,stream=video,output=h264_360p.mp4 \ + in=h264_main_480p_1000.mp4,stream=video,output=h264_480p.mp4 \ + in=h264_main_720p_3000.mp4,stream=video,output=h264_720p.mp4 \ + in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p.mp4 \ + --enable_fixed_key_encryption \ + --key_id abba271e8bcf552bbd2e86a434a9a5d9 \ + --key 69eaa802a6763af979e8d1940fb88392 \ + --mpd_output h264.mpd + +Widevine PSSH:: + + $ packager \ + in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4 \ + in=h264_baseline_360p_600.mp4,stream=video,output=h264_360p.mp4 \ + in=h264_main_480p_1000.mp4,stream=video,output=h264_480p.mp4 \ + in=h264_main_720p_3000.mp4,stream=video,output=h264_720p.mp4 \ + in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p.mp4 \ + --enable_fixed_key_encryption \ + --key_id abba271e8bcf552bbd2e86a434a9a5d9 \ + --key 69eaa802a6763af979e8d1940fb88392 \ + --pssh 000000407073736800000000edef8ba979d64acea3c827dcd51d21ed000000201a0d7769646576696e655f74657374220f7465737420636f6e74656e74206964 \ + --mpd_output h264.mpd + +Refer to +`player setup `_ +on how to config the DRM in Shaka Player. + +Test vectors used in this tutorial +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Key ID + + abba271e8bcf552bbd2e86a434a9a5d9 + + Key ID must be 16 bytes or 32 digits in HEX. + +Key + + 69eaa802a6763af979e8d1940fb88392 + + Key must be 16 bytes or 32 digits in HEX. + +Widevine PSSH + + 000000407073736800000000edef8ba979d64acea3c827dcd51d21ed000000201a0d7769646576696e655f74657374220f7465737420636f6e74656e74206964 + + The PSSH is generated using + `pssh-box script `_:: + + $ pssh-box.py --widevine-system-id \ + --content-id 7465737420636f6e74656e74206964 --provider widevine_test + +.. include:: /options/raw_key_encryption_options.rst + +pssh-box (Utility to generate PSSH boxes) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +https://github.com/google/shaka-packager/tree/master/packager/tools/pssh diff --git a/docs/source/tutorials/tutorials.rst b/docs/source/tutorials/tutorials.rst new file mode 100644 index 0000000000..5ce31569ee --- /dev/null +++ b/docs/source/tutorials/tutorials.rst @@ -0,0 +1,11 @@ +Tutorials +==================== + +.. toctree:: + :maxdepth: 2 + + basic_usage.md + dash.rst + hls.md + live.md + drm.rst diff --git a/docs/source/tutorials/widevine.rst b/docs/source/tutorials/widevine.rst new file mode 100644 index 0000000000..e8f2861be1 --- /dev/null +++ b/docs/source/tutorials/widevine.rst @@ -0,0 +1,87 @@ +Widevine +======== + +There are two options to package a Widevine DRM encrypted content: + +1. If you know the encryption keys and have the associated Widevine PSSH at + hand, you can provide them in clear text to *packager* directly. Refer to + :doc:`/tutorials/raw_key` for details. + +2. Provide *key_server_url* and associated credentials to *packager*. + *Packager* will fetch encryption keys from Widevine key server. + +Synopsis +-------- + +AES signing:: + + $ packager {stream_descriptor} [stream_descriptor] ... \ + --enable_widevine_encryption \ + --key_server_url \ + --content_id \ + --signer --aes_signing_key \ + --aes_signing_iv \ + [Other options, e.g. DASH options, HLS options] + +RSA signing:: + + $ packager {stream_descriptor} [stream_descriptor] ... \ + --enable_widevine_encryption \ + --key_server_url \ + --content_id \ + --signer --rsa_signing_key_path \ + [Other options, e.g. DASH options, HLS options] + +Examples +-------- + +The examples below uses the H264 streams created in :doc:`encoding`. + +Here is an example with DASH. It can be applied to HLS in a similar way:: + + $ packager \ + in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4 \ + in=h264_baseline_360p_600.mp4,stream=video,output=h264_360p.mp4 \ + in=h264_main_480p_1000.mp4,stream=video,output=h264_480p.mp4 \ + in=h264_main_720p_3000.mp4,stream=video,output=h264_720p.mp4 \ + in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p.mp4 \ + --mpd_output h264.mpd \ + --enable_widevine_encryption \ + --key_server_url https://license.uat.widevine.com/cenc/getcontentkey/widevine_test \ + --content_id 7465737420636f6e74656e74206964 \ + --signer widevine_test \ + --aes_signing_key 1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9 \ + --aes_signing_iv d58ce954203b7c9a9a9d467f59839249 + +Refer to +`player setup `_ +on how to config the DRM in Shaka Player. + +Widevine test credential +------------------------ + +Here is the test crendential used in this tutorial. + +key_server_url + + https://license.uat.widevine.com/cenc/getcontentkey/widevine_test + +signer + + widevine_test + +aes_signing_key + + 1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9 + +aes_signing_iv + + d58ce954203b7c9a9a9d467f59839249 + +.. note:: + + The test credential is only meant for development. Please reach out to + `Widevine `_ if + you need something for production use. + +.. include:: /options/widevine_encryption_options.rst