diff --git a/packager/packager.gyp b/packager/packager.gyp index 038fe1cb7d..1ca81fa6bf 100644 --- a/packager/packager.gyp +++ b/packager/packager.gyp @@ -151,6 +151,20 @@ }], 'dependencies': ['packager'], }, + { + 'target_name': 'pssh_box_py', + 'type': 'none', + 'copies': [{ + 'destination': '<(PRODUCT_DIR)', + 'files': [ + 'tools/pssh/pssh-box.py', + ], + }], + 'dependencies': [ + 'media/base/media_base.gyp:widevine_pssh_data_proto', + 'third_party/protobuf/protobuf.gyp:py_proto', + ], + }, { 'target_name': 'status', 'type': '<(component)', diff --git a/packager/third_party/protobuf/protobuf.gyp b/packager/third_party/protobuf/protobuf.gyp index c6054140bc..f85158a28f 100644 --- a/packager/third_party/protobuf/protobuf.gyp +++ b/packager/third_party/protobuf/protobuf.gyp @@ -464,13 +464,6 @@ 'python/google/protobuf/symbol_database.py', 'python/google/protobuf/text_encoding.py', 'python/google/protobuf/text_format.py', - - # TODO(ncarter): protoc's python generator treats - # descriptor.proto specially, but only when the input path is - # exactly "google/protobuf/descriptor.proto". I'm not sure how - # to execute a rule from a different directory. For now, use a - # manually-generated copy of descriptor_pb2.py. - 'python/google/protobuf/descriptor_pb2.py', ], }, { @@ -491,39 +484,33 @@ ], }, ], - # # We can't generate a proper descriptor_pb2.py -- see earlier comment. - # 'rules': [ - # { - # 'rule_name': 'genproto', - # 'extension': 'proto', - # 'inputs': [ - # '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', - # ], - # 'variables': { - # # The protoc compiler requires a proto_path argument with the - # # directory containing the .proto file. - # 'rule_input_relpath': 'src/google/protobuf', - # }, - # 'outputs': [ - # '<(PRODUCT_DIR)/pyproto/google/protobuf/<(RULE_INPUT_ROOT)_pb2.py', - # ], - # 'action': [ - # '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', - # '-I./src', - # '-I.', - # '--python_out=<(PRODUCT_DIR)/pyproto/google/protobuf', - # 'google/protobuf/descriptor.proto', - # ], - # 'message': 'Generating Python code from <(RULE_INPUT_PATH)', - # }, - # ], - # 'dependencies': [ - # 'protoc#host', - # ], - # 'sources': [ - # 'src/google/protobuf/descriptor.proto', - # ], - }, + # Generate descriptor_pb2.py. + 'rules': [ + { + 'rule_name': 'genproto', + 'extension': 'proto', + 'inputs': [ + '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', + ], + 'outputs': [ + '<(PRODUCT_DIR)/pyproto/google/protobuf/<(RULE_INPUT_ROOT)_pb2.py', + ], + 'action': [ + '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', + '-Isrc', + '--python_out=<(PRODUCT_DIR)/pyproto', + 'src/google/protobuf/descriptor.proto', + ], + 'message': 'Generating Python code from <(RULE_INPUT_PATH)', + }, + ], + 'dependencies': [ + 'protoc#host', + ], + 'sources': [ + 'src/google/protobuf/descriptor.proto', + ], + }, ], }, { # use_system_protobuf==1 'targets': [ diff --git a/packager/tools/pssh/README.md b/packager/tools/pssh/README.md index c2df33142d..9ee64a3c76 100644 --- a/packager/tools/pssh/README.md +++ b/packager/tools/pssh/README.md @@ -1,29 +1,86 @@ -pssh-box - Utility to generate and print PSSH boxes +pssh-box - Utility to parse and generate PSSH boxes =================================================== -## Installation +## Prerequisite -To use this script you must first install the Python ProtoBuf library. If you -have it installed already, you can just use the script directly. These -instructions describe how to compile the ProtoBuf library so this script can -run. This will not install ProtoBuf globally; it will only compile it. +- Python 2.6 or newer. -1) You need Python 2.6 or newer. +## Build the utility using Shaka Packager build setup -2) Install `setuptools`. This is installed by default when you -install `pip`. If you don't have it, when you run `setup.py` it will install -it locally. If you want to install manually, see: +The utility needs to be built before being used, i.e. do not use the script in +`packager/tools/pssh/pssh_box.py` directly. -``` - https://packaging.python.org/en/latest/installing.html#setup-for-installing-packages -``` +If you have not set up the build environment for Shaka Packager, see +https://github.com/google/shaka-packager/blob/master/docs/source/build_instructions.md. -3) Build the packager, which will build `protoc` in `out/{Debug,Release}`. - -4) Run `setup.py`. You will need to have `protoc` in PATH, which was build in -the previous step: +With the build environment set up, use `ninja` to build the utility: ```bash -cd packager/third_party/protobuf/python -PATH=../../../../out/{Debug,Release}/:"$PATH" python setup.py build +$ ninja -C out/Release pssh_box_py +``` + +Then you can use the built utility in `out/Release/pssh_box.py`. You can add +`out/Release` to your `PATH` so you can run it from anywhere. + +## Usage + +All examples below assume that that `pssh-box.py` is in the `PATH` variable of +the executing shell. + +### PSSH box generation + +The utility can be used to generate one or more PSSH boxes. + +An example to generate a Widevine PSSH with content-id 1234: + +```bash +$ pssh-box.py --widevine-system-id --content-id 1234 +``` + +It can be also be used to generate PSSH box from PSSH data (base64), e.g. + +```bash +$ pssh-box.py --widevine-system-id --pssh-data AAAABCICEjQ= +``` + +The output can be in base64 form (`--base64`), in hex form (`--hex`) or in human +readable form (`--human`). Human readable form is the default. + +An example to generate a Widevine PSSH with content-id 1234 in hex: + +```bash +$ pssh-box.py --widevine-system-id --content-id 1234 --hex +``` + +Multiple boxes can be generated by separating boxes with `--`. + +An example to generate concatenated PSSHs with a Widevine PSSH with content-id +1234 and a common PSSH with key-id 31323334353637383930313233343536 (hex form). + +```bash +$ pssh-box.py \ + --widevine-system-id --content-id 1234 -- \ + --common-system-id --key-id 31323334353637383930313233343536 +``` + +### PSSH box parsing + +The utility can be used to parse a single PSSH box or multiple concatenated PSSH +boxes. The input can be in hex or in base64. + +```bash +$ pssh-box.py --from-hex \ + 000000247073736800000000EDEF8BA979D64ACEA3C827DCD51D21ED0000000422021234 +``` + +```bash +$ pssh-box.py --from-base64 AAAAJHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAAQiAhI0 +``` + +### More options + +Run the utility with no arguments to see the full list of options. + +```bash +$ pssh-box.py ``` diff --git a/packager/tools/pssh/pssh-box.py b/packager/tools/pssh/pssh-box.py index 0e20568810..70c67d6730 100755 --- a/packager/tools/pssh/pssh-box.py +++ b/packager/tools/pssh/pssh-box.py @@ -14,24 +14,17 @@ import os import struct import sys -# Append the local protobuf location. Use a path relative to the tools/pssh -# folder where this file should be found. This allows the file to be executed -# from any directory. -_pssh_dir = os.path.dirname(os.path.realpath(__file__)) -sys.path.insert(0, os.path.join(_pssh_dir, '../../third_party/protobuf/python')) -# Import the widevine protobuf. Use either Release or Debug. -_proto_path_format = os.path.join( - _pssh_dir, '../../../out/%s/pyproto/packager/media/base') -if os.path.isdir(_proto_path_format % 'Release'): - sys.path.insert(0, _proto_path_format % 'Release') -else: - sys.path.insert(0, _proto_path_format % 'Debug') -try: - import widevine_pssh_data_pb2 # pylint: disable=g-import-not-at-top -except ImportError: - print >> sys.stderr, 'Cannot find proto file, make sure to build first' - raise +_script_dir = os.path.dirname(os.path.realpath(__file__)) +_proto_path = os.path.join(_script_dir, 'pyproto') +_widevine_proto_path = os.path.join(_proto_path, 'packager/media/base') +assert os.path.exists(_proto_path), ( + 'Please run from output directory, e.g. out/Debug/pssh-box.py') + +sys.path.insert(0, _proto_path) +sys.path.insert(0, _widevine_proto_path) + +import widevine_pssh_data_pb2 # pylint: disable=g-import-not-at-top COMMON_SYSTEM_ID = base64.b16decode('1077EFECC0B24D02ACE33C1E52E2FB4B') WIDEVINE_SYSTEM_ID = base64.b16decode('EDEF8BA979D64ACEA3C827DCD51D21ED')