EME WTF؟

مقدمه ای بر برنامه های افزودنی رسانه رمزگذاری شده

Encrypted Media Extensions یک API ارائه می‌کند که برنامه‌های کاربردی وب را قادر می‌سازد تا با سیستم‌های حفاظت محتوا تعامل داشته باشند تا امکان پخش صدا و ویدیوی رمزگذاری شده را فراهم کند.

EME به گونه ای طراحی شده است که برنامه و فایل های رمزگذاری شده مشابه را بدون در نظر گرفتن سیستم حفاظتی زیربنایی، در هر مرورگری مورد استفاده قرار دهد. اولی توسط APIهای استاندارد شده و جریان ممکن می شود در حالی که دومی با مفهوم رمزگذاری مشترک ممکن می شود.

EME یک پسوند برای مشخصات HTMLMediaElement است - از این رو نام آن است. "افزونه" بودن به این معنی است که پشتیبانی مرورگر برای EME اختیاری است: اگر مرورگر از رسانه رمزگذاری شده پشتیبانی نکند، نمی تواند رسانه رمزگذاری شده را پخش کند، اما EME برای مطابقت با مشخصات HTML مورد نیاز نیست. از مشخصات EME :

پیاده سازی های EME از اجزای خارجی زیر استفاده می کنند:

  • سیستم کلیدی: مکانیزم حفاظت از محتوا (DRM). EME به جز Clear Key خود سیستم های کلیدی را تعریف نمی کند (در ادامه در مورد آن بیشتر توضیح می دهیم).
  • ماژول رمزگشایی محتوا (CDM): یک نرم افزار یا مکانیزم سخت افزاری سمت سرویس گیرنده است که امکان پخش رسانه های رمزگذاری شده را فراهم می کند. مانند سیستم های کلیدی، EME هیچ CDM را تعریف نمی کند، اما یک رابط برای برنامه های کاربردی برای تعامل با CDM های موجود ارائه می دهد.
  • سرور مجوز (کلید): با یک CDM تعامل دارد تا کلیدهایی را برای رمزگشایی رسانه ارائه کند. مذاکره با سرور لایسنس بر عهده اپلیکیشن است.
  • خدمات بسته بندی: رسانه ها را برای توزیع/مصرف رمزگذاری و رمزگذاری می کند.

توجه داشته باشید که برنامه ای که از EME استفاده می کند با یک سرور مجوز تعامل دارد تا کلیدهایی را برای فعال کردن رمزگشایی دریافت کند، اما هویت کاربر و احراز هویت بخشی از EME نیست. بازیابی کلیدها برای فعال کردن پخش رسانه پس از احراز هویت (اختیاری) یک کاربر انجام می شود. خدماتی مانند نتفلیکس باید کاربران را در برنامه وب خود احراز هویت کنند: وقتی کاربر وارد برنامه می شود، برنامه هویت و امتیازات کاربر را تعیین می کند.

EME چگونه کار می کند؟

در اینجا نحوه تعامل اجزای EME، مطابق با مثال کد زیر آمده است:

  1. یک برنامه وب سعی می کند صدا یا ویدیویی را پخش کند که یک یا چند جریان رمزگذاری شده دارد.
  2. مرورگر تشخیص می‌دهد که رسانه رمزگذاری شده است (برای اینکه چگونه این اتفاق می‌افتد، به کادر زیر مراجعه کنید) و یک رویداد encrypted را با فراداده ( initData ) به‌دست‌آمده از رسانه در مورد رمزگذاری فعال می‌کند.
  3. برنامه رویداد encrypted را مدیریت می کند:
    1. اگر هیچ شی MediaKeys با عنصر رسانه مرتبط نشده است، ابتدا یک سیستم کلید موجود را با استفاده از navigator.requestMediaKeySystemAccess() انتخاب کنید تا بررسی کنید که سیستم های کلیدی در دسترس هستند، سپس یک شی MediaKeys برای یک سیستم کلیدی موجود از طریق یک شی MediaKeySystemAccess ایجاد کنید. توجه داشته باشید که مقداردهی اولیه شی MediaKeys باید قبل از اولین رویداد encrypted اتفاق بیفتد. دریافت URL سرور مجوز توسط برنامه مستقل از انتخاب یک سیستم کلید موجود انجام می شود. یک شی MediaKeys نشان دهنده تمام کلیدهای موجود برای رمزگشایی رسانه برای یک عنصر صوتی یا تصویری است. این یک نمونه CDM را نشان می‌دهد و دسترسی به CDM را فراهم می‌کند، مخصوصاً برای ایجاد جلسات کلید، که برای دریافت کلیدها از سرور مجوز استفاده می‌شود.
    2. هنگامی که شی MediaKeys ایجاد شد، آن را به عنصر رسانه اختصاص دهید: setMediaKeys() شی MediaKeys را با یک HTMLMediaElement مرتبط می کند، به طوری که کلیدهای آن را می توان در حین پخش، یعنی در هنگام رمزگشایی استفاده کرد.
  4. این برنامه با فراخوانی createSession() در MediaKeys یک MediaKeySession ایجاد می کند. این یک MediaKeySession ایجاد می کند که طول عمر مجوز و کلید(های) آن را نشان می دهد.
  5. برنامه با ارسال داده های رسانه ای به دست آمده در کنترل کننده encrypted به CDM، با فراخوانی generateRequest() در MediaKeySession یک درخواست مجوز ایجاد می کند.
  6. CDM یک رویداد message اجرا می کند: درخواستی برای دریافت یک کلید از سرور مجوز.
  7. شی MediaKeySession رویداد message دریافت می کند و برنامه پیامی را به سرور مجوز می فرستد (برای مثال از طریق XHR).
  8. برنامه یک پاسخ از سرور مجوز دریافت می کند و داده ها را با استفاده از روش update() MediaKeySession به CDM ارسال می کند.
  9. CDM با استفاده از کلیدهای موجود در مجوز، رسانه را رمزگشایی می کند. یک کلید معتبر ممکن است از هر جلسه ای در MediaKey مرتبط با عنصر رسانه استفاده شود. CDM به کلید و خط مشی که با شناسه کلید نمایه شده است دسترسی خواهد داشت.
  10. پخش رسانه از سر گرفته می شود.

وای…

توجه داشته باشید که ممکن است چندین پیام بین CDM و سرور مجوز وجود داشته باشد، و تمام ارتباطات در این فرآیند برای مرورگر و برنامه غیرشفاف است: پیام‌ها فقط توسط CDM و سرور مجوز قابل درک هستند، اگرچه لایه برنامه می‌تواند نوع پیام را ببیند. CDM در حال ارسال است. درخواست مجوز حاوی مدرکی دال بر اعتبار CDM (و رابطه اعتماد) و همچنین کلیدی برای استفاده در هنگام رمزگذاری کلید(های) محتوا در مجوز به دست آمده است.

... اما CDM ها واقعا چه کار می کنند؟

پیاده سازی EME به خودی خود راهی برای رمزگشایی رسانه ارائه نمی دهد: آن به سادگی یک API برای یک برنامه وب برای تعامل با ماژول های رمزگشایی محتوا فراهم می کند.

آنچه CDM ها در واقع انجام می دهند توسط مشخصات EME تعریف نشده است، و CDM ممکن است رمزگشایی (فشرده سازی) رسانه و همچنین رمزگشایی را انجام دهد. از کمترین تا قوی ترین، چندین گزینه بالقوه برای عملکرد CDM وجود دارد:

  • فقط رمزگشایی، امکان پخش با استفاده از خط لوله معمولی رسانه، برای مثال از طریق عنصر <video> .
  • رمزگشایی و رمزگشایی، ارسال فریم های ویدئویی به مرورگر برای رندر.
  • رمزگشایی و رمزگشایی، رندر مستقیم در سخت افزار (به عنوان مثال، GPU).

راه های متعددی برای در دسترس قرار دادن CDM برای یک برنامه وب وجود دارد:

  • یک CDM را با مرورگر همراه کنید.
  • یک CDM را جداگانه توزیع کنید.
  • یک CDM در سیستم عامل بسازید.
  • یک CDM را در سیستم عامل قرار دهید.
  • یک CDM را در سخت افزار جاسازی کنید.

نحوه در دسترس قرار گرفتن CDM توسط مشخصات EME تعریف نشده است، اما در همه موارد مرورگر مسئول بررسی و افشای CDM است.

EME سیستم کلید خاصی را اجباری نمی کند. در میان مرورگرهای دسکتاپ و موبایل فعلی، کروم از Widevine و IE11 از PlayReady پشتیبانی می کنند.

گرفتن کلید از سرور مجوز

در استفاده تجاری معمولی، محتوا با استفاده از یک سرویس یا ابزار بسته بندی رمزگذاری و کدگذاری می شود. هنگامی که رسانه رمزگذاری شده به صورت آنلاین در دسترس قرار گرفت، یک سرویس گیرنده وب می تواند یک کلید (که در یک مجوز موجود است) از سرور مجوز دریافت کند و از کلید برای فعال کردن رمزگشایی و پخش محتوا استفاده کند.

کد زیر (اقتباس شده از نمونه های مشخصات ) نشان می دهد که چگونه یک برنامه کاربردی می تواند یک سیستم کلید مناسب را انتخاب کند و یک کلید را از سرور مجوز دریافت کند.

var video = document.querySelector('video');

var config = [{initDataTypes: ['webm'],
  videoCapabilities: [{contentType: 'video/webm; codecs="vp9"'}]}];

if (!video.mediaKeys) {
  navigator.requestMediaKeySystemAccess('org.w3.clearkey',
      config).then(
    function(keySystemAccess) {
      var promise = keySystemAccess.createMediaKeys();
      promise.catch(
        console.error.bind(console, 'Unable to create MediaKeys')
      );
      promise.then(
        function(createdMediaKeys) {
          return video.setMediaKeys(createdMediaKeys);
        }
      ).catch(
        console.error.bind(console, 'Unable to set MediaKeys')
      );
      promise.then(
        function(createdMediaKeys) {
          var initData = new Uint8Array([...]);
          var keySession = createdMediaKeys.createSession();
          keySession.addEventListener('message', handleMessage,
              false);
          return keySession.generateRequest('webm', initData);
        }
      ).catch(
        console.error.bind(console,
          'Unable to create or initialize key session')
      );
    }
  );
}

function handleMessage(event) {
  var keySession = event.target;
  var license = new Uint8Array([...]);
  keySession.update(license).catch(
    console.error.bind(console, 'update() failed')
  );
}

رمزگذاری رایج

راه‌حل‌های رمزگذاری مشترک به ارائه‌دهندگان محتوا اجازه می‌دهد تا محتوای خود را یک بار در هر ظرف/کدک رمزگذاری و بسته‌بندی کنند و از آن با انواع سیستم‌های کلیدی، CDM و کلاینت‌ها استفاده کنند: یعنی هر CDM که از رمزگذاری مشترک پشتیبانی می‌کند. به عنوان مثال، یک ویدیوی بسته بندی شده با استفاده از Playready را می توان در مرورگر با استفاده از یک CDM Widevine که کلیدی را از سرور مجوز Widevine دریافت می کند، پخش کرد.

این برخلاف راه‌حل‌های قدیمی است که فقط با یک پشته عمودی کامل کار می‌کنند، از جمله یک کلاینت منفرد که اغلب شامل زمان اجرای برنامه نیز می‌شود.

رمزگذاری مشترک (CENC) یک استاندارد ISO است که یک طرح حفاظتی برای ISO BMFF تعریف می کند. مفهوم مشابهی برای WebM صدق می کند.

کلید پاک کردن

اگرچه EME عملکرد DRM را تعریف نمی کند، اما این مشخصات در حال حاضر الزام می کند که همه مرورگرهایی که از EME پشتیبانی می کنند باید Clear Key را پیاده سازی کنند. با استفاده از این سیستم، رسانه ها را می توان با یک کلید رمزگذاری کرد و سپس به سادگی با ارائه آن کلید پخش شد. Clear Key را می توان در مرورگر تعبیه کرد: نیازی به استفاده از ماژول رمزگشایی جداگانه ندارد.

در حالی که به احتمال زیاد برای بسیاری از انواع محتوای تجاری استفاده نمی شود، Clear Key به طور کامل در تمام مرورگرهایی که از EME پشتیبانی می کنند قابل همکاری است. همچنین برای آزمایش پیاده سازی های EME و برنامه های کاربردی با استفاده از EME، بدون نیاز به درخواست کلید محتوا از سرور مجوز، مفید است. یک مثال ساده Clear Key در simpl.info/ck وجود دارد. در زیر توضیحی از کد ارائه شده است که با مراحل توضیح داده شده در بالا هماهنگی دارد، البته بدون تعامل با سرور مجوز.

// Define a key: hardcoded in this example
// – this corresponds to the key used for encryption
var KEY = new Uint8Array([
  0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
  0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c
]);

var config = [{
  initDataTypes: ['webm'],
  videoCapabilities: [{
    contentType: 'video/webm; codecs="vp8"'
  }]
}];

var video = document.querySelector('video');
video.addEventListener('encrypted', handleEncrypted, false);

navigator.requestMediaKeySystemAccess('org.w3.clearkey', config).then(
  function(keySystemAccess) {
    return keySystemAccess.createMediaKeys();
  }
).then(
  function(createdMediaKeys) {
    return video.setMediaKeys(createdMediaKeys);
  }
).catch(
  function(error) {
    console.error('Failed to set up MediaKeys', error);
  }
);

function handleEncrypted(event) {
  var session = video.mediaKeys.createSession();
  session.addEventListener('message', handleMessage, false);
  session.generateRequest(event.initDataType, event.initData).catch(
    function(error) {
      console.error('Failed to generate a license request', error);
    }
  );
}

function handleMessage(event) {
  // If you had a license server, you would make an asynchronous XMLHttpRequest
  // with event.message as the body.  The response from the server, as a
  // Uint8Array, would then be passed to session.update().
  // Instead, we will generate the license synchronously on the client, using
  // the hard-coded KEY at the top.
  var license = generateLicense(event.message);

  var session = event.target;
  session.update(license).catch(
    function(error) {
      console.error('Failed to update the session', error);
    }
  );
}

// Convert Uint8Array into base64 using base64url alphabet, without padding.
function toBase64(u8arr) {
  return btoa(String.fromCharCode.apply(null, u8arr)).
      replace(/\+/g, '-').replace(/\//g, '_').replace(/=*$/, '');
}

// This takes the place of a license server.
// kids is an array of base64-encoded key IDs
// keys is an array of base64-encoded keys
function generateLicense(message) {
  // Parse the clearkey license request.
  var request = JSON.parse(new TextDecoder().decode(message));
  // We only know one key, so there should only be one key ID.
  // A real license server could easily serve multiple keys.
  console.assert(request.kids.length === 1);

  var keyObj = {
    kty: 'oct',
    alg: 'A128KW',
    kid: request.kids[0],
    k: toBase64(KEY)
  };
  return new TextEncoder().encode(JSON.stringify({
    keys: [keyObj]
  }));
}

برای آزمایش این کد، به یک ویدیوی رمزگذاری شده برای پخش نیاز دارید. رمزگذاری یک ویدیو برای استفاده با Clear Key می تواند برای WebM طبق دستورالعمل webm_crypt انجام شود. خدمات تجاری نیز در دسترس هستند (حداقل برای ISO BMFF/MP4) و راه حل های دیگری در حال توسعه هستند.

پسوندهای منبع رسانه (MSE)

HTMLMediaElement موجودی با زیبایی ساده است.

ما می توانیم رسانه ها را به سادگی با ارائه یک URL src بارگیری، رمزگشایی و پخش کنیم:

<video src='foo.webm'></video>

Media Source API یک افزونه برای HTMLMediaElement است که با اجازه دادن به جاوا اسکریپت برای ساخت جریان‌هایی برای پخش از «تکه‌های» ویدیو، کنترل دقیق‌تری را بر منبع رسانه امکان‌پذیر می‌سازد. این به نوبه خود تکنیک هایی مانند جریان تطبیقی ​​و تغییر زمان را امکان پذیر می کند.

چرا MSE برای EME مهم است؟ زیرا علاوه بر توزیع محتوای محافظت شده، ارائه دهندگان محتوای تجاری باید بتوانند تحویل محتوا را با شرایط شبکه و سایر الزامات تطبیق دهند. برای مثال، نتفلیکس با تغییر شرایط شبکه، به صورت پویا نرخ بیت جریان را تغییر می‌دهد. EME با پخش جریان های رسانه ای ارائه شده توسط یک پیاده سازی MSE کار می کند، درست همانطور که با رسانه ارائه شده از طریق یک ویژگی src این کار را انجام می دهد.

چگونه رسانه های کدگذاری شده با نرخ بیت های مختلف را تکه تکه و پخش کنیم؟ بخش DASH را در زیر ببینید.

می توانید MSE را در عمل در simpl.info/mse مشاهده کنید. برای اهداف این مثال، یک ویدیوی WebM با استفاده از File API به پنج تکه تقسیم می‌شود. در یک برنامه تولیدی، تکه‌های ویدیو از طریق Ajax بازیابی می‌شوند.

ابتدا یک SourceBuffer ایجاد می شود:

var sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"');

سپس کل فیلم با اضافه کردن هر تکه با استفاده از متد ()appendBuffer به یک عنصر ویدیویی پخش می‌شود:

reader.onload = function (e) {
  sourceBuffer.appendBuffer(new Uint8Array(e.target.result));
  if (i === NUM_CHUNKS - 1) {
    mediaSource.endOfStream();
  } else {
    if (video.paused) {
      // start playing after first chunk is appended
      video.play();
    }
    readChunk_(++i);
  }
};

در مقاله HTML5 Rocks درباره MSE اطلاعات بیشتری کسب کنید.

پخش جریانی تطبیقی ​​پویا از طریق HTTP (DASH)

چند دستگاه، چند پلتفرم، موبایل - هر چه آن را بنامید، وب اغلب تحت شرایط اتصال قابل تغییر تجربه می شود. تحویل پویا و تطبیقی ​​برای مقابله با محدودیت‌های پهنای باند و تنوع در دنیای چند دستگاهی بسیار مهم است.

DASH (معروف به MPEG-DASH) به گونه‌ای طراحی شده است که بهترین پخش رسانه ممکن را در یک دنیای پرتقال، هم برای پخش و هم برای دانلود، فراهم کند. چندین فناوری دیگر نیز کاری مشابه انجام می دهند - مانند HTTP Live Streaming (HLS) اپل و Smooth Streaming مایکروسافت - اما DASH تنها روش پخش نرخ بیت تطبیقی ​​از طریق HTTP است که بر اساس یک استاندارد باز است. DASH در حال حاضر توسط سایت هایی مانند YouTube استفاده می شود.

این چه ربطی به EME و MSE دارد؟ پیاده‌سازی‌های DASH مبتنی بر MSE می‌توانند یک مانیفست را تجزیه کنند، بخش‌هایی از ویدیو را با نرخ بیت مناسب دانلود کنند، و آن‌ها را به عنصر ویدیویی که گرسنه شد - با استفاده از زیرساخت‌های HTTP موجود تغذیه کنند.

به عبارت دیگر، DASH ارائه دهندگان محتوای تجاری را قادر می سازد تا جریان تطبیقی ​​محتوای محافظت شده را انجام دهند.

DASH کاری را که روی قلع می گوید انجام می دهد:

  • پویا: به شرایط متغیر پاسخ می دهد.
  • تطبیقی: برای ارائه نرخ بیت صوتی یا تصویری مناسب سازگار است.
  • استریم: امکان پخش جریانی و همچنین دانلود را فراهم می کند.
  • HTTP: تحویل محتوا را با مزیت HTTP، بدون معایب سرور جریان سنتی، امکان پذیر می کند.

بی بی سی شروع به ارائه جریان های آزمایشی با استفاده از DASH کرده است:

به طور خلاصه:

  1. رسانه با نرخ بیت های مختلف کدگذاری می شود.
  2. فایل‌های نرخ بیت مختلف از یک سرور HTTP در دسترس هستند.
  3. یک برنامه وب سرویس گیرنده انتخاب می کند که کدام بیت را بازیابی و با DASH پخش کند.

به عنوان بخشی از فرآیند تقسیم‌بندی ویدیو، یک مانیفست XML که به عنوان توصیف ارائه رسانه (MPD) شناخته می‌شود، به صورت برنامه‌نویسی ساخته می‌شود. این مجموعه‌ها و بازنمایی‌های انطباق را با مدت زمان و آدرس‌های اینترنتی توصیف می‌کند. MPD به شکل زیر است:

<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" mediaPresentationDuration="PT0H3M1.63S" minBufferTime="PT1.5S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011"
type="static">
  <Period duration="PT0H3M1.63S" start="PT0S">
    <AdaptationSet>
      <ContentComponent contentType="video" id="1" />
      <Representation bandwidth="4190760" codecs="avc1.640028" height="1080" id="1" mimeType="video/mp4" width="1920">
        <BaseURL>car-20120827-89.mp4</BaseURL>
        <SegmentBase indexRange="674-1149">
          <Initialization range="0-673" />
        </SegmentBase>
      </Representation>
      <Representation bandwidth="2073921" codecs="avc1.4d401f" height="720" id="2" mimeType="video/mp4" width="1280">
        <BaseURL>car-20120827-88.mp4</BaseURL>
        <SegmentBase indexRange="708-1183">
          <Initialization range="0-707" />
        </SegmentBase>
      </Representation>

      …

    </AdaptationSet>
  </Period>
</MPD>

(این XML از فایل mpd. استفاده شده برای پخش کننده نمایشی YouTube DASH گرفته شده است)

با توجه به مشخصات DASH، یک فایل MPD در تئوری می تواند به عنوان src برای یک ویدیو استفاده شود. با این حال، برای ارائه انعطاف‌پذیری بیشتر به توسعه‌دهندگان وب، فروشندگان مرورگر ترجیح داده‌اند پشتیبانی از DASH را به کتابخانه‌های جاوا اسکریپت با استفاده از MSE مانند dash.js بسپارند. پیاده سازی DASH در جاوا اسکریپت به الگوریتم سازگاری اجازه می دهد تا بدون نیاز به به روز رسانی مرورگر تکامل یابد. استفاده از MSE همچنین امکان آزمایش با قالب‌های مانیفست جایگزین و مکانیسم‌های تحویل را بدون نیاز به تغییرات مرورگر فراهم می‌کند. Shaka Player Google یک کلاینت DASH را با پشتیبانی EME پیاده سازی می کند.

Mozilla Developer Network دستورالعمل‌هایی در مورد نحوه استفاده از ابزار WebM و FFmpeg برای تقسیم‌بندی ویدیو و ساخت MPD دارد .

نتیجه

استفاده از وب برای ارائه ویدیو و صدای پولی با سرعت زیادی در حال رشد است. به نظر می رسد که هر دستگاه جدید، اعم از تبلت، کنسول بازی، تلویزیون متصل یا ست تاپ باکس، می تواند رسانه ها را از ارائه دهندگان اصلی محتوا از طریق HTTP پخش کند. بیش از 85 درصد از مرورگرهای تلفن همراه و دسکتاپ اکنون از <video> و <audio> پشتیبانی می‌کنند و سیسکو تخمین می‌زند که ویدئو تا سال 2017 80 تا 90 درصد از ترافیک اینترنت مصرف‌کننده جهانی خواهد بود . در این زمینه، پشتیبانی مرورگر برای توزیع محتوای محافظت شده احتمالاً به طور فزاینده ای قابل توجه خواهد بود، زیرا فروشندگان مرورگر پشتیبانی از API هایی را که اکثر افزونه های رسانه به آنها متکی هستند، محدود می کنند .

بیشتر خواندن

مشخصات و استانداردها

مقالات