From ae803432d68e00bcb4ad0339e5e2985a87b08e91 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Tue, 9 Jul 2024 16:53:34 +0200 Subject: [PATCH] Add DRM integration tests --- .../tools/DummyMediaElement/eme.ts | 4 + .../DASH_DRM_static_SegmentTemplate/index.mjs | 3 + .../DASH_DRM_static_SegmentTemplate/infos.mjs | 31 + .../media/1-80399bf5/0001.m4s | Bin 0 -> 3099 bytes .../media/1-80399bf5/init.mp4 | Bin 0 -> 990 bytes .../media/10-80399bf5/0001.m4s | Bin 0 -> 3113 bytes .../media/10-80399bf5/init.mp4 | Bin 0 -> 1075 bytes .../media/11-90953e09/0001.m4s | Bin 0 -> 3113 bytes .../media/11-90953e09/init.mp4 | Bin 0 -> 1059 bytes .../media/12-90953e09/0001.m4s | Bin 0 -> 3113 bytes .../media/12-90953e09/init.mp4 | Bin 0 -> 1059 bytes .../media/15-585f233f/0001.m4s | Bin 0 -> 1429 bytes .../media/15-585f233f/init.mp4 | Bin 0 -> 1750 bytes .../media/16-4222bd78/0001.m4s | Bin 0 -> 1429 bytes .../media/16-4222bd78/init.mp4 | Bin 0 -> 1753 bytes .../media/17/0001.m4s | Bin 0 -> 540 bytes .../media/17/init.mp4 | Bin 0 -> 1673 bytes .../media/19/0001.m4s | Bin 0 -> 437 bytes .../media/19/init.mp4 | Bin 0 -> 716 bytes .../media/2-80399bf5/0001.m4s | Bin 0 -> 3099 bytes .../media/2-80399bf5/init.mp4 | Bin 0 -> 991 bytes .../media/27/0001.m4s | Bin 0 -> 440 bytes .../media/27/init.mp4 | Bin 0 -> 716 bytes .../media/3-80399bf5/0001.m4s | Bin 0 -> 3099 bytes .../media/3-80399bf5/init.mp4 | Bin 0 -> 995 bytes .../media/4-90953e09/0001.m4s | Bin 0 -> 3099 bytes .../media/4-90953e09/init.mp4 | Bin 0 -> 990 bytes .../media/5-90953e09/0001.m4s | Bin 0 -> 3099 bytes .../media/5-90953e09/init.mp4 | Bin 0 -> 992 bytes .../media/8-80399bf5/0001.m4s | Bin 0 -> 3113 bytes .../media/8-80399bf5/init.mp4 | Bin 0 -> 1059 bytes .../media/9-80399bf5/0001.m4s | Bin 0 -> 3113 bytes .../media/9-80399bf5/init.mp4 | Bin 0 -> 1059 bytes .../media/encrypted_multiple_keys_number.mpd | 127 ++++ .../DASH_DRM_static_SegmentTemplate/urls.mjs | 138 ++++ tests/contents/urls.mjs | 2 + tests/integration/scenarios/drm_base.js | 655 ++++++++++++++++++ .../scenarios/drm_getLicenceConfig.js | 224 ++++++ 38 files changed, 1184 insertions(+) create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/index.mjs create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/infos.mjs create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/1-80399bf5/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/1-80399bf5/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/10-80399bf5/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/10-80399bf5/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/11-90953e09/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/11-90953e09/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/12-90953e09/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/12-90953e09/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/15-585f233f/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/15-585f233f/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/16-4222bd78/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/16-4222bd78/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/17/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/17/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/19/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/19/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/2-80399bf5/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/2-80399bf5/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/27/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/27/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/3-80399bf5/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/3-80399bf5/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/4-90953e09/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/4-90953e09/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/5-90953e09/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/5-90953e09/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/8-80399bf5/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/8-80399bf5/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/9-80399bf5/0001.m4s create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/9-80399bf5/init.mp4 create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/media/encrypted_multiple_keys_number.mpd create mode 100644 tests/contents/DASH_DRM_static_SegmentTemplate/urls.mjs create mode 100644 tests/integration/scenarios/drm_base.js create mode 100644 tests/integration/scenarios/drm_getLicenceConfig.js diff --git a/src/experimental/tools/DummyMediaElement/eme.ts b/src/experimental/tools/DummyMediaElement/eme.ts index 9a5f5657e58..e9b2d6288d1 100644 --- a/src/experimental/tools/DummyMediaElement/eme.ts +++ b/src/experimental/tools/DummyMediaElement/eme.ts @@ -574,6 +574,10 @@ export class DummyMediaKeySession return Promise.resolve(); } + public getPolicyLevel(): number { + return this._currentPolicyLevel; + } + public updatePolicyLevel(newLevel: number) { this._currentPolicyLevel = newLevel; diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/index.mjs b/tests/contents/DASH_DRM_static_SegmentTemplate/index.mjs new file mode 100644 index 00000000000..2dc7a001cf2 --- /dev/null +++ b/tests/contents/DASH_DRM_static_SegmentTemplate/index.mjs @@ -0,0 +1,3 @@ +import manifestInfos from "./infos.mjs"; + +export { manifestInfos }; diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/infos.mjs b/tests/contents/DASH_DRM_static_SegmentTemplate/infos.mjs new file mode 100644 index 00000000000..b7d7b6a8610 --- /dev/null +++ b/tests/contents/DASH_DRM_static_SegmentTemplate/infos.mjs @@ -0,0 +1,31 @@ +const BASE_URL = + "http://" + + /* eslint-disable no-undef */ + __TEST_CONTENT_SERVER__.URL + + ":" + + __TEST_CONTENT_SERVER__.PORT + + /* eslint-enable no-undef */ + "/DASH_DRM_static_SegmentTemplate/media/"; + +export default { + url: BASE_URL + "encrypted_multiple_keys_number.mpd", + transport: "dash", + isDynamic: false, + isLive: false, + duration: 734, + minimumPosition: 0, + maximumPosition: 734, + availabilityStartTime: 0, + periods: [ + { + start: 0, + duration: 734, + // TODO? + adaptations: { + audio: [], + video: [], + text: [], + }, + }, + ], +}; diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/1-80399bf5/0001.m4s b/tests/contents/DASH_DRM_static_SegmentTemplate/media/1-80399bf5/0001.m4s new file mode 100644 index 0000000000000000000000000000000000000000..a134aadb653b25c06910168f017fb96abcc0035c GIT binary patch literal 3099 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 literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/11-90953e09/0001.m4s b/tests/contents/DASH_DRM_static_SegmentTemplate/media/11-90953e09/0001.m4s new file mode 100644 index 0000000000000000000000000000000000000000..39f4234773c050738f2fd667fe85bfc1f0ff0a5f GIT binary patch literal 3113 zcmcJR>2Fk37{<>zcZQJ}8cRirQjm&E(JEk-eHCm$6eyb@h0f6FOouX^fjc#_Xc{13 z2qi?}1K$Y5B>_!@#Dqv7Y=Mvv6HtSoAN&9sS&U2K5)j|_p6B*G{{T1XocH&<&pG#O z_na!F2Kc45#k`+xQ}l3|_j7MkSnKD~T=Jt;#hk7nvOiksEB~p6kFW0xIPpWiP{>eN zp3k(U;nPYb&Xm@q0=>k#2{NRs@=_*Uf{%+@KU++5!f(xGspv<4g!+M7aNTGQE~RLpi(C9Wy;WfzV6gq;(P_2ys*>Qp1e7ZA^-c&wvm9esxrr^J)+ z9R0B9y5#6ro%k*BB+4B9P0{swN53Vp`CL5ars#UM=oQ_ftIHDWQQ}c|9et4K(bq*+ zze%hg7msdm^h1t*#L>$ojx>o!-4nh31JSk9=briJwbe5%U~YIQljxo-7`3wWEI~x^enreiV;8 zSNbE-%_^sEQFOh`#=UBMdr0yYO4b!q#q-;)^i@&Si?}lQtqpzy#k<3CO*4Ev4r2W- z_#yCFa6fPznAec~DR6)Ad*Dj&Qt$xF@w?zhkpC3?D7XVW5d00e3S0#9`qBFnG4NpI z7l0oFcY=q2e*#xqHV43b{!n}7I+)j+$2SAaX9ID?R`8RS)kW}A@Q(mLjr?EW8ssa% z!z@P|z|X*c1NT~9Pf+Z zaQ$BbZ-AfAex9$vVE*oyBj7QX<72>l2Xg)%c${Su?w|3<|A{=GG2~ZAz!Q<*0p>HB z^06<#{QVI}6W}TE7r;|3H}wbeSxEkPD|j0Gcfivvo0H&IkiP}4w_Fy!kMA(<&pXJ^ zu%ib~Y9Mqo<`K6ZC@8Bln zmx1}r_IG=&3iGSd7CBgZPX&N zCl5UpL2&U>^dxxlAb1f(e?UP`B6#s2UKEc-S!Z5$yQ%df$;^D;%w+N=gphGh-E9Rj znk9r#w9Jt{_#gbcek0AY_vNHv?g-#37& ziG<$)TM)ee&O_xd5L+tNJXT@XVdvBx*}(j?sTG z?3#-I#8qH(a2wlNp5{zR@FsXDm1YKW(Fa@UgvO|VEr4bTHatU^<1smMrGqtB-{X_m zJ`3^CHIjhgCU>y{aa41fEYypkZ$!}aKpjhjZkio)nx)zVi#g^XP|vsH&`N!JU#dn3 zbXh7nSS;kwDc*E(;fQQcP2}*iYvAII*q4#gndf+~2hlx0aTlmzfxD^2)t}_|pPd~- z4x1KqIa;N8+UsG0i5VtdtKAKwItgm=9M!cMY0Kzz>`~s`c)0Yb_iG!*DiAW?A-T__ zGX*6F7U|pgRig?otIPB>@?I<)pC={Y#-!^Du*8MW?SI7y-~ym5g`5T**?csAFnqcE z?CH(*8$Z5(>;heoO0PUk(Xs63YibNmbbTQ9E!4PChHJE$av;7YxV9)wX4enDOzgB; ju%RLBApOUVKUWbpJH{Mcte0@fNxa!g@l>T)nkoGSdWER7 literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/12-90953e09/0001.m4s b/tests/contents/DASH_DRM_static_SegmentTemplate/media/12-90953e09/0001.m4s new file mode 100644 index 0000000000000000000000000000000000000000..088478fe2e271a0b2302e7cf05f1f0be114d7549 GIT binary patch literal 3113 zcmcJR>u(fQ7{EwzZcPfflt;wW1Zgq6nx!MJ*LkE&{uB+wCgbuFRSWCZ-qy z1Tmt33C3uGe&7=tV@QlK8k-_0YBUfM4JIbuLJ;K=5S7IDo%4+E`3Ib2_q@O7dCtt4 znRCvrQYsym*OZE3u3yo?Z80o7O=Wvn$Z^YuR&`y&QRTk0GTUm^oVWLGjkx+~ad5DY z%9>(de-1gVRP|_ibvDw=teeOoUDcHPa%JSWX%F+I92;S8Ax}*`eF$~s)*aJRtKRK= zb5~~Virirz9_YEvZ{eN=S& zh3Iys=nY4t)+;2V*Lix2=;m_KO{LU&qh#vd6Wxr6u8X4UOQdc+A(>#d=>I)WdPlZG zbUjIGvtRn^KRx|N(T(?P>*HrjbHHRIqrHrIOZ1^vF@GrEd;mJt_PAusVbOzv==Ms{ z?JZIpZ(cQS5u*H2 z?NXbUBx81nuJ?NS#h$*+tN)RVe$CS_6+LmC=ytu-rcW~ZjOaSP7Tt?Uif+z%^&isL zEcW!2=sKRCJRjyrCWzlPpMR?8`VHx8_IUcEUX6F1Yzy5c$x|pZrIamww)xvyl~76I zrs%sp`i>NPf$O$ckgKEf5mzL@{H%zRz2JJs`b%(wW3wFG2wo3vLVg&WcHA@`e3@hW zK6niJZvgYUr|a7-;IZ(30gnTBfq74&eC<4NGyK27yr+<_p9D{Ue-3;Fco&%066MV- zFz>;{EopEo`~W=Bu|5LkJ%jT0Q*ax28u)6*4PS$=LI1_zYr)Ted2R6c$AEeM^7tCS zlfedjJ@V_oH#n}_1MWcnL-38r=fP9JDKO7Tx?bzA;F}x=Gr%`HHu3x8Im!30;os_5 zPXOPB{3qbs;hzFega1AF4*2o=ywh=g{6426zXbWa9IH4#1ODsqd5@#<4Q&U{a@;%u zzT2_=8GH}=e+9nRanJ*vjr=$;uWi2n4)9#`kJm@1&1up}~``2>tMezB*1)V=J37m0kp9S-8 z7LPC9Cs#VwC*bq%A&)N}PY!tnzZZNG%)c9azGL7#cmcQ{Y{3P`I$nQ|!=DMC|1Z+{ lf_Ofzfu6nYRZdM=ju-fYrrt&e2id*Aoow{PYxA!OWD51PIV z=LjJbJ+q|;@u(Yd4*nYYWf|V!%(u-ee!$II6tY&GGjq*Xo_V!)anYP9&KFD8(&ZH^ z;_>{#S?hk;DV=v6ZV6i|9)XbYR)k>;K_Fs}flrz7LnjnQNTCN4AP$g(RMNGF;|xGm z5%V_qyx{$J9xZ)`+*Faqu?tm)%1M+5zKJ9lAek){*{cxWQL9?VK;p~J>(2>~*?(-P znvnnG6+p8cLPi!eJ0qK~`Dgqafpwg8+d*zgWvjxBQhW(Rw2eZnWP zJQm=kYm0q`o7}e*$iu4LV1Zr?eJA{e3v3}4S~NZ8G)uS%7ICaWLq6Av0yBx}BdMGK z;F45wuvn;}Q@l~fg`=f4HIVJVv8xc`AMH>@0;itiy&hx_y|}(eGbV%^nr#0jfA)5F z2{~q%pmMT8bF|mP0s|`y{IxfqWGa)u7B5lVo1(hLhfaRyo9n!My8V7{jE<2J(CQMp zM$9Q_$u7~4(Y8~8m(^r)8#y-;w#VaHzzVYN3Gk#2$L*iu3}8M$rb0{`9o=|#;Yjdi z`Ni{l>vwnoO@BKAFgF kHeo|Uv;5>6JN-(9D0Yh3x>+ybx*fZ7<>I+=adu|*FG>=pi~s-t literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/15-585f233f/0001.m4s b/tests/contents/DASH_DRM_static_SegmentTemplate/media/15-585f233f/0001.m4s new file mode 100644 index 0000000000000000000000000000000000000000..16cd2119c28e627185e52f8dfc68f59354e30974 GIT binary patch literal 1429 zcmcK1%Wl&^7>40-M5HXcK&VJ8kdOeONWcoQp{$VD04Z%rTS9T-IB}_yka3_VS_%cq zxs>y<1 zc*YdIwX3y@=5smYC1$ZbPalr!^-yJ3999F?X-#@>()3-wJ8}J#*{NFn4JzBCD+z;S zt!!Vjw$cc+z}RwB5gQdvy-a>&ThE^6p{fOu`xJMsmNKj?DF>AO$_~ZdTkm<@``o!kmF?@>C-ukj_M<|B9-eJo-L11w{R6|7=}qj(0#Fvc3z zv4Ll?i53%V;W<2y<2ZqnIEB-A0cUU)FX9|t!pk_1SMVxc!v(yKH}EFj!rOQU@8Tlf z!zH|r5AY#A!pHaopW-uojxX>fzQSc(!Poc(-{LC1!}s_BKjJ6+j9-kI&cuPA`~_X! B^L_vT literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/15-585f233f/init.mp4 b/tests/contents/DASH_DRM_static_SegmentTemplate/media/15-585f233f/init.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..a90fe4d0b499c23b3b344968be2b4aaf8c62d5c1 GIT binary patch literal 1750 zcmeHHJ#W-N5M5saNfE(CTqsb47C{lA*f_@}92GeZLO=>SDJUQWihSO6Y{hGzcK42t ziUNt2KY)k?O*(!61)_k8ijta&20D-^nAx?71r4Hw(VgeLH?uqA8OekY8tHq3MCFTw z5NEB`q2LK}7O0qz8i^$5sQtHpaspRy|Cd$1##s{3l_ce~Cv!FoIiq(H9n(v_PM7-L zlGk)ET-{yIW`a&9hOTyCP7UOBmgFD)M{;AQhvS;Vj>OntB8Ocf{FzjGQ>; zXJEchIa+Um!Yap$P5x)z*F1W2Z_W2}cQZ0>+7^<2-;u6&%KClADY7<%p+rV$> zZFA3r?S1G0CZtyVT-nL)_%9t7k(6EI-_RIuuNu*U6Im^$+opQIJD6bEWd z<-@GR=+}WWYL~SdWGpqaciJM!A_&)&uy+?{PB5#_GRZNHhFwk#Wl9VDUFm)b_=VES z?5)sucot&6XnSu~BXtyP$7G%>rjU;vg~#~eM7gHR3t?p1}(h1p~6^zCm|Fos?33wfJ8NF#+=C;o5#=ja^=g@=i>Ezw9^2&uCz9_ zZ4Po(^+M_}y-|?f;Ss ufxlCr2Y*-RIQ_Y5FITzDX$QVBVGc8amo8o(@{WY@AT^@_V*T_7N`3(48Qd}e literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/16-4222bd78/0001.m4s b/tests/contents/DASH_DRM_static_SegmentTemplate/media/16-4222bd78/0001.m4s new file mode 100644 index 0000000000000000000000000000000000000000..f242760d01f240c42cb5a0bc1d55bd598b534e30 GIT binary patch literal 1429 zcmb`{%TE(g6vy#9jg4IrMQs%j!3S!6fS~vQ<*BGBRlx^V7&?6nI<(;q28}Uc=TiR+ z{sC4RNKE`U+_`t>(%&uLZVfTqMb zGbX=P&$bVmujPyvo6q%maw4i$OG=xfQYD~IJ<0BP*?0AH?CJ^ArCjwrO6#L3E(P&+ zT0drOxfZCw*kV`~%?eGu)NseQ)vsein;V1GwaM>aeyZML7s@r+=yjLn)$Pn!KYTB} zLUE}eO-hkhwChCG-LY{(HFtqV!dLn!US3&J?rQ2!=2V*|W_FOz(laG@(!ZNMZ?&dg zzBjJuQ@H2Wrg|gfySdiC-ibEO8)Z$`_aEyf{#Z87?Ze*nl^-8}{oaTBu^A8GK|F+M z%-~@>f-TsJZFm&h@fdbsCmzQWcoI)x7oNs5cowsG4$tESyolY{gO{)u`|vVe!G64o z*YG;tzyTb@n|KR{a2Q8$6vuEJZ{r=Dz`J-4@8cvsz=t@6IedhV@d-}j3_itY_#9v0 pEWX6X_w|bT9L}SU3s}Gai&(-kRxrdxe2s4~Lj89>q@uu&{{r>U_C^2z literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/16-4222bd78/init.mp4 b/tests/contents/DASH_DRM_static_SegmentTemplate/media/16-4222bd78/init.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..29ec02c6e57d406e3eac3642cd0cc24c38f80e96 GIT binary patch literal 1753 zcmeHHF>4e-6rR0A6C}#1iG>6i#UhBiZq7?Q8_DHNjKax5G=(U#w=(J4+xnC<;w`13@bTsXY6bgPw(SY!~gunPe>&jm~v02Qn}AFOff4W>@L!zZanEWv>q zQ*w|N82u`6M(wgzf|Mm@_D(~@X%E6xCG6e#nUl=w(=6i{N5d{B23bOL{9Wm80{Df} z%Iq!Iw|E+2zi7K}Rv}dsY{%p@S4<%vIR=l>BMVc+c}$!GTZDZ3x@YY0_}ZsuEBE(0 zxT}t`y-f5n5r}>r@19g)B*2ppise;iK#M`58Z~3i_~MCIn>$O**Do)~2ko~{KZ0CU zTASK72f51gjWP-RULGqPAfDt)_u6AKZ{}Y`4Y&Q^<@sWx;^OlFoW_ zUfuKQ8R~}JjLz46-=}WGhc!5{^9NNXiz--mwcS~Sa}UdvDBNhwg647~R~iL?=&avr zwHp2}xe)j}1$ywewZsL?lzX|#GfA89nF%G#1YSCSeaJf+M*YN$28i_sKTz@m-2~l3 literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/17/0001.m4s b/tests/contents/DASH_DRM_static_SegmentTemplate/media/17/0001.m4s new file mode 100644 index 0000000000000000000000000000000000000000..5c32987f360f77e69f660048bbfb7cac215eb7e7 GIT binary patch literal 540 zcmZQzV2~&-sVvAXPRU>Z0uY^BoLK>6>J(?DfM^h4WMGIr0A@i5Aiwqo17iup1TdfR zLT-M38jvZFo0gFRRR>hVxTB;f5hN~A0upCp&;YW5;w(TW7zmW4rIbLJAd<18q^LBH zfq@CAh9MTnzX8OdP#iYM+1Wt%0mF;Y9*8Y~H~@%qf!G6xy@41QzKqU54Dt`UUy6ZZ V?m+AYmB*%rj^R+lk(-iO0sy;_JGuY> literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/17/init.mp4 b/tests/contents/DASH_DRM_static_SegmentTemplate/media/17/init.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..5bb51e244d86fbf05a34ea674eba814fa0a026a0 GIT binary patch literal 1673 zcmeHHzi-n(6h60wFaR=8I-m*;i2)&O+>nN_C4`oM6cnjd1_Yvx?^0X!`7GZ#{FoS! zSlO8P11j+sAO`*i79?gQBo;>4c<*czt1O5Wo?^f6d+*)7ci%-OgwUyel156d6GE(E zt4F~T7FLmD`Fk{NXU=xhZ?7jj6c5~JUeXRUD--&Q;YRr zz*SH{^Iiu2w8jxaO(1KrlRQp#k#p^AY=gJxJOxjh(M62&!j(n&Js7v+hN) zLb0a~82DAeeIs)qg^R`9jkfcI3-f^t7{_s&%r}jUBnk6#7D>A1uDdPQqgSXC zOfuSTd7ej|kk6X1;@ux~S+2TZ->u>32CREt??hooV+H7KcFIVn0+3zv`u%>#J5URW szl*>O-oBQ20T=7D+~t|1J@_mH5;TEBm&b>?GeMZf)xV|iCq7Z~6JZp_fB*mh literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/19/0001.m4s b/tests/contents/DASH_DRM_static_SegmentTemplate/media/19/0001.m4s new file mode 100644 index 0000000000000000000000000000000000000000..d9b943dd01cf0707bcec00546d9cba27ff36c279 GIT binary patch literal 437 zcmaJ*u};G<5OvDL)FLr3Fj!__sp3FELQ#^L4`Atri=D&}+rhq)^e^~?ejcB}xhaf2 zo$tMSdhcXH$W?${Z-Q(IRzwr@h;$jWj2J5+hnFq`3x7V1=JEIdYG5sw-#B<$A|w)E{qgV0MOBNHk7Od=yT48 zVMvEn>U_g(-~gs$(UEt;HYGc78*=oXNZj<-hchK1QipyX~!4RM2S5Z+esRImpH4<2&Ri|}-zvg*NO8p>pc5YkYdIx;{!^aNv^U=|vr}%mzms=zyua*-t#2M5JWr+ zD0=ewweg}3#%>iS4gG0Y@fj)Nbv~$*zqpCg1<%+6`Zj09n`H5Agxmn3b(Mv$>Z5Rl z+89p@L3i~E!kHkygNd%wnDt)EEfap7s$91@KB&h?W5{vBC>fm2&u8IVU0wOm3D*IQ z)Ihb#sS6cWeiML4{m6;^LlzIzZvL?v^3KE9!|axXa!iD*(?VOLf~lA?^#iS`h>Q|H zOK>B^2NI-SX{m2XNPou{0Hl4}&hy;LyH+B6JC?R;6ECB+C4eko#pSrhm$CL!jVp*b P_*X#9Qme5P~kyC>Z<-_QImXXZC^ z=A_QKrZ^est;LltXP4SqTWb{wR9ETE_^-Vt%iHT*oT&BmbeJsFI=U*U zi(-l&CVj2yZ%ovma}B1IOTSXmQAw=z*P^(yw<1H_UhTA|(SC+e!_bnkKZmcqt#PRN zmrcpY?oX_LZoIa$*IMtZu(Elp9f(`2gVsiE?cHtG*01uM(*JweQ|8-)do<$AgEb(# z3MZVqY&7Xx-|gI0>0n*)v~$<}lS>_}iEgeB-?__8&qU`<*Z)#CcaeVKBwG323p&37 ztvvJ4md9N{EB0*A(QLFHRLbZw+VZ&X(aQ51dRiX$Lx^?fgD$*}o?-b1(3)=ntvn}# zzdI9j{xn*1*@o5_j-yRRD>HflT64K4=)#p~<+&cMJQHZ;iG!Y+ukt)fzv)>!(6*7I z#c1Uj4YASApq(GT@{G}M+I^SNPob?oZX;Ut@oQn-?pVhEV$e$uWcJTjAy4G%pggzJ zZ)u|CAvS8u=n7i%T8P%X&Y>0Cn9+Xjnpc^A>05%%EkUd1ThW#?T8p-v?z5nyRcO`6 z&&71Ufqv~Dzt)=9kxcCUAvPMy=-p`f`!Q=gzUCUwiy_Z{-iyaV9`||B(Z^`TzLx3t z^;CXeXZc)%k80Q(boQN%{JN`#bMYyd_Wd?~_ic!s+8e6XIQ`T2&%GIcOJ$z*dsGX0 z#+*1kB$dD1^84TAU-ymQX$Q4EJNJj~3mm<7S(HY!7;c8IfS0B0F2SmR`MXKD1wIGg z4IhGaYMFn&8P?mY=QY8ajq;s`wG+fY!S~@`g0-6zUxZh~E8#W7e+`%6GjJ>H^J~}Y zdEa2yYKzapdV`D$hvD{=qXh1NeLXvg{}Ou_{3BdVIe!Y)4%d8!;dS_b1V4bi1=cFd ze;(WoFN1qhE;PW}netx*1NM{fBk*QeZ;s;o;Z4N*{h(7__7AWR!ISXjl$Y*@bsCs|bOL@H z_Vs-Nz7_kE@Ex#D9L2AOpN7}KTj2TdGby{D;bH7E;b&oA&*xyjzjfm3c{k!el5*}Q zSYK1wx4_%sRq*pEyW_CFeDYrb>nmsMd_6`}&gZeefWP05yWoS^b?Pc#JFJshya9d* z-U;u4{e1N`mA_x_m*E}wzmoFQ`S2?Cjo5W^Yy6+W#$$n{qSu3 z-+H@0dG{7}zdzrGug3qtH2Xo~C$PVRy$HXHeGEPX`}~LTUyfa0PtE@ld=$I= M8*t%Nto+~(e=xdMNtd%QlX<>C?rEu+fqaa1R zdgWrFeYv?(Y&At8bd(kn3r+OGD2g!%!r0^J;p@)}SsDQLJ;Gp_*Mxg`1X6t*m&U>2 z*hXs3kGLW!a{}%pN%AB)If)1tf@&CxO;SRUZU?45)(|r-4UeJ8qukWeD1&-;#Mp1O zbT$y**BhqJQFE-F!5VU-xx)$j?x1o2moU-pV*zRfz`Wp^j*%CE(uNt;w$oMY*$^9q z8VmW@@7)<3K`uvg?tZ2(T=jTB{V*2$oSM9Ew+r?4a=pqL$VV*gdDZFgz_ifX4*gCG zle2MX))?RQJWsVemx6N0NT2D+fTgh|m2L(|pHo_yD=_3|MaQM9K{j5~5OyE`LKQ+kr<6Mh$VcK4v za@ZlS5Jd8CA^9`%j2!*>0mt$89Vzd!cdXMG!`T3XG<$KDbs7>OzB`B3zrez2~4N zV6?7!B_!o_)i}9FDfI`wo;Iq}cEgII#PhJui=tpuS$Vb|^QUChFF{4Rvs9br`)jL* V6@BZS$t&*bisLqX(`p<5^)InOan=9; literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/27/init.mp4 b/tests/contents/DASH_DRM_static_SegmentTemplate/media/27/init.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..bb1553584ef3c09350ed52d6166e4b23b7ae8af3 GIT binary patch literal 716 zcma)3y-ve05O#{hREZ7@3=A1yK_o$~C{Te^#D67FB_zbalGM%*jg!j0CcqQ$2D}9` zBk#Z?u<#h1ourM*!pYWs-*>+A>5dSx=EL(OlIboX#895PGDJM^1!Gq-y=F9W&GRT` z=1`<`I%3q!BM8ll;qi&NV|VSgb$WJZ36^#DJ65pgwGVucS=^Pt1Qu#M@-)p5#5@Zr zdh+$X`KB($?iDA7J{nehPKtP)_v_>@ZlH9@GxmhO#aZzuS^gLzH$iA!W#O;-DqNu! z#wUfKyLt!Vj*&mWSl2P;z1MQfgqc&7>$brA^%yY*94CyD$?4*JmVVUJn{3^kV z5g$sBdZnelEnzYnUkEViIZmGEcHXg55jcr-RGau1ttA0u0V^&?HNJ|qUus-I%o(LM MZH2{2pg5D{7hoWGqyPW_ literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/3-80399bf5/0001.m4s b/tests/contents/DASH_DRM_static_SegmentTemplate/media/3-80399bf5/0001.m4s new file mode 100644 index 0000000000000000000000000000000000000000..da80d3a5e45160d28f2908cc3067dc98c6b83666 GIT binary patch literal 3099 zcmcJQZ)jCz9LJw?x~rRmwb&RlN-GO8_NEsRnWRyWP%m1VX`0=;-QDeGcbmIcb5?U% znOe=MQ@1qJWoG{@D2NDRAVI#V-h@E~Qb-_#A+AV>`h9mkXV1glcVIi;&-4BLe$Vfm z`<&--&NWx6{k`Q%q08B&d%05DXtJeJD(J2&vcKjjmHdlbG`H1cZg`4ozb*Il6iwEb zi(Q2zL^-veRr~T9Z>(xOc3IP^rN8=Wu~4;pdbLzKdkZou9i>jYHQJwHlpVbDz~qh_ z7B>zq{bis!G&*79*H+p(d+naaDlKQxy7yP|rA>B^+B>@2?LKwon(F`G%VxRWChk$k z!Nh9Fu9{QMWk#xf>${z+OPY1Hr|lhQ<0Qat(ZE#u&Ru4D4qCC7&{x>_LqW`KXbXut zy>{o(YNf{OOg&n4=A&&c_ZM1qn!R?1(5lnqb!HEGmW|(n&X{gMtIkTV-HTpN$LqO1 zXI%Q6*U?p8XZNGkb2^uLUdy=V>J9WOJ~zsFotceRpL6|q)aP}>YiP}NFIvCFBDCgu z+-r9dt@m>z&VmxSMg!^^T8; z-azZQ-Vb6X(CX*=KrcY6p9ce-KBMYn+X)b$$-&q%~FNLtoR41a*E2bntscHwJaS_PNo&Ub~AyZm@o$cNw?mn*Ij$ zTnuyzvlw-wgzAYKLc zB%Eo4wTsHX23`l3VXbuY8@9m}{JY^QyZ~MguYk3}E#G|!KaGD7-U#o9wMrHLBfJTJ z7}l<-ekb5(iQfP}hu;P33sAk^;m!Dq;6Zo}{CvVo?t-@@9G772GMaxJ)+r|*ge4Xs-?+17kPUjngkK@0du-ggi6jAcGw;3G+0PsyB-_&4U0;Rg z2_Y7G<|q&1$(H0C{0;QiRk+TX@6fA$z-d*6Y}4h8-uJafuT@KBI$u~WEaop?Y2+o3 zmM<>l+ZURPE3GEa3rA@#p-^gDgkc0hAR>=}Cm+9``-_7R`!-@?nb(8^JOqh8ii@M* zXlw&@+7FpRDSe#WjN^DGJ~0Le79tf9@hwyYPqstG-&O%rEe#K$$-~^lk|+&&cgWZ; zwRAQB-_aYU&V)JEUT+P!;oSa&19wLwRqSa2 z4FZh{Hgdgty$Rs5IH&#|zvPm~0_=ye$Yy7X` zElAEp!mKg6>sgj)GfZ;KK|_6NQwB7Ntw`x+0Q6al_-mkz)-*)w7TiJw zLL6w;u~MT<%ONb-PM9O#I0h=+brf{U-i5IPc-4vAvc*U){z_;Yd{2%QKdt_Vf91&B zZ@6$=J4NQ7WfvaZwaB>lv;6wQtAG3ZSiY)~<4v`saG=lva2e%#0!0`0-`{u+I3Fmg zkuzpZ?ykJ}^W;o1vs?T2P(OYC4(Lo%OHJ&11v2;fF*#`!fji}ff$X@!7O~9(R9b1% Yc?gXGR{gRDX8=FwYXb*4Za4t{0X0RhLI3~& literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/4-90953e09/0001.m4s b/tests/contents/DASH_DRM_static_SegmentTemplate/media/4-90953e09/0001.m4s new file mode 100644 index 0000000000000000000000000000000000000000..09fb716ba717f5e19d753bf49020d24ad49533b2 GIT binary patch literal 3099 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 avGjae;dkJ4{^~nR{pJ1<++4`jm;M8GY6=4Y literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/8-80399bf5/init.mp4 b/tests/contents/DASH_DRM_static_SegmentTemplate/media/8-80399bf5/init.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..46fb1628ed0e794d43e55ce90b272dd4faf5d925 GIT binary patch literal 1059 zcmZuv&ubGw6rR}?3>YxP94fRhDG|IRG|?vZ)YVpvq8Jd1iXJvQ6L;xOHtbB+A4ti` zLl5Gy(o3%e!JFVkEchRI^C%uXdht?}_}*-4w$=|a@4fGP@9oRHA%x8I^wUA0qD4Xo zMax~~gP-fgLV&%F_L_=r3Ld!ZN)QUxi6cJr1ZR%}?X#<$iz{rQ)~q$EtC!cRu}GR1 z&Q%|^x{ak?S5&2|w1}aR{a!{<0!}CspM%Z7{%!&aBV^da0SJdgLY!>wQQrcpEfets zY(a|2H%~OaK+JS(c&x&%)6S_^0DXWW02pgq$L>1#5A?d}W25l-+nc+oj?sTG?V5`J z#161HBxP_AQW0D$u(Kjm+As%m(HA@Egw`nuTL6toKD|SjV~!MWjj-miJz^jghePLZE*32IFgalnR8}5hUmGUcq`Om;Jz~A@(=Rs_x?U1Cv65@ zPCGPD$74*eF#}d*ljYZ&mQx0`c8QwWjI?viqUGkjt=)=zJ1&wUPGaMWeE2ap55e(O zx);CeI`FZMN^c|Ii>2#}qz+t3dA<-%Gve9lZoBI05&v5HAvss bnOz-WvpMdXVl(~?H|Z_5YUf+E`a=B=5{RL8 literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/9-80399bf5/0001.m4s b/tests/contents/DASH_DRM_static_SegmentTemplate/media/9-80399bf5/0001.m4s new file mode 100644 index 0000000000000000000000000000000000000000..3f768ce9ec87bb970b05c01693bacce53ba2c18a GIT binary patch literal 3113 zcmcJRdu&ui6vofo-L0gJvH=<}VB&+sMk@w_q67>vG5+BnQhA7IWlOh@1-7ldmq&}% z^)1L-lxjhNihzhbj0h=&KvM$=0b`;uMhSujHQERYMzM)=?tGJT=>OiNd(ZFtzH?`G z?qs$^G%So-n(|?`p6tcQG( zrt`J+S>$Y{q$g^wiuH)~Aa<-y>8LgvA;-7!u&yb~Mp%=pv$rAk&!QPnxVPid(wim? zDNH%r7OiMMV)YT>?7Aj<_gQYs*fif;!m3=Wy_@QqhH86{uS{9`|Gn%eH`;+4dB$pB zo{+s#Jw(a1QSMLg^)<(|J{YDw(v~PSnlg4j0`tOWw4qIw2X_tn|M` zPwM>3lDXHa<1XPRM3 zFR1!S={4<2->38|O21Fl6IJFprB^HcF42QCQkzg^Zc}8h@6@pRtnoo9py0{ykFmW;LqXb!H2;O=)WD@=s0x(+yp-behU5HgZUif`R@UTjt5==N9ZpF&j-%~ zF91j2g^sBYya>D=+=BcCFrTG%{G{(+48H*XY4rR3#lJy3-(TUkISvBwv;F!D;4FMT zr)>Y2ecKj@QaCh3;AqS^dChN3FH6( literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/9-80399bf5/init.mp4 b/tests/contents/DASH_DRM_static_SegmentTemplate/media/9-80399bf5/init.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..8d56b697b6c08b3d48e31845abb1ed2f48d26771 GIT binary patch literal 1059 zcmZuv&ubGw6rR~d3>YwIC>1JfN(3((nrIVy>T0V-Q4EL$iyk(aS$FA9HtbB+A4u7g zhaSXZrI%g{f;Yj7Snxma>Pb9!^x~x`@x9r^Y^@*czW2WGy|-`Y4IyOKQ%?thj1~zY z6fJY54}QUmIR|?a?F|{-<}7fnYeC4ZP8_jek2C9WpnU6k=kkiRP;1s2_UhF&JLXCA z(gpibtJ_%ey4)77R6K@8=6exE2{@rhdQ0I^_dem9*ggyK z&^3~P;U@oL4dSTn_F1SGLqCY1?}1uQgl?K2v&u4Uj>Q~v5U3Z2acE^e-IS^u0^N{G zP8JI}be{KnxNts`n`SttYfRK}> z1zpZKv`9xIOfWG6R%Mdq*IR~D0kw98>e`&Nd(5Cg^Zxc;RlFU|q%$c@V&aW__^~h# zCC69ke*CWMz{ff=JB^|j3)kmK9k{aW`2sBI!S6yk;yiExSW6+NK?~{9&d;riQ%>)G z-Bd5P_kk`+rB|M%=va>PHC2WaeKrxt7HWD?j_VGYav@$9Tw9bX`Srt@fKUPi>+FHq5cQv0i<65 literal 0 HcmV?d00001 diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/media/encrypted_multiple_keys_number.mpd b/tests/contents/DASH_DRM_static_SegmentTemplate/media/encrypted_multiple_keys_number.mpd new file mode 100644 index 00000000000..aa84cec211b --- /dev/null +++ b/tests/contents/DASH_DRM_static_SegmentTemplate/media/encrypted_multiple_keys_number.mpd @@ -0,0 +1,127 @@ + + + + + + + + + AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgA5AFoAcwA1AGcAQwBHAEsARgBFAEMAQQBVACsASgArAGQASQA2AFkAdwBRAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA== + + xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4AOQBaAHMANQBnAEMARwBLAEYARQBDAEEAVQArAEoAKwBkAEkANgBZAHcAQQA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA= + + + AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQgDmb9YohQBSAU+J+dI6YwQ== + + + + + + + + + + + + AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBDAFQANgBWAGsATABKAHMAbwAwAG0AaQBZAEgAcABmADcAKwByAFUAbQBRAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA== + xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4AQwBUADYAVgBrAEwASgBzAG8AMABtAGkAWQBIAHAAZgA3ACsAcgBVAG0AUQA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA= + + + AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQkJU+CWyySaOiYHpf7+rUmQ== + + + + + + + + + + + AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgA5AFoAcwA1AGcAQwBHAEsARgBFAEMAQQBVACsASgArAGQASQA2AFkAdwBBAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA== + xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4AOQBaAHMANQBnAEMARwBLAEYARQBDAEEAVQArAEoAKwBkAEkANgBZAHcAQQA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA= + + + AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQgDmb9YohQBSAU+J+dI6YwA== + + + + + + + + + + + + AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBDAFQANgBWAGsATABKAHMAbwAwAG0AaQBZAEgAcABmADcAKwByAFUAbQBRAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA== + xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4AQwBUADYAVgBrAEwASgBzAG8AMABtAGkAWQBIAHAAZgA3ACsAcgBVAG0AUQA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA= + + + AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQkJU+CWyySaOiYHpf7+rUmQ== + + + + + + + + + + AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBQAHkATgBmAFcASABJAHcAOABVAGEAZgBwAEcAMwBDAEwARwBhAGcARgBBAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA== + xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4AUAB5AE4AZgBXAEgASQB3ADgAVQBhAGYAcABHADMAQwBMAEcAYQBnAEYAQQA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA= + + + AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQWF8jPzByRvGfpG3CLGagFA== + + + + + + + + + + + AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBlAEwAMABpAFEAawBXADgAdgAwAEcAMgBQAG0AKwBCAFQAYwBPAFIAMwB3AD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA== + xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4AZQBMADAAaQBRAGsAVwA4AHYAMABHADIAUABtACsAQgBUAGMATwBSADMAdwA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA= + + + AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQQiK9eLxFQb+2Pm+BTcOR3w== + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/contents/DASH_DRM_static_SegmentTemplate/urls.mjs b/tests/contents/DASH_DRM_static_SegmentTemplate/urls.mjs new file mode 100644 index 00000000000..42482fc073c --- /dev/null +++ b/tests/contents/DASH_DRM_static_SegmentTemplate/urls.mjs @@ -0,0 +1,138 @@ +/* eslint-env node */ + +import * as path from "path"; +import patchSegmentWithTimeOffset from "../utils/patchSegmentWithTimeOffset.mjs"; +import { fileURLToPath } from "url"; + +const currentDirectory = path.dirname(fileURLToPath(import.meta.url)); + +const baseURL = "/DASH_DRM_static_SegmentTemplate/media/"; + +const segments = []; + +// video +[ + "8-80399bf5", + "9-80399bf5", + "10-80399bf5", + "11-90953e09", + "12-90953e09", + "1-80399bf5", + "2-80399bf5", + "3-80399bf5", + "4-90953e09", + "5-90953e09", +].forEach((dir) => { + segments.push({ + url: baseURL + dir + "/init.mp4", + path: path.join(currentDirectory, `./media/${dir}/init.mp4`), + content: "video/mp4", + }); + const duration = [ + "1-80399bf5", + "2-80399bf5", + "3-80399bf5", + "4-90953e09", + "5-90953e09", + ].includes(dir) + ? 96 + : 4799983; + for (let i = 1; i <= 184; i++) { + const nb = String(i).padStart(4, "0"); + segments.push({ + url: baseURL + dir + `/${nb}.m4s`, + path: path.join(currentDirectory, `./media/${dir}/0001.m4s`), + postProcess: (buffer) => patchMp4(buffer, (i - 1) * duration), + content: "video/mp4", + }); + } +}); + +[ + // audio + "15-585f233f", + "16-4222bd78", + "17", +].forEach((dir) => { + segments.push({ + url: baseURL + dir + "/init.mp4", + path: path.join(currentDirectory, `./media/${dir}/init.mp4`), + content: "audio/mp4", + }); + const duration = 95232; + for (let i = 1; i <= 185; i++) { + const nb = String(i).padStart(4, "0"); + segments.push({ + url: baseURL + dir + `/${nb}.m4s`, + path: path.join(currentDirectory, `./media/${dir}/0001.m4s`), + postProcess: (buffer) => patchMp4(buffer, (i - 1) * duration), + content: "audio/mp4", + }); + } +}); + +[ + // subtitles + "19", + "27", +].forEach((dir) => { + segments.push({ + url: baseURL + dir + "/init.mp4", + path: path.join(currentDirectory, `./media/${dir}/init.mp4`), + content: "application/mp4", + }); + const duration = 4000; + for (let i = 1; i <= 184; i++) { + const nb = String(i).padStart(4, "0"); + segments.push({ + url: baseURL + dir + `/${nb}.m4s`, + path: path.join(currentDirectory, `./media/${dir}/0001.m4s`), + postProcess: (buffer) => patchMp4(buffer, (i - 1) * duration), + content: "application/mp4", + }); + } +}); + +export default [ + // Manifest + { + url: baseURL + "encrypted_multiple_keys_number.mpd", + path: path.join(currentDirectory, "./media/encrypted_multiple_keys_number.mpd"), + contentType: "application/dash+xml", + }, + ...segments, +]; + +/** + * Translate groups of 4 big-endian bytes to Integer. + * @param {Uint8Array} bytes + * @param {Number} offset - The offset (from the start of the given array) + * @returns {Number} + */ +function be4toi(bytes, offset) { + return ( + bytes[offset + 0] * 0x1000000 + + bytes[offset + 1] * 0x0010000 + + bytes[offset + 2] * 0x0000100 + + bytes[offset + 3] + ); +} + +function patchMp4(buffer, startTime) { + const bufferu8 = new Uint8Array(buffer); + let ret = bufferu8; + + // If it just finishes with "mdat", fill in the rest with 0 + if ( + bufferu8[bufferu8.length - 4] === 0x6d && + bufferu8[bufferu8.length - 3] === 0x64 && + bufferu8[bufferu8.length - 2] === 0x61 && + bufferu8[bufferu8.length - 1] === 0x74 + ) { + const mdatLen = be4toi(bufferu8, bufferu8.length - 8); + const remainingLength = mdatLen - 8; + ret = new Uint8Array(bufferu8.length + remainingLength); + ret.set(bufferu8, 0); + } + return patchSegmentWithTimeOffset(ret, startTime).buffer; +} diff --git a/tests/contents/urls.mjs b/tests/contents/urls.mjs index 1d6a684ec8d..ffcfd06f908 100644 --- a/tests/contents/urls.mjs +++ b/tests/contents/urls.mjs @@ -13,6 +13,7 @@ import urls8 from "./directfile_webm/urls.mjs"; import urls9 from "./DASH_dynamic_SegmentTemplate_Multi_Periods/urls.mjs"; import urls10 from "./DASH_static_broken_cenc_in_MPD/urls.mjs"; import urls11 from "./DASH_static_number_based_SegmentTimeline/urls.mjs"; +import urls12 from "./DASH_DRM_static_SegmentTemplate/urls.mjs"; export default [ ...urls1, @@ -26,4 +27,5 @@ export default [ ...urls9, ...urls10, ...urls11, + ...urls12, ]; diff --git a/tests/integration/scenarios/drm_base.js b/tests/integration/scenarios/drm_base.js new file mode 100644 index 00000000000..eb39c424a81 --- /dev/null +++ b/tests/integration/scenarios/drm_base.js @@ -0,0 +1,655 @@ +import { describe, beforeEach, afterEach, it, expect } from "vitest"; +import { manifestInfos } from "../../contents/DASH_DRM_static_SegmentTemplate"; +import DummyMediaElement from "../../../dist/es2017/experimental/tools/DummyMediaElement"; +import RxPlayer from "../../../dist/es2017"; +import waitForPlayerState, { + waitForLoadedStateAfterLoadVideo, +} from "../../utils/waitForPlayerState"; +import { lockLowestBitrates } from "../../utils/bitrates"; +import sleep from "../../utils/sleep"; + +const textDecoder = new TextDecoder(); +const textEncoder = new TextEncoder(); + +describe("DRM: Basic use cases", function () { + const { url, transport } = manifestInfos; + let player; + const oldMediaSourceSupported = MediaSource.isTypeSupported; + + let dummy; + beforeEach(() => { + MediaSource.isTypeSupported = () => true; + dummy = new DummyMediaElement(); + player = new RxPlayer({ videoElement: dummy }); + player.setWantedBufferAhead(10); + }); + + afterEach(async () => { + MediaSource.isTypeSupported = oldMediaSourceSupported; + player.dispose(); + }); + + it("should trigger error if no key system option is provided", async function () { + lockLowestBitrates(player); + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + }); + await waitForPlayerState(player, "STOPPED", ["LOADING"]); + const error = player.getError(); + expect(error).not.toBeNull(); + expect(error.code).to.equal("MEDIA_IS_ENCRYPTED_ERROR"); + expect(error.name).to.equal("EncryptedMediaError"); + expect(error.type).to.equal("ENCRYPTED_MEDIA_ERROR"); + }); + + it("should load the content if licenses are returned", async function () { + lockLowestBitrates(player); + const expectedKeyIds = [ + "80399bf58a2140148053e27e748e98c1", + "585f233f307246f19fa46dc22c66a014", + ]; + const askedKeyIds = []; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + getLicense: generateGetLicense({ + expectedKeyIds, + askedKeyIds, + }), + }, + ], + }); + await waitForLoadedStateAfterLoadVideo(player); + expect(player.getVideoRepresentation().id).toEqual("8-80399bf5"); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + expect(player.getError()).toBeNull(); + expect(askedKeyIds.length).toEqual(expectedKeyIds.length); + + player.stop(); + await sleep(10); + expect(dummy.mediaKeys.sessions).toHaveLength(2); + }); + + it("should close sessions after stop if `closeSessionsOnStop` is set", async function () { + lockLowestBitrates(player); + const expectedKeyIds = [ + "80399bf58a2140148053e27e748e98c1", + "585f233f307246f19fa46dc22c66a014", + ]; + const askedKeyIds = []; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + getLicense: generateGetLicense({ + expectedKeyIds, + askedKeyIds, + }), + closeSessionsOnStop: true, + }, + ], + }); + await waitForLoadedStateAfterLoadVideo(player); + expect(player.getVideoRepresentation().id).toEqual("8-80399bf5"); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + expect(player.getError()).toBeNull(); + expect(askedKeyIds.length).toEqual(expectedKeyIds.length); + expect(dummy.mediaKeys.sessions).toHaveLength(2); + + player.stop(); + await sleep(10); + expect(dummy.mediaKeys.sessions).toHaveLength(0); + }); + + it("should trigger specific error if the license request fails", async function () { + lockLowestBitrates(player); + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + getLicense() { + throw new Error("I do not work"); + }, + }, + ], + }); + await waitForPlayerState(player, "STOPPED", ["LOADING"]); + const error = player.getError(); + expect(error).not.toBeNull(); + expect(error.code).to.equal("KEY_LOAD_ERROR"); + expect(error.name).to.equal("EncryptedMediaError"); + expect(error.type).to.equal("ENCRYPTED_MEDIA_ERROR"); + }); + + it("should fallback from license request error with a `fallbackOnLastTry` toggle on", async function () { + const failingKeyIds = ["90953e096cb249a3a2607a5fefead499"]; + const expectedKeyIds = [ + "90953e096cb249a3a2607a5fefead499", + "585f233f307246f19fa46dc22c66a014", + "80399bf58a2140148053e27e748e98c1", + ]; + const askedKeyIds = []; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + getLicense: generateGetLicense({ + expectedKeyIds, + askedKeyIds, + failingKeyIds, + }), + }, + ], + }); + let brokenVideoLock = 0; + player.addEventListener("newAvailablePeriods", (p) => { + player.lockVideoRepresentations({ + periodId: p[0].id, + representations: ["11-90953e09", "12-90953e09"], + }); + }); + player.addEventListener("brokenRepresentationsLock", (lock) => { + if (lock.trackType === "video") { + brokenVideoLock++; + } + }); + await waitForLoadedStateAfterLoadVideo(player); + expect(brokenVideoLock).toEqual(1); + expect(["8-80399bf5", "9-80399bf5", "10-80399bf5"]).toContain( + player.getVideoRepresentation().id, + ); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + expect(player.getError()).toBeNull(); + }); + + it('should fallback from an `"output-restricted"` MediaKeyStatus under the corresponding option', async function () { + const highPolicyLevelKeyIds = ["90953e096cb249a3a2607a5fefead499"]; + const expectedKeyIds = [ + "90953e096cb249a3a2607a5fefead499", + "585f233f307246f19fa46dc22c66a014", + "80399bf58a2140148053e27e748e98c1", + ]; + const askedKeyIds = []; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + onKeyOutputRestricted: "fallback", + getLicense: generateGetLicense({ + expectedKeyIds, + askedKeyIds, + highPolicyLevelKeyIds, + }), + }, + ], + }); + let brokenVideoLock = 0; + player.addEventListener("newAvailablePeriods", (p) => { + player.lockVideoRepresentations({ + periodId: p[0].id, + representations: ["11-90953e09", "12-90953e09"], + }); + }); + player.addEventListener("brokenRepresentationsLock", (lock) => { + if (lock.trackType === "video") { + brokenVideoLock++; + } + }); + await waitForLoadedStateAfterLoadVideo(player); + expect(brokenVideoLock).toEqual(1); + expect(["8-80399bf5", "9-80399bf5", "10-80399bf5"]).toContain( + player.getVideoRepresentation().id, + ); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + expect(player.getError()).toBeNull(); + }); + + it('should continue from an `"output-restricted"` MediaKeyStatus under the corresponding option', async function () { + const highPolicyLevelKeyIds = ["90953e096cb249a3a2607a5fefead499"]; + const expectedKeyIds = [ + "90953e096cb249a3a2607a5fefead499", + "585f233f307246f19fa46dc22c66a014", + "80399bf58a2140148053e27e748e98c1", + ]; + const askedKeyIds = []; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + onKeyOutputRestricted: "continue", + getLicense: generateGetLicense({ + expectedKeyIds, + askedKeyIds, + highPolicyLevelKeyIds, + }), + }, + ], + }); + + let brokenVideoLock = 0; + player.addEventListener("newAvailablePeriods", (p) => { + player.lockVideoRepresentations({ + periodId: p[0].id, + representations: ["11-90953e09", "12-90953e09"], + }); + }); + player.addEventListener("brokenRepresentationsLock", (lock) => { + if (lock.trackType === "video") { + brokenVideoLock++; + } + }); + + await sleep(150); + expect(player.getPlayerState()).toEqual("LOADING"); + expect(brokenVideoLock).toEqual(0); + expect(["11-90953e09", "12-90953e09"]).toContain(player.getVideoRepresentation().id); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + expect(player.getError()).toBeNull(); + }); + + it('should fail from an `"output-restricted"` MediaKeyStatus under the corresponding option', async function () { + player.setWantedBufferAhead(10); + const highPolicyLevelKeyIds = ["90953e096cb249a3a2607a5fefead499"]; + const expectedKeyIds = [ + "90953e096cb249a3a2607a5fefead499", + "585f233f307246f19fa46dc22c66a014", + "80399bf58a2140148053e27e748e98c1", + ]; + const askedKeyIds = []; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + onKeyOutputRestricted: "error", + getLicense: generateGetLicense({ + expectedKeyIds, + askedKeyIds, + highPolicyLevelKeyIds, + }), + }, + ], + }); + let brokenVideoLock = 0; + player.addEventListener("newAvailablePeriods", (p) => { + player.lockVideoRepresentations({ + periodId: p[0].id, + representations: ["11-90953e09", "12-90953e09"], + }); + }); + player.addEventListener("brokenRepresentationsLock", (lock) => { + if (lock.trackType === "video") { + brokenVideoLock++; + } + }); + await waitForPlayerState(player, "STOPPED", ["LOADING"]); + const error = player.getError(); + expect(error).not.toBeNull(); + expect(error.code).to.equal("KEY_STATUS_CHANGE_ERROR"); + expect(error.name).to.equal("EncryptedMediaError"); + expect(error.type).to.equal("ENCRYPTED_MEDIA_ERROR"); + expect(brokenVideoLock).toEqual(0); + }); + + it('should fallback from an `"output-restricted"` MediaKeyStatus happening during playback under the corresponding option', async function () { + const mediumPolicyLevelKeyIds = ["90953e096cb249a3a2607a5fefead499"]; + const expectedKeyIds = [ + "90953e096cb249a3a2607a5fefead499", + "585f233f307246f19fa46dc22c66a014", + "80399bf58a2140148053e27e748e98c1", + ]; + const askedKeyIds = []; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + onKeyOutputRestricted: "fallback", + getLicense: generateGetLicense({ + expectedKeyIds, + askedKeyIds, + mediumPolicyLevelKeyIds, + }), + }, + ], + }); + let brokenVideoLock = 0; + player.addEventListener("newAvailablePeriods", (p) => { + player.lockVideoRepresentations({ + periodId: p[0].id, + representations: ["11-90953e09", "12-90953e09"], + }); + }); + player.addEventListener("brokenRepresentationsLock", (lock) => { + if (lock.trackType === "video") { + brokenVideoLock++; + } + }); + + await waitForLoadedStateAfterLoadVideo(player); + expect(brokenVideoLock).toEqual(0); + expect(["11-90953e09", "12-90953e09"]).toContain(player.getVideoRepresentation().id); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + + await sleep(50); + dummy.mediaKeys.sessions.forEach((s) => { + s.updatePolicyLevel(10); + }); + await waitForPlayerState(player, "PAUSED", ["PLAYING", "RELOADING"]); + expect(brokenVideoLock).toEqual(1); + expect(["8-80399bf5", "9-80399bf5", "10-80399bf5"]).toContain( + player.getVideoRepresentation().id, + ); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + expect(player.getError()).toBeNull(); + }); + + it('should fail from an `"output-restricted"` MediaKeyStatus happening during playback under the corresponding option', async function () { + player.setWantedBufferAhead(10); + const mediumPolicyLevelKeyIds = ["90953e096cb249a3a2607a5fefead499"]; + const expectedKeyIds = [ + "90953e096cb249a3a2607a5fefead499", + "585f233f307246f19fa46dc22c66a014", + "80399bf58a2140148053e27e748e98c1", + ]; + const askedKeyIds = []; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + onKeyOutputRestricted: "error", + getLicense: generateGetLicense({ + expectedKeyIds, + askedKeyIds, + mediumPolicyLevelKeyIds, + }), + }, + ], + }); + let brokenVideoLock = 0; + player.addEventListener("newAvailablePeriods", (p) => { + player.lockVideoRepresentations({ + periodId: p[0].id, + representations: ["11-90953e09", "12-90953e09"], + }); + }); + player.addEventListener("brokenRepresentationsLock", (lock) => { + if (lock.trackType === "video") { + brokenVideoLock++; + } + }); + + await waitForLoadedStateAfterLoadVideo(player); + expect(brokenVideoLock).toEqual(0); + expect(["11-90953e09", "12-90953e09"]).toContain(player.getVideoRepresentation().id); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + + await sleep(50); + dummy.mediaKeys.sessions.forEach((s) => { + s.updatePolicyLevel(10); + }); + await waitForPlayerState(player, "STOPPED", ["LOADING"]); + const error = player.getError(); + expect(error).not.toBeNull(); + expect(error.code).to.equal("KEY_STATUS_CHANGE_ERROR"); + expect(error.name).to.equal("EncryptedMediaError"); + expect(error.type).to.equal("ENCRYPTED_MEDIA_ERROR"); + expect(brokenVideoLock).toEqual(0); + }); + + it("should re-allow a Representation re-becoming decipherable", async function () { + const mediumPolicyLevelKeyIds = ["90953e096cb249a3a2607a5fefead499"]; + const expectedKeyIds = [ + "90953e096cb249a3a2607a5fefead499", + "585f233f307246f19fa46dc22c66a014", + "80399bf58a2140148053e27e748e98c1", + ]; + const askedKeyIds = []; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + onKeyOutputRestricted: "fallback", + getLicense: generateGetLicense({ + expectedKeyIds, + askedKeyIds, + mediumPolicyLevelKeyIds, + }), + }, + ], + }); + let brokenVideoLock = 0; + player.addEventListener("newAvailablePeriods", (p) => { + player.lockVideoRepresentations({ + periodId: p[0].id, + representations: ["11-90953e09", "12-90953e09"], + }); + }); + player.addEventListener("brokenRepresentationsLock", (lock) => { + if (lock.trackType === "video") { + brokenVideoLock++; + } + }); + + await waitForLoadedStateAfterLoadVideo(player); + expect(brokenVideoLock).toEqual(0); + expect(["11-90953e09", "12-90953e09"]).toContain(player.getVideoRepresentation().id); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + + await sleep(50); + dummy.mediaKeys.sessions.forEach((s) => { + s.updatePolicyLevel(10); + }); + await waitForPlayerState(player, "PAUSED", ["PLAYING", "RELOADING"]); + expect(brokenVideoLock).toEqual(1); + expect(["8-80399bf5", "9-80399bf5", "10-80399bf5"]).toContain( + player.getVideoRepresentation().id, + ); + expect(player.getVideoTrack().representations.map((r) => r.id)).not.toContain( + "12-90953e09", + ); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + expect(player.getError()).toBeNull(); + + dummy.mediaKeys.sessions.forEach((s) => { + s.updatePolicyLevel(100); + }); + await sleep(10); + expect(player.getVideoTrack().representations.map((r) => r.id)).toContain( + "12-90953e09", + ); + player.lockVideoRepresentations(["12-90953e09"]); + expect(player.getVideoRepresentation().id).toEqual("12-90953e09"); + }); + + it('should change track if all Representation from the current one are `"output-restricted"` with the corresponding option', async function () { + const mediumPolicyLevelKeyIds = [ + "90953e096cb249a3a2607a5fefead499", + "80399bf58a2140148053e27e748e98c1", + ]; + const expectedKeyIds = [ + "90953e096cb249a3a2607a5fefead499", + "585f233f307246f19fa46dc22c66a014", + "80399bf58a2140148053e27e748e98c1", + "80399bf58a2140148053e27e748e98c0", + ]; + const askedKeyIds = []; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + onKeyOutputRestricted: "fallback", + getLicense: generateGetLicense({ + expectedKeyIds, + askedKeyIds, + mediumPolicyLevelKeyIds, + }), + }, + ], + }); + let brokenVideoLock = 0; + let videoTrackUpdate = 0; + player.addEventListener("newAvailablePeriods", (p) => { + player.lockVideoRepresentations({ + periodId: p[0].id, + representations: ["11-90953e09", "12-90953e09"], + }); + }); + player.addEventListener("trackUpdate", (obj) => { + if (obj.trackType === "video") { + if (obj.reason === "no-playable-representation") { + videoTrackUpdate++; + } + } + }); + player.addEventListener("brokenRepresentationsLock", (lock) => { + if (lock.trackType === "video") { + brokenVideoLock++; + } + }); + + await waitForLoadedStateAfterLoadVideo(player); + expect(brokenVideoLock).toEqual(0); + expect(["11-90953e09", "12-90953e09"]).toContain(player.getVideoRepresentation().id); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + + await sleep(50); + dummy.mediaKeys.sessions.forEach((s) => { + s.updatePolicyLevel(10); + }); + await waitForPlayerState(player, "PAUSED", ["PLAYING", "RELOADING"]); + + await sleep(50); + expect(brokenVideoLock).toEqual(1); + expect(videoTrackUpdate).toEqual(0); + dummy.mediaKeys.sessions.forEach((s) => { + s.updatePolicyLevel(10); + }); + await waitForPlayerState(player, "PAUSED", ["PLAYING", "RELOADING"]); + + expect(brokenVideoLock).toEqual(1); + expect(videoTrackUpdate).toEqual(1); + expect(["1-80399bf5", "2-80399bf5", "3-80399bf5"]).toContain( + player.getVideoRepresentation().id, + ); + expect(player.getAudioRepresentation().id).toEqual("15-585f233f"); + expect(player.getError()).toBeNull(); + }); + + function generateGetLicense({ + expectedKeyIds, + askedKeyIds, + highPolicyLevelKeyIds, + mediumPolicyLevelKeyIds, + failingKeyIds, + }) { + return function getLicense(challenge, messageType) { + return new Promise((resolve, reject) => { + setTimeout(() => { + try { + expect(messageType).toEqual("license-request"); + const challengeStr = textDecoder.decode(challenge); + const challengeObj = JSON.parse(challengeStr); + const keys = {}; + challengeObj.keyIds.forEach((kid) => { + if (Array.isArray(expectedKeyIds)) { + expect(expectedKeyIds).toContain(kid); + } + if (Array.isArray(askedKeyIds)) { + askedKeyIds.push(kid); + } + if (Array.isArray(failingKeyIds) && failingKeyIds.includes(kid)) { + const error = new Error("Should fallback!"); + error.noRetry = true; + error.fallbackOnLastTry = true; + reject(error); + } + let policyLevel = 0; + if ( + Array.isArray(highPolicyLevelKeyIds) && + highPolicyLevelKeyIds.includes(kid) + ) { + policyLevel = 200; + } else if ( + Array.isArray(mediumPolicyLevelKeyIds) && + mediumPolicyLevelKeyIds.includes(kid) + ) { + policyLevel = 50; + } + keys[kid] = { + policyLevel, + }; + }); + const license = { + type: "license", + persistent: false, + keys, + }; + const licenseU8 = textEncoder.encode(JSON.stringify(license)); + resolve(licenseU8.buffer); + } catch (e) { + reject(e); + } + }, 50); + }); + }; + } +}); diff --git a/tests/integration/scenarios/drm_getLicenceConfig.js b/tests/integration/scenarios/drm_getLicenceConfig.js new file mode 100644 index 00000000000..55443cadfc4 --- /dev/null +++ b/tests/integration/scenarios/drm_getLicenceConfig.js @@ -0,0 +1,224 @@ +import { describe, beforeEach, afterEach, it, expect } from "vitest"; +import { manifestInfos } from "../../contents/DASH_DRM_static_SegmentTemplate"; +import DummyMediaElement from "../../../dist/es2017/experimental/tools/DummyMediaElement"; +import RxPlayer from "../../../dist/es2017"; +import waitForPlayerState from "../../utils/waitForPlayerState"; +import { lockLowestBitrates } from "../../utils/bitrates"; + +const textDecoder = new TextDecoder(); + +describe("DRM: getLicenseConfig", () => { + const { url, transport } = manifestInfos; + let player; + const oldMediaSourceSupported = MediaSource.isTypeSupported; + + let dummy; + beforeEach(() => { + MediaSource.isTypeSupported = () => true; + dummy = new DummyMediaElement(); + player = new RxPlayer({ videoElement: dummy }); + player.setWantedBufferAhead(10); + }); + + afterEach(async () => { + MediaSource.isTypeSupported = oldMediaSourceSupported; + player.dispose(); + }); + + it("should attempt the license request 3 times by default", async function () { + lockLowestBitrates(player); + const expectedKeyIds = [ + "80399bf58a2140148053e27e748e98c1", + "585f233f307246f19fa46dc22c66a014", + ]; + const askedKeyIds = {}; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + getLicense(challenge) { + const challengeStr = textDecoder.decode(challenge); + const challengeObj = JSON.parse(challengeStr); + challengeObj.keyIds.forEach((kid) => { + expect(expectedKeyIds).toContain(kid); + if (askedKeyIds[kid] === undefined) { + askedKeyIds[kid] = 1; + } else { + askedKeyIds[kid]++; + } + throw new Error("A"); + }); + }, + }, + ], + }); + await waitForPlayerState(player, "STOPPED", ["LOADING"]); + expect(askedKeyIds).toHaveProperty(expectedKeyIds[0]); + expect(askedKeyIds).toHaveProperty(expectedKeyIds[1]); + if (askedKeyIds[expectedKeyIds[0]] === 3) { + expect(askedKeyIds[expectedKeyIds[1]]).toEqual(2); + } else if (askedKeyIds[expectedKeyIds[1]] === 3) { + expect(askedKeyIds[expectedKeyIds[0]]).toEqual(2); + } else { + throw new Error("No key has 3 request attempts: " + JSON.stringify(askedKeyIds)); + } + const error = player.getError(); + expect(error).not.toBeNull(); + expect(error.code).to.equal("KEY_LOAD_ERROR"); + expect(error.name).to.equal("EncryptedMediaError"); + expect(error.type).to.equal("ENCRYPTED_MEDIA_ERROR"); + }); + + it("should update the number of attempts with getLicenseConfig", async function () { + lockLowestBitrates(player); + const expectedKeyIds = [ + "80399bf58a2140148053e27e748e98c1", + "585f233f307246f19fa46dc22c66a014", + ]; + const askedKeyIds = {}; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + getLicenseConfig: { + retry: 1, + }, + getLicense(challenge) { + const challengeStr = textDecoder.decode(challenge); + const challengeObj = JSON.parse(challengeStr); + challengeObj.keyIds.forEach((kid) => { + expect(expectedKeyIds).toContain(kid); + if (askedKeyIds[kid] === undefined) { + askedKeyIds[kid] = 1; + } else { + askedKeyIds[kid]++; + } + throw new Error("A"); + }); + }, + }, + ], + }); + await waitForPlayerState(player, "STOPPED", ["LOADING"]); + expect(askedKeyIds).toHaveProperty(expectedKeyIds[0]); + expect(askedKeyIds).toHaveProperty(expectedKeyIds[1]); + if (askedKeyIds[expectedKeyIds[0]] === 2) { + expect(askedKeyIds[expectedKeyIds[1]]).toEqual(1); + } else if (askedKeyIds[expectedKeyIds[1]] === 2) { + expect(askedKeyIds[expectedKeyIds[0]]).toEqual(1); + } else { + throw new Error("No key has 3 request attempts: " + JSON.stringify(askedKeyIds)); + } + const error = player.getError(); + expect(error).not.toBeNull(); + expect(error.code).to.equal("KEY_LOAD_ERROR"); + expect(error.name).to.equal("EncryptedMediaError"); + expect(error.type).to.equal("ENCRYPTED_MEDIA_ERROR"); + }); + + it("should not retry if `noRetry` is set on the error", async function () { + lockLowestBitrates(player); + const expectedKeyIds = [ + "80399bf58a2140148053e27e748e98c1", + "585f233f307246f19fa46dc22c66a014", + ]; + const askedKeyIds = {}; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + getLicenseConfig: { + retry: 1, + }, + getLicense(challenge) { + const challengeStr = textDecoder.decode(challenge); + const challengeObj = JSON.parse(challengeStr); + challengeObj.keyIds.forEach((kid) => { + expect(expectedKeyIds).toContain(kid); + if (askedKeyIds[kid] === undefined) { + askedKeyIds[kid] = 1; + } else { + askedKeyIds[kid]++; + } + const error = new Error("A"); + error.noRetry = true; + throw error; + }); + }, + }, + ], + }); + await waitForPlayerState(player, "STOPPED", ["LOADING"]); + expect(Object.keys(askedKeyIds)).toHaveLength(1); + expect(askedKeyIds[Object.keys(askedKeyIds)[0]]).toEqual(1); + const error = player.getError(); + expect(error).not.toBeNull(); + expect(error.code).to.equal("KEY_LOAD_ERROR"); + expect(error.name).to.equal("EncryptedMediaError"); + expect(error.type).to.equal("ENCRYPTED_MEDIA_ERROR"); + }); + + it("should update a timeout with getLicenseConfig", async function () { + lockLowestBitrates(player); + const expectedKeyIds = [ + "80399bf58a2140148053e27e748e98c1", + "585f233f307246f19fa46dc22c66a014", + ]; + const askedKeyIds = {}; + player.loadVideo({ + url, + transport, + autoPlay: false, + textTrackMode: "html", + textTrackElement: document.createElement("div"), + keySystems: [ + { + type: "com.microsoft.playready", + getLicenseConfig: { + retry: 0, + timeout: 1, + }, + getLicense(challenge) { + return new Promise((resolve) => { + setTimeout(() => { + const challengeStr = textDecoder.decode(challenge); + const challengeObj = JSON.parse(challengeStr); + challengeObj.keyIds.forEach((kid) => { + expect(expectedKeyIds).toContain(kid); + if (askedKeyIds[kid] === undefined) { + askedKeyIds[kid] = 1; + } else { + askedKeyIds[kid]++; + } + }); + resolve({}); + }, 10); + }); + }, + }, + ], + }); + await waitForPlayerState(player, "STOPPED", ["LOADING"]); + expect(askedKeyIds).toEqual({}); + const error = player.getError(); + expect(error).not.toBeNull(); + expect(error.code).to.equal("KEY_LOAD_ERROR"); + expect(error.name).to.equal("EncryptedMediaError"); + expect(error.type).to.equal("ENCRYPTED_MEDIA_ERROR"); + }); +});