Support Fairplay in --additional_protection_systems

Issue: #245.

Change-Id: I15187c1d3463534bf5e11ff97032311bb1d0c3bf
This commit is contained in:
KongQun Yang 2018-08-07 16:01:43 -07:00
parent 2a80c6773a
commit db076d6892
20 changed files with 137 additions and 48 deletions

View File

@ -80,7 +80,7 @@
- Support for attributes RESOLUTION, CHANNELS, AUTOSELECT and DEFAULT. - Support for attributes RESOLUTION, CHANNELS, AUTOSELECT and DEFAULT.
- Live and Event playlists. - Live and Event playlists.
- fMP4 in HLS (including byte range support). - fMP4 in HLS (including byte range support).
- DRM: Widevine and Fairplay. - DRM: Widevine and FairPlay.
- I-Frame playlist. - I-Frame playlist.
- Enhanced subtitle support. - Enhanced subtitle support.
- Segmented WebVTT in fMP4. - Segmented WebVTT in fMP4.

View File

@ -27,7 +27,7 @@ Shaka Packager supports:
- Key systems: - Key systems:
- [Widevine](http://www.widevine.com/) - [Widevine](http://www.widevine.com/)
- [PlayReady](https://www.microsoft.com/playready/ - [PlayReady](https://www.microsoft.com/playready/
- [Fairplay](https://developer.apple.com/streaming/fps/ - [FairPlay](https://developer.apple.com/streaming/fps/
- Encryption standards: - Encryption standards:
- [CENC](https://en.wikipedia.org/wiki/MPEG_Common_Encryption) - [CENC](https://en.wikipedia.org/wiki/MPEG_Common_Encryption)
- [SAMPLE-AES](https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption/Intro/Intro.html) - [SAMPLE-AES](https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption/Intro/Intro.html)

View File

@ -18,4 +18,4 @@ General encryption options
Generate additional protection systems in addition to the native protection Generate additional protection systems in addition to the native protection
system provided by the key source. Supported protection systems include system provided by the key source. Supported protection systems include
Widevine, PlayReady, and CommonSystem (https://goo.gl/s8RIhr). Widevine, PlayReady, FairPlay, and CommonSystem (https://goo.gl/s8RIhr).

View File

@ -265,6 +265,7 @@ bool ParseProtectionSystems(
std::map<std::string, EncryptionParams::ProtectionSystem> mapping = { std::map<std::string, EncryptionParams::ProtectionSystem> mapping = {
{"common", EncryptionParams::ProtectionSystem::kCommonSystem}, {"common", EncryptionParams::ProtectionSystem::kCommonSystem},
{"commonsystem", EncryptionParams::ProtectionSystem::kCommonSystem}, {"commonsystem", EncryptionParams::ProtectionSystem::kCommonSystem},
{"fairplay", EncryptionParams::ProtectionSystem::kFairPlay},
{"playready", EncryptionParams::ProtectionSystem::kPlayReady}, {"playready", EncryptionParams::ProtectionSystem::kPlayReady},
{"widevine", EncryptionParams::ProtectionSystem::kWidevine}, {"widevine", EncryptionParams::ProtectionSystem::kWidevine},
}; };

View File

@ -52,6 +52,9 @@ int GetProtectionSystemsFlag(
case EncryptionParams::ProtectionSystem::kCommonSystem: case EncryptionParams::ProtectionSystem::kCommonSystem:
protection_systems_flags |= COMMON_PROTECTION_SYSTEM_FLAG; protection_systems_flags |= COMMON_PROTECTION_SYSTEM_FLAG;
break; break;
case EncryptionParams::ProtectionSystem::kFairPlay:
protection_systems_flags |= FAIRPLAY_PROTECTION_SYSTEM_FLAG;
break;
case EncryptionParams::ProtectionSystem::kPlayReady: case EncryptionParams::ProtectionSystem::kPlayReady:
protection_systems_flags |= PLAYREADY_PROTECTION_SYSTEM_FLAG; protection_systems_flags |= PLAYREADY_PROTECTION_SYSTEM_FLAG;
break; break;

View File

@ -12,5 +12,5 @@ DEFINE_string(additional_protection_systems,
"", "",
"Generate additional protection systems in addition to the " "Generate additional protection systems in addition to the "
"native protection system provided by the key source. Supported " "native protection system provided by the key source. Supported "
"protection systems include Widevine, PlayReady, and " "protection systems include Widevine, PlayReady, FairPlay, and "
"CommonSystem (https://goo.gl/s8RIhr)."); "CommonSystem (https://goo.gl/s8RIhr).");

View File

@ -441,12 +441,11 @@ class PackagerAppTest(unittest.TestCase):
flags.append('--iv=' + self.encryption_iv) flags.append('--iv=' + self.encryption_iv)
if fairplay: if fairplay:
fairplay_pssh = ('000000207073736800000000'
'29701FE43CC74A348C5BAE90C7439A4700000000')
fairplay_key_uri = ('skd://www.license.com/' fairplay_key_uri = ('skd://www.license.com/'
'getkey?KeyId=31323334-3536-3738-3930-313233343536') 'getkey?KeyId=31323334-3536-3738-3930-313233343536')
flags += [ flags += [
'--pssh=' + fairplay_pssh, '--hls_key_uri=' + fairplay_key_uri '--additional_protection_systems=FairPlay',
'--hls_key_uri=' + fairplay_key_uri
] ]
if protection_scheme: if protection_scheme:
flags += ['--protection_scheme', protection_scheme] flags += ['--protection_scheme', protection_scheme]
@ -1096,7 +1095,7 @@ class PackagerFunctionalTest(PackagerAppTest):
self.assertPackageSuccess(streams, flags) self.assertPackageSuccess(streams, flags)
self._CheckTestResults('avc-ts-aac-packed-audio-with-encryption') self._CheckTestResults('avc-ts-aac-packed-audio-with-encryption')
def testAvcTsWithEncryptionAndFairplay(self): def testAvcTsWithEncryptionAndFairPlay(self):
# Currently we only support live packaging for ts. # Currently we only support live packaging for ts.
self.assertPackageSuccess( self.assertPackageSuccess(
self._GetStreams( self._GetStreams(

View File

@ -15,6 +15,7 @@
#include "packager/base/strings/string_number_conversions.h" #include "packager/base/strings/string_number_conversions.h"
#include "packager/base/strings/stringprintf.h" #include "packager/base/strings/stringprintf.h"
#include "packager/hls/base/media_playlist.h" #include "packager/hls/base/media_playlist.h"
#include "packager/media/base/fairplay_pssh_generator.h"
#include "packager/media/base/protection_system_specific_info.h" #include "packager/media/base/protection_system_specific_info.h"
#include "packager/media/base/proto_json_util.h" #include "packager/media/base/proto_json_util.h"
#include "packager/media/base/raw_key_pssh_generator.h" #include "packager/media/base/raw_key_pssh_generator.h"
@ -32,7 +33,7 @@ namespace hls {
namespace { namespace {
const char kUriBase64Prefix[] = "data:text/plain;base64,"; const char kUriBase64Prefix[] = "data:text/plain;base64,";
const char kUriFairplayPrefix[] = "skd://"; const char kUriFairPlayPrefix[] = "skd://";
const char kWidevineDashIfIopUUID[] = const char kWidevineDashIfIopUUID[] =
"urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"; "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed";
@ -47,9 +48,10 @@ bool IsCommonSystemId(const std::vector<uint8_t>& system_id) {
std::equal(system_id.begin(), system_id.end(), media::kCommonSystemId); std::equal(system_id.begin(), system_id.end(), media::kCommonSystemId);
} }
bool IsFairplaySystemId(const std::vector<uint8_t>& system_id) { bool IsFairPlaySystemId(const std::vector<uint8_t>& system_id) {
return system_id.size() == arraysize(media::kFairplaySystemId) && return system_id.size() == arraysize(media::kFairPlaySystemId) &&
std::equal(system_id.begin(), system_id.end(), media::kFairplaySystemId); std::equal(system_id.begin(), system_id.end(),
media::kFairPlaySystemId);
} }
std::string Base64EncodeData(const std::string& prefix, std::string Base64EncodeData(const std::string& prefix,
@ -438,16 +440,16 @@ bool SimpleHlsNotifier::NotifyEncryptionUpdate(
NotifyEncryptionToMediaPlaylist(encryption_method, key_uri, empty_key_id, NotifyEncryptionToMediaPlaylist(encryption_method, key_uri, empty_key_id,
iv, "identity", "", media_playlist.get()); iv, "identity", "", media_playlist.get());
return true; return true;
} else if (IsFairplaySystemId(system_id)) { } else if (IsFairPlaySystemId(system_id)) {
std::string key_uri = hls_params().key_uri; std::string key_uri = hls_params().key_uri;
if (key_uri.empty()) { if (key_uri.empty()) {
// Use key_id as the key_uri. The player needs to have custom logic to // Use key_id as the key_uri. The player needs to have custom logic to
// convert it to the actual key uri. // convert it to the actual key uri.
std::string key_uri_data = VectorToString(key_id); std::string key_uri_data = VectorToString(key_id);
key_uri = Base64EncodeData(kUriFairplayPrefix, key_uri_data); key_uri = Base64EncodeData(kUriFairPlayPrefix, key_uri_data);
} }
// Fairplay defines IV to be carried with the key, not the playlist. // FairPlay defines IV to be carried with the key, not the playlist.
const std::vector<uint8_t> empty_iv; const std::vector<uint8_t> empty_iv;
NotifyEncryptionToMediaPlaylist(encryption_method, key_uri, empty_key_id, NotifyEncryptionToMediaPlaylist(encryption_method, key_uri, empty_key_id,
empty_iv, "com.apple.streamingkeydelivery", empty_iv, "com.apple.streamingkeydelivery",

View File

@ -13,6 +13,7 @@
#include "packager/base/files/file_path.h" #include "packager/base/files/file_path.h"
#include "packager/hls/base/mock_media_playlist.h" #include "packager/hls/base/mock_media_playlist.h"
#include "packager/hls/base/simple_hls_notifier.h" #include "packager/hls/base/simple_hls_notifier.h"
#include "packager/media/base/fairplay_pssh_generator.h"
#include "packager/media/base/protection_system_specific_info.h" #include "packager/media/base/protection_system_specific_info.h"
#include "packager/media/base/raw_key_pssh_generator.h" #include "packager/media/base/raw_key_pssh_generator.h"
#include "packager/media/base/raw_key_source.h" #include "packager/media/base/raw_key_source.h"
@ -36,7 +37,7 @@ namespace {
const char kMasterPlaylistName[] = "master.m3u8"; const char kMasterPlaylistName[] = "master.m3u8";
const char kDefaultLanguage[] = "en"; const char kDefaultLanguage[] = "en";
const char kEmptyKeyUri[] = ""; const char kEmptyKeyUri[] = "";
const char kFairplayKeyUri[] = "skd://www.license.com/getkey?key_id=testing"; const char kFairPlayKeyUri[] = "skd://www.license.com/getkey?key_id=testing";
const char kIdentityKeyUri[] = "https://www.license.com/getkey?key_id=testing"; const char kIdentityKeyUri[] = "https://www.license.com/getkey?key_id=testing";
const HlsPlaylistType kVodPlaylist = HlsPlaylistType::kVod; const HlsPlaylistType kVodPlaylist = HlsPlaylistType::kVod;
const HlsPlaylistType kLivePlaylist = HlsPlaylistType::kLive; const HlsPlaylistType kLivePlaylist = HlsPlaylistType::kLive;
@ -88,15 +89,12 @@ class SimpleHlsNotifierTest : public ::testing::Test {
SimpleHlsNotifierTest() : SimpleHlsNotifierTest(kVodPlaylist) {} SimpleHlsNotifierTest() : SimpleHlsNotifierTest(kVodPlaylist) {}
SimpleHlsNotifierTest(HlsPlaylistType playlist_type) SimpleHlsNotifierTest(HlsPlaylistType playlist_type)
: widevine_system_id_( : widevine_system_id_(std::begin(media::kWidevineSystemId),
media::kWidevineSystemId, std::end(media::kWidevineSystemId)),
media::kWidevineSystemId + arraysize(media::kWidevineSystemId)), common_system_id_(std::begin(media::kCommonSystemId),
common_system_id_( std::end(media::kCommonSystemId)),
media::kCommonSystemId, fairplay_system_id_(std::begin(media::kFairPlaySystemId),
media::kCommonSystemId + arraysize(media::kCommonSystemId)), std::end(media::kFairPlaySystemId)) {
fairplay_system_id_(
media::kFairplaySystemId,
media::kFairplaySystemId + arraysize(media::kFairplaySystemId)) {
hls_params_.playlist_type = kVodPlaylist; hls_params_.playlist_type = kVodPlaylist;
hls_params_.time_shift_buffer_depth = kTestTimeShiftBufferDepth; hls_params_.time_shift_buffer_depth = kTestTimeShiftBufferDepth;
hls_params_.base_url = kTestPrefix; hls_params_.base_url = kTestPrefix;
@ -707,14 +705,14 @@ TEST_F(SimpleHlsNotifierTest, EncryptionScheme) {
stream_id, key_id, common_system_id_, iv, dummy_pssh_data)); stream_id, key_id, common_system_id_, iv, dummy_pssh_data));
} }
// Verify that the Fairplay systemID is correctly handled when constructing // Verify that the FairPlay systemID is correctly handled when constructing
// encryption info. // encryption info.
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFairplay) { TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFairPlay) {
// Pointer released by SimpleHlsNotifier. // Pointer released by SimpleHlsNotifier.
MockMediaPlaylist* mock_media_playlist = MockMediaPlaylist* mock_media_playlist =
new MockMediaPlaylist("playlist.m3u8", "", ""); new MockMediaPlaylist("playlist.m3u8", "", "");
hls_params_.playlist_type = kLivePlaylist; hls_params_.playlist_type = kLivePlaylist;
hls_params_.key_uri = kFairplayKeyUri; hls_params_.key_uri = kFairPlayKeyUri;
SimpleHlsNotifier notifier(hls_params_); SimpleHlsNotifier notifier(hls_params_);
const uint32_t stream_id = const uint32_t stream_id =
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier); SetupStream(kSampleAesProtectionScheme, mock_media_playlist, &notifier);
@ -724,7 +722,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFairplay) {
EXPECT_CALL( EXPECT_CALL(
*mock_media_playlist, *mock_media_playlist,
AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes, AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes,
StrEq(kFairplayKeyUri), StrEq(""), StrEq(""), StrEq(kFairPlayKeyUri), StrEq(""), StrEq(""),
StrEq("com.apple.streamingkeydelivery"), StrEq("1"))); StrEq("com.apple.streamingkeydelivery"), StrEq("1")));
EXPECT_TRUE(notifier.NotifyEncryptionUpdate( EXPECT_TRUE(notifier.NotifyEncryptionUpdate(
stream_id, key_id, fairplay_system_id_, std::vector<uint8_t>(), stream_id, key_id, fairplay_system_id_, std::vector<uint8_t>(),

View File

@ -0,0 +1,42 @@
// Copyright 2018 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include "packager/media/base/fairplay_pssh_generator.h"
namespace shaka {
namespace media {
namespace {
const uint8_t kFairPlayPsshBoxVersion = 1;
} // namespace
FairPlayPsshGenerator::FairPlayPsshGenerator()
: PsshGenerator(std::vector<uint8_t>(std::begin(kFairPlaySystemId),
std::end(kFairPlaySystemId)),
kFairPlayPsshBoxVersion) {}
FairPlayPsshGenerator::~FairPlayPsshGenerator() = default;
bool FairPlayPsshGenerator::SupportMultipleKeys() {
return true;
}
base::Optional<std::vector<uint8_t>>
FairPlayPsshGenerator::GeneratePsshDataFromKeyIdAndKey(
const std::vector<uint8_t>& key_id,
const std::vector<uint8_t>& key) const {
NOTIMPLEMENTED();
return base::nullopt;
}
base::Optional<std::vector<uint8_t>>
FairPlayPsshGenerator::GeneratePsshDataFromKeyIds(
const std::vector<std::vector<uint8_t>>& key_ids) const {
// Intentionally empty PSSH data for FairPlay.
return std::vector<uint8_t>();
}
} // namespace media
} // namespace shaka

View File

@ -0,0 +1,48 @@
// Copyright 2018 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#ifndef PACKAGER_MEDIA_BASE_FAIRPLAY_PSSH_GENERATOR_H_
#define PACKAGER_MEDIA_BASE_FAIRPLAY_PSSH_GENERATOR_H_
#include "packager/media/base/pssh_generator.h"
namespace shaka {
namespace media {
// Unofficial FairPlay system id extracted from
// https://forums.developer.apple.com/thread/6185.
const uint8_t kFairPlaySystemId[] = {0x29, 0x70, 0x1F, 0xE4, 0x3C, 0xC7,
0x4A, 0x34, 0x8C, 0x5B, 0xAE, 0x90,
0xC7, 0x43, 0x9A, 0x47};
class FairPlayPsshGenerator : public PsshGenerator {
public:
FairPlayPsshGenerator();
~FairPlayPsshGenerator() override;
/// @name PsshGenerator implemetation overrides.
/// @{
bool SupportMultipleKeys() override;
/// @}
private:
FairPlayPsshGenerator& operator=(const FairPlayPsshGenerator&) = delete;
FairPlayPsshGenerator(const FairPlayPsshGenerator&) = delete;
// PsshGenerator implemetation overrides.
base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIds(
const std::vector<std::vector<uint8_t>>& key_ids) const override;
base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIdAndKey(
const std::vector<uint8_t>& key_id,
const std::vector<uint8_t>& key) const override;
};
} // namespace media
} // namespace shaka
#endif // PACKAGER_MEDIA_BASE_FAIRPLAY_PSSH_GENERATOR_H_

View File

@ -7,6 +7,7 @@
#include "packager/media/base/key_source.h" #include "packager/media/base/key_source.h"
#include "packager/base/logging.h" #include "packager/base/logging.h"
#include "packager/media/base/fairplay_pssh_generator.h"
#include "packager/media/base/playready_pssh_generator.h" #include "packager/media/base/playready_pssh_generator.h"
#include "packager/media/base/raw_key_pssh_generator.h" #include "packager/media/base/raw_key_pssh_generator.h"
#include "packager/media/base/widevine_pssh_generator.h" #include "packager/media/base/widevine_pssh_generator.h"
@ -30,6 +31,10 @@ KeySource::KeySource(int protection_systems_flags) {
if (protection_systems_flags & WIDEVINE_PROTECTION_SYSTEM_FLAG) { if (protection_systems_flags & WIDEVINE_PROTECTION_SYSTEM_FLAG) {
pssh_generators_.emplace_back(new WidevinePsshGenerator()); pssh_generators_.emplace_back(new WidevinePsshGenerator());
} }
if (protection_systems_flags & FAIRPLAY_PROTECTION_SYSTEM_FLAG) {
pssh_generators_.emplace_back(new FairPlayPsshGenerator());
}
} }
KeySource::~KeySource() {} KeySource::~KeySource() {}

View File

@ -44,6 +44,8 @@
'decryptor_source.cc', 'decryptor_source.cc',
'decryptor_source.h', 'decryptor_source.h',
'encryption_config.h', 'encryption_config.h',
'fairplay_pssh_generator.cc',
'fairplay_pssh_generator.h',
'fourccs.h', 'fourccs.h',
'http_key_fetcher.cc', 'http_key_fetcher.cc',
'http_key_fetcher.h', 'http_key_fetcher.h',

View File

@ -81,12 +81,7 @@ PlayReadyKeySource::PlayReadyKeySource(
client_cert_private_key_file_(client_cert_private_key_file), client_cert_private_key_file_(client_cert_private_key_file),
client_cert_private_key_password_(client_cert_private_key_password) {} client_cert_private_key_password_(client_cert_private_key_password) {}
PlayReadyKeySource::PlayReadyKeySource( PlayReadyKeySource::~PlayReadyKeySource() = default;
std::unique_ptr<EncryptionKey> encryption_key)
: KeySource(PLAYREADY_PROTECTION_SYSTEM_FLAG),
encryption_key_(std::move(encryption_key)) {}
PlayReadyKeySource::~PlayReadyKeySource() {}
Status RetrieveTextInXMLElement(const std::string& element, Status RetrieveTextInXMLElement(const std::string& element,
const std::string& xml, const std::string& xml,

View File

@ -68,7 +68,6 @@ class PlayReadyKeySource : public KeySource {
private: private:
Status GetKeyInternal(); Status GetKeyInternal();
Status GetCryptoPeriodKeyInternal(); Status GetCryptoPeriodKeyInternal();
explicit PlayReadyKeySource(std::unique_ptr<EncryptionKey> key);
std::unique_ptr<EncryptionKey> encryption_key_; std::unique_ptr<EncryptionKey> encryption_key_;
std::string server_url_; std::string server_url_;

View File

@ -17,6 +17,7 @@
#define COMMON_PROTECTION_SYSTEM_FLAG 0x01 #define COMMON_PROTECTION_SYSTEM_FLAG 0x01
#define PLAYREADY_PROTECTION_SYSTEM_FLAG 0x02 #define PLAYREADY_PROTECTION_SYSTEM_FLAG 0x02
#define WIDEVINE_PROTECTION_SYSTEM_FLAG 0x04 #define WIDEVINE_PROTECTION_SYSTEM_FLAG 0x04
#define FAIRPLAY_PROTECTION_SYSTEM_FLAG 0x08
namespace shaka { namespace shaka {
namespace media { namespace media {

View File

@ -6,8 +6,6 @@
#include "packager/media/base/raw_key_pssh_generator.h" #include "packager/media/base/raw_key_pssh_generator.h"
#include "packager/media/base/raw_key_source.h"
namespace shaka { namespace shaka {
namespace media { namespace media {
namespace { namespace {
@ -19,7 +17,7 @@ RawKeyPsshGenerator::RawKeyPsshGenerator()
std::end(kCommonSystemId)), std::end(kCommonSystemId)),
kCommonSystemPsshBoxVersion) {} kCommonSystemPsshBoxVersion) {}
RawKeyPsshGenerator::~RawKeyPsshGenerator() {} RawKeyPsshGenerator::~RawKeyPsshGenerator() = default;
bool RawKeyPsshGenerator::SupportMultipleKeys() { bool RawKeyPsshGenerator::SupportMultipleKeys() {
return true; return true;
@ -39,5 +37,6 @@ RawKeyPsshGenerator::GeneratePsshDataFromKeyIds(
// Intentionally empty PSSH data for RawKey. // Intentionally empty PSSH data for RawKey.
return std::vector<uint8_t>(); return std::vector<uint8_t>();
} }
} // namespace media } // namespace media
} // namespace shaka } // namespace shaka

View File

@ -17,12 +17,6 @@
namespace shaka { namespace shaka {
namespace media { namespace media {
// Unofficial fairplay system id extracted from
// https://forums.developer.apple.com/thread/6185.
const uint8_t kFairplaySystemId[] = {0x29, 0x70, 0x1F, 0xE4, 0x3C, 0xC7,
0x4A, 0x34, 0x8C, 0x5B, 0xAE, 0x90,
0xC7, 0x43, 0x9A, 0x47};
/// A key source that uses raw keys for encryption. /// A key source that uses raw keys for encryption.
class RawKeySource : public KeySource { class RawKeySource : public KeySource {
public: public:

View File

@ -28,7 +28,7 @@ constexpr double kPackedAudioTimescale = 90000;
constexpr char kTimestampOwnerIdentifier[] = constexpr char kTimestampOwnerIdentifier[] =
"com.apple.streaming.transportStreamTimestamp"; "com.apple.streaming.transportStreamTimestamp";
/// http://goo.gl/FPhLma 2.4.3.4 Elementary Stream Setup for fairplay streaming /// http://goo.gl/FPhLma 2.4.3.4 Elementary Stream Setup for FairPlay streaming
/// Audio setup information is carried inside an ID3 PRIV tag with identifier: /// Audio setup information is carried inside an ID3 PRIV tag with identifier:
constexpr char kAudioDescriptionOwnerIdentifier[] = constexpr char kAudioDescriptionOwnerIdentifier[] =
"com.apple.streaming.audioDescription"; "com.apple.streaming.audioDescription";

View File

@ -117,9 +117,10 @@ struct EncryptionParams {
/// Supported protection systems. /// Supported protection systems.
enum class ProtectionSystem { enum class ProtectionSystem {
kWidevine,
kPlayReady,
kCommonSystem, kCommonSystem,
kFairPlay,
kPlayReady,
kWidevine,
}; };
/// Additional protection systems to be generated. /// Additional protection systems to be generated.
std::vector<ProtectionSystem> additional_protection_systems; std::vector<ProtectionSystem> additional_protection_systems;