From 96efc5aa70c2152a242f36644100161bc562d3f7 Mon Sep 17 00:00:00 2001 From: wjywbs Date: Fri, 23 Feb 2024 18:29:13 -0500 Subject: [PATCH] feat: Add PlayReady support in HLS. (#1011) Co-authored-by: Cosmin Stejerean --- .../encryption-with-multi-drms/stream_0.m3u8 | 1 + .../encryption-with-multi-drms/stream_1.m3u8 | 1 + packager/hls/base/simple_hls_notifier.cc | 23 ++++++++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packager/app/test/testdata/encryption-with-multi-drms/stream_0.m3u8 b/packager/app/test/testdata/encryption-with-multi-drms/stream_0.m3u8 index 1eecba5c115..5f5caf3af6f 100644 --- a/packager/app/test/testdata/encryption-with-multi-drms/stream_0.m3u8 +++ b/packager/app/test/testdata/encryption-with-multi-drms/stream_0.m3u8 @@ -4,6 +4,7 @@ #EXT-X-TARGETDURATION:2 #EXT-X-PLAYLIST-TYPE:VOD #EXT-X-MAP:URI="bear-640x360-audio.mp4",BYTERANGE="1568@0" +#EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="data:text/plain;charset=UTF-16;base64,BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATgBEAE0AeQBNAFQAWQAxAE8ARABjADUATQBEAEUAeQBNAHoAUQAxAE4AZwA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBsADUATABvAFUAZwBLADkASwBDAGcAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=",KEYFORMATVERSIONS="1",KEYFORMAT="com.microsoft.playready" #EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="data:text/plain;base64,AAAAOHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABgSEDEyMzQ1Njc4OTAxMjM0NTZI49yVmwY=",KEYID=0x31323334353637383930313233343536,KEYFORMATVERSIONS="1",KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" #EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="skd://www.license.com/getkey?KeyId=31323334-3536-3738-3930-313233343536",KEYFORMATVERSIONS="1",KEYFORMAT="com.apple.streamingkeydelivery" #EXTINF:1.022, diff --git a/packager/app/test/testdata/encryption-with-multi-drms/stream_1.m3u8 b/packager/app/test/testdata/encryption-with-multi-drms/stream_1.m3u8 index 6b261d7f392..443fdfa39a7 100644 --- a/packager/app/test/testdata/encryption-with-multi-drms/stream_1.m3u8 +++ b/packager/app/test/testdata/encryption-with-multi-drms/stream_1.m3u8 @@ -4,6 +4,7 @@ #EXT-X-TARGETDURATION:2 #EXT-X-PLAYLIST-TYPE:VOD #EXT-X-MAP:URI="bear-640x360-video.mp4",BYTERANGE="1692@0" +#EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="data:text/plain;charset=UTF-16;base64,BgIAAAEAAQD8ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ATgBEAE0AeQBNAFQAWQAxAE8ARABjADUATQBEAEUAeQBNAHoAUQAxAE4AZwA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBsADUATABvAFUAZwBLADkASwBDAGcAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=",KEYFORMATVERSIONS="1",KEYFORMAT="com.microsoft.playready" #EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="data:text/plain;base64,AAAAOHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABgSEDEyMzQ1Njc4OTAxMjM0NTZI49yVmwY=",KEYID=0x31323334353637383930313233343536,KEYFORMATVERSIONS="1",KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" #EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="skd://www.license.com/getkey?KeyId=31323334-3536-3738-3930-313233343536",KEYFORMATVERSIONS="1",KEYFORMAT="com.apple.streamingkeydelivery" #EXTINF:1.001, diff --git a/packager/hls/base/simple_hls_notifier.cc b/packager/hls/base/simple_hls_notifier.cc index 9b85f83bd10..f016a7a3d52 100644 --- a/packager/hls/base/simple_hls_notifier.cc +++ b/packager/hls/base/simple_hls_notifier.cc @@ -36,6 +36,7 @@ namespace hls { namespace { const char kUriBase64Prefix[] = "data:text/plain;base64,"; +const char kUriBase64Utf16Prefix[] = "data:text/plain;charset=UTF-16;base64,"; const char kUriFairPlayPrefix[] = "skd://"; const char kWidevineDashIfIopUUID[] = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"; @@ -57,6 +58,12 @@ bool IsFairPlaySystemId(const std::vector& system_id) { media::kFairPlaySystemId); } +bool IsPlayReadySystemId(const std::vector& system_id) { + return system_id.size() == std::size(media::kPlayReadySystemId) && + std::equal(system_id.begin(), system_id.end(), + media::kPlayReadySystemId); +} + std::string Base64EncodeData(const std::string& prefix, const std::string& data) { std::string data_base64; @@ -65,7 +72,7 @@ std::string Base64EncodeData(const std::string& prefix, } std::string VectorToString(const std::vector& v) { - return std::string(v.begin(), v.end()); + return std::string(v.begin(), v.end()); } // Segment URL is relative to either output directory or the directory @@ -471,6 +478,20 @@ bool SimpleHlsNotifier::NotifyEncryptionUpdate( "1", media_playlist.get()); return true; } + if (IsPlayReadySystemId(system_id)) { + std::unique_ptr b = + media::PsshBoxBuilder::ParseFromBox( + protection_system_specific_data.data(), + protection_system_specific_data.size()); + std::string pssh_data(reinterpret_cast(b->pssh_data().data()), + b->pssh_data().size()); + std::string key_uri_data_base64 = + Base64EncodeData(kUriBase64Utf16Prefix, pssh_data); + NotifyEncryptionToMediaPlaylist(encryption_method, key_uri_data_base64, + empty_key_id, iv, "com.microsoft.playready", + "1", media_playlist.get()); + return true; + } LOG(WARNING) << "HLS: Ignore unknown or unsupported system ID: " << absl::BytesToHexString(absl::string_view(