Apa itu EME?

Ekstensi Media Terenkripsi menyediakan API yang memungkinkan aplikasi web berinteraksi dengan sistem perlindungan konten, untuk memungkinkan pemutaran audio dan video terenkripsi.

EME dirancang untuk memungkinkan aplikasi yang sama dan file terenkripsi digunakan di browser apa pun, terlepas dari sistem perlindungan yang mendasarinya. Yang pertama dimungkinkan oleh API dan flow terstandardisasi, sedangkan yang kedua dimungkinkan oleh konsep Common Encryption.

EME adalah ekstensi untuk spesifikasi HTMLMediaElement — sehingga disebut sebagai namanya. Menjadi 'ekstensi' berarti dukungan browser untuk EME bersifat opsional: jika browser tidak mendukung media terenkripsi, browser tidak akan dapat memutar media terenkripsi, tetapi EME tidak diperlukan untuk kepatuhan spesifikasi HTML. Dari spesifikasi EME:

Proposal ini memperluas HTMLMediaElement yang menyediakan API untuk mengontrol pemutaran konten yang dilindungi.

API ini mendukung berbagai kasus penggunaan, mulai dari dekripsi kunci yang jelas dan sederhana hingga video bernilai tinggi (dengan penerapan agen pengguna yang sesuai). Pertukaran kunci/lisensi dikontrol oleh aplikasi, yang memfasilitasi pengembangan aplikasi pemutaran yang andal yang mendukung berbagai teknologi perlindungan dan dekripsi konten.

Spesifikasi ini tidak menentukan perlindungan konten atau sistem Pengelolaan Hak Digital. Sebaliknya, Cloud Firestore mendefinisikan API umum yang dapat digunakan untuk menemukan, memilih, dan berinteraksi dengan sistem tersebut serta dengan sistem enkripsi konten yang lebih sederhana. Penerapan Manajemen Hak Digital (DRM) tidak diperlukan untuk mematuhi spesifikasi ini: hanya sistem Clear Key yang diperlukan untuk diterapkan sebagai dasar pengukuran umum.

API umum mendukung serangkaian kemampuan enkripsi konten yang sederhana, sehingga memungkinkan fungsi aplikasi seperti autentikasi dan otorisasi kepada penulis halaman. Hal ini dicapai dengan mewajibkan pesan khusus sistem perlindungan konten dimediasi oleh halaman, bukan melakukan komunikasi out-of-band antara sistem enkripsi dan lisensi atau server lainnya.

Implementasi EME menggunakan komponen eksternal berikut:

  • Sistem Kunci: Mekanisme perlindungan konten (DRM). EME tidak mendefinisikan Sistem Kunci itu sendiri, selain Clear Key (selengkapnya tentang hal itu di bawah).
  • Modul Dekripsi Konten (CDM): Mekanisme software atau hardware sisi klien yang memungkinkan pemutaran media terenkripsi. Seperti Key Systems, EME tidak menentukan CDM apa pun, tetapi menyediakan antarmuka bagi aplikasi untuk berinteraksi dengan CDM yang tersedia.
  • Server lisensi (Kunci): Berinteraksi dengan CDM untuk menyediakan kunci untuk mendekripsi media. Negosiasi dengan server lisensi adalah tanggung jawab aplikasi.
  • Layanan pengemasan: Mengenkode dan mengenkripsi media untuk distribusi/penggunaan.

Perlu diperhatikan bahwa aplikasi yang menggunakan EME berinteraksi dengan server lisensi untuk mendapatkan kunci guna mengaktifkan dekripsi, tetapi identitas dan autentikasi pengguna bukan bagian dari EME. Pengambilan kunci untuk mengaktifkan pemutaran media dilakukan setelah (secara opsional) mengautentikasi pengguna. Layanan seperti Netflix harus mengautentikasi pengguna dalam aplikasi webnya: saat pengguna login ke aplikasi, aplikasi tersebut akan menentukan identitas dan hak istimewa pengguna.

Bagaimana cara kerja EME?

Berikut ini cara komponen EME berinteraksi, yang sesuai dengan contoh kode di bawah ini:

Jika tersedia beberapa format atau codec, MediaSource.isTypeSupported() atau HTMLMediaElement.canPlayType() dapat digunakan untuk memilih format yang tepat. Namun, CDM mungkin hanya mendukung sebagian dari resource yang didukung browser untuk konten yang tidak terenkripsi. Sebaiknya negosiasikan konfigurasi MediaKeys sebelum memilih format dan codec. Jika aplikasi menunggu peristiwa terenkripsi, tetapi MediaKeys menunjukkan bahwa aplikasi tidak dapat menangani format/codec yang dipilih, mungkin terlambat untuk beralih tanpa mengganggu pemutaran.

Alur yang direkomendasikan adalah menegosiasikan MediaKeys terlebih dahulu, menggunakan MediaKeysSystemAccess.getConfiguration() untuk mengetahui konfigurasi yang dinegosiasikan.

Jika hanya ada satu format/codec yang dapat dipilih, Anda tidak perlu menggunakan getConfiguration(). Namun, sebaiknya siapkan MediaKeys terlebih dahulu. Satu-satunya alasan untuk menunggu peristiwa terenkripsi adalah jika tidak ada cara untuk mengetahui apakah konten dienkripsi atau tidak, tetapi dalam praktiknya, hal itu tidak mungkin.

  1. Aplikasi web mencoba memutar audio atau video yang memiliki satu atau beberapa streaming terenkripsi.
  2. Browser mengetahui bahwa media dienkripsi (lihat kotak di bawah untuk mengetahui bagaimana proses itu terjadi) dan mengaktifkan peristiwa terenkripsi dengan metadata (initData) yang diperoleh dari media tentang enkripsi tersebut.
  3. Aplikasi menangani peristiwa terenkripsi:

    1. Jika tidak ada objek MediaKeys yang dikaitkan dengan elemen media, pertama pilih Sistem Kunci yang tersedia menggunakan navigator.requestMediaKeySystemAccess() untuk memeriksa Sistem Kunci yang tersedia, lalu buat objek MediaKeys untuk Sistem Kunci yang tersedia melalui objek MediaKeySystemAccess. Perlu diperhatikan bahwa inisialisasi objek MediaKeys harus terjadi sebelum peristiwa terenkripsi pertama. Mendapatkan URL server lisensi dilakukan oleh aplikasi tanpa memilih sistem kunci yang tersedia. Objek MediaKeys mewakili semua kunci yang tersedia untuk mendekripsi media untuk elemen audio atau video. Objek ini mewakili instance CDM dan memberikan akses ke CDM, khususnya untuk membuat sesi kunci, yang digunakan untuk mendapatkan kunci dari server lisensi.

    2. Setelah objek MediaKeys dibuat, tetapkan objek tersebut ke elemen media: setMediaKeys() mengaitkan objek MediaKeys dengan HTMLMediaElement, sehingga kuncinya dapat digunakan selama pemutaran, yaitu selama decoding.

  4. Aplikasi membuat MediaKeySession dengan memanggil createSession() pada MediaKeys. Tindakan ini akan membuat MediaKeySession, yang mewakili masa aktif lisensi dan kuncinya.

  5. Aplikasi menghasilkan permintaan lisensi dengan meneruskan data media yang diperoleh dalam pengendali terenkripsi ke CDM, dengan memanggil generateRequest() pada MediaKeySession.

  6. CDM mengaktifkan peristiwa pesan: permintaan untuk mendapatkan kunci dari server lisensi.

  7. Objek MediaKeySession menerima peristiwa pesan dan aplikasi mengirim pesan ke server lisensi (misalnya, melalui XHR).

  8. Aplikasi ini menerima respons dari server lisensi dan meneruskan data tersebut ke CDM menggunakan metode update() dari MediaKeySession.

  9. CDM mendekripsi media menggunakan kunci dalam lisensi. Kunci yang valid dapat digunakan, dari sesi apa pun dalam MediaKeys yang terkait dengan elemen media. CDM akan mengakses kunci dan kebijakan, yang diindeks oleh ID Kunci.

Pemutaran media dilanjutkan.

Bagaimana browser mengetahui bahwa media dienkripsi?

Informasi ini ada dalam metadata file penampung media, yang akan memiliki format seperti ISO BMFF atau WebM. Untuk ISO BMFF, ini berarti metadata {i> header<i}, yang disebut kotak informasi skema perlindungan. WebM menggunakan elemen ContentEncryption Matroska, dengan beberapa tambahan khusus WebM. Panduan disediakan untuk setiap container dalam registry khusus EME.

Perlu diperhatikan bahwa mungkin ada beberapa pesan antara CDM dan server lisensi, dan semua komunikasi dalam proses ini tidak terlihat jelas bagi browser dan aplikasi: pesan hanya dipahami oleh CDM dan server lisensi, meskipun lapisan aplikasi dapat melihat jenis pesan yang dikirim oleh CDM. Permintaan lisensi berisi bukti validitas (dan hubungan kepercayaan) CDM, serta kunci yang akan digunakan saat mengenkripsi kunci konten dalam lisensi yang dihasilkan.

Tapi apa yang sebenarnya dilakukan CDM?

Implementasi EME dengan sendirinya tidak menyediakan cara untuk mendekripsi media: implementasi tersebut hanya menyediakan API untuk aplikasi web agar dapat berinteraksi dengan Modul Dekripsi Konten.

Yang sebenarnya dilakukan CDM tidak ditentukan oleh spesifikasi EME, dan CDM dapat menangani dekode (dekompresi) media serta dekripsi. Dari yang paling tidak hingga yang paling tangguh, ada beberapa opsi potensial untuk fungsi CDM:

  • Hanya dekripsi, yang memungkinkan pemutaran menggunakan pipeline media normal, misalnya melalui elemen <video>.
  • Dekripsi dan decoding, meneruskan frame video ke browser untuk rendering.
  • Mendekripsi dan mendekode, merender secara langsung di hardware (misalnya, GPU).

Ada beberapa cara untuk menyediakan CDM untuk aplikasi web:

  • Membundel CDM dengan browser.
  • Mendistribusikan CDM secara terpisah.
  • Membangun CDM ke dalam sistem operasi.
  • Menyertakan CDM dalam firmware.
  • Menyematkan CDM di hardware.

Cara CDM disediakan tidak ditentukan oleh spesifikasi EME, tetapi dalam semua kasus, browser bertanggung jawab untuk memeriksa dan mengekspos CDM.

EME tidak mewajibkan Sistem Kunci tertentu; di antara browser desktop dan seluler saat ini, Chrome mendukung Widevine dan IE11 mendukung PlayReady.

Mendapatkan kunci dari server lisensi

Dalam penggunaan komersial biasa, konten akan dienkripsi dan dienkode menggunakan layanan atau alat pengemasan. Setelah media terenkripsi tersedia secara online, klien web dapat memperoleh kunci (yang terdapat dalam lisensi) dari server lisensi dan menggunakan kunci tersebut untuk mengaktifkan dekripsi dan pemutaran konten.

Kode berikut (diadaptasi dari contoh spesifikasi) menunjukkan cara aplikasi memilih sistem kunci yang sesuai dan mendapatkan kunci dari server lisensi.

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

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

    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')
      );
    }

Enkripsi umum

Dengan solusi Enkripsi umum, penyedia konten dapat mengenkripsi dan mengemas kontennya sekali per penampung/codec dan menggunakannya dengan berbagai Sistem Kunci, CDM, dan klien: yaitu, semua CDM yang mendukung Enkripsi Umum. Misalnya, video yang dikemas menggunakan Playsiap dapat diputar kembali di browser menggunakan Widevine CDM dengan mendapatkan kunci dari server lisensi Widevine.

Hal ini berbeda dengan solusi lama yang hanya akan berfungsi dengan stack vertikal lengkap, termasuk satu klien yang sering kali juga menyertakan runtime aplikasi.

Common Encryption (CENC) adalah standar ISO yang menentukan skema perlindungan untuk ISO BMFF; konsep serupa berlaku untuk WebM.

Hapus Kunci

Meskipun EME tidak menentukan fungsi DRM, saat ini spesifikasi tersebut mewajibkan semua browser yang mendukung EME mengimplementasikan Clear Key. Dengan sistem ini, media dapat dienkripsi dengan kunci, lalu diputar cukup dengan memberikan kunci tersebut. Clear Key dapat dibangun ke dalam browser: tidak memerlukan penggunaan modul dekripsi terpisah.

Meskipun tidak mungkin digunakan untuk banyak jenis konten komersial, Clear Key dapat dioperasikan sepenuhnya di semua browser yang mendukung EME. Alat ini juga berguna untuk menguji implementasi EME dan aplikasi yang menggunakan EME, tanpa perlu meminta kunci konten dari server lisensi. Ada contoh Hapus Kunci sederhana di simpl.info/ck. Di bawah ini adalah panduan kode, yang paralel dengan langkah-langkah yang dijelaskan di atas, meskipun tanpa interaksi server lisensi.

// 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],
    }),
  );
}

Untuk menguji kode ini, Anda memerlukan video terenkripsi untuk diputar. Mengenkripsi video untuk digunakan dengan Clear Key dapat dilakukan untuk WebM sesuai dengan petunjuk webm_crypt. Layanan komersial juga tersedia (setidaknya untuk ISO BMFF/MP4) dan solusi lainnya sedang dikembangkan.

HTMLMediaElement adalah makhluk keindahan sederhana.

Kita dapat memuat, mendekode, dan memutar media hanya dengan memberikan URL src:

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

API Sumber Media adalah ekstensi HTMLMediaElement yang memungkinkan kontrol lebih mendetail atas sumber media, dengan mengizinkan JavaScript membuat streaming untuk pemutaran dari 'potongan' video. Hal ini pada akhirnya memungkinkan teknik seperti streaming adaptif dan pergeseran waktu.

Mengapa MSE penting bagi EME? Karena selain mendistribusikan konten yang dilindungi, penyedia konten komersial harus dapat menyesuaikan penayangan konten dengan kondisi jaringan dan persyaratan lainnya. Misalnya Netflix, secara dinamis mengubah kecepatan bit streaming ketika kondisi jaringan berubah. EME berfungsi dengan pemutaran aliran media yang disediakan oleh penerapan MSE, seperti yang dilakukan dengan media yang disediakan melalui atribut src.

Bagaimana cara memilah dan memutar media yang dienkode pada kecepatan bit yang berbeda? Lihat bagian DASH di bawah.

Anda dapat melihat cara kerja MSE di simpl.info/mse; untuk contoh ini, video WebM dibagi menjadi lima bagian menggunakan File API. Dalam aplikasi produksi, potongan video akan diambil melalui AJAX.

Pertama-tama, SourceBuffer dibuat:

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

Seluruh film kemudian 'di-streaming' ke elemen video dengan menambahkan setiap potongan menggunakan metode addBuffer():

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);
  }
};

Cari tahu tentang MSE lebih lanjut di MSE primer.

Multiperangkat, multi-platform, seluler — apa pun namanya, web sering kali mengalami kondisi konektivitas yang dapat berubah. Pengiriman yang dinamis dan adaptif sangat penting untuk mengatasi kendala bandwidth dan variabilitas di dunia multi-perangkat.

DASH (alias MPEG-DASH) dirancang untuk memungkinkan pengiriman media terbaik dalam dunia yang tidak stabil, untuk streaming maupun download. Beberapa teknologi lain melakukan hal serupa — seperti HTTP Live Streaming (HLS) Apple dan Smooth Streaming Microsoft — tetapi DASH adalah satu-satunya metode streaming kecepatan bit adaptif melalui HTTP yang didasarkan pada standar terbuka. DASH sudah digunakan oleh situs seperti YouTube.

Apa hubungannya dengan EME dan MSE? Implementasi DASH berbasis MSE dapat mengurai manifes, mendownload segmen video pada kecepatan bit yang sesuai, dan memasukkannya ke elemen video saat lapar menggunakan infrastruktur HTTP yang ada.

Dengan kata lain, DASH memungkinkan penyedia konten komersial untuk melakukan streaming adaptif pada konten yang dilindungi.

DASH melakukan apa yang dikatakannya di kaleng:

  • Dinamis: merespons perubahan kondisi.
  • Adaptif: beradaptasi untuk memberikan kecepatan bit audio atau video yang sesuai.
  • Streaming: memungkinkan streaming serta download.
  • HTTP: memungkinkan pengiriman konten dengan memanfaatkan HTTP, tanpa kelemahan server streaming tradisional.

BBC mulai menyediakan uji streaming menggunakan DASH:

Media dienkode beberapa kali pada kecepatan bit yang berbeda. Setiap encoding disebut Representation. Segmen ini dibagi menjadi sejumlah Segmen Media. Klien menjalankan program dengan meminta segmen secara berurutan dari representasi melalui HTTP. Representasi dapat dikelompokkan menjadi Kumpulan Adaptasi representasi yang berisi konten yang setara. Jika ingin mengubah kecepatan bit, klien dapat memilih alternatif dari kumpulan adaptasi saat ini dan mulai meminta segmen dari representasi tersebut. Konten dienkode sedemikian rupa untuk mempermudah peralihan ini dilakukan oleh klien. Selain sejumlah segmen media, representasi umumnya juga memiliki Segmen Inisialisasi. Ini dapat dianggap sebagai header, yang berisi informasi tentang encoding, ukuran frame, dll. Klien perlu mendapatkan ini untuk representasi tertentu sebelum memakai segmen media dari representasi tersebut.

Ringkasnya:

  1. Media dienkode pada kecepatan bit yang berbeda.
  2. File kecepatan bit yang berbeda tersedia dari server HTTP.
  3. Aplikasi web klien memilih kecepatan bit yang akan diambil dan diputar dengan DASH.

Sebagai bagian dari proses segmentasi video, manifes XML yang dikenal sebagai Media Presentation Description (MPD) dibuat secara terprogram. Ini menjelaskan Kumpulan dan Representasi Adaptasi, beserta durasi dan URL. MPD terlihat seperti ini:

    <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 ini diambil dari file .mpd yang digunakan untuk pemutar demo DASH YouTube.)

Menurut spesifikasi DASH, secara teori file MPD dapat digunakan sebagai src untuk video. Namun, untuk memberikan lebih banyak fleksibilitas kepada developer web, vendor browser telah memilih untuk membiarkan dukungan DASH hingga library JavaScript menggunakan MSE seperti dash.js. Mengimplementasikan DASH di JavaScript memungkinkan algoritma adaptasi berkembang tanpa memerlukan update browser. Penggunaan MSE juga memungkinkan eksperimen dengan format manifes alternatif dan mekanisme pengiriman tanpa memerlukan perubahan browser. Shaka Player Google menerapkan klien DASH dengan dukungan EME.

Mozilla Developer Network memiliki petunjuk cara menggunakan alat WebM dan FFmpeg untuk menyegmentasi video dan membuat MPD.

Kesimpulan

Penggunaan web untuk menayangkan video dan audio berbayar berkembang dengan kecepatan yang sangat besar. Tampaknya setiap perangkat baru, baik tablet, konsol game, TV yang terhubung, atau dekoder, dapat melakukan streaming media dari penyedia konten utama melalui HTTP. Lebih dari 85% browser seluler dan desktop kini mendukung <video> dan <audio>, dan Cisco memperkirakan bahwa video akan menjadi 80 hingga 90 persen traffic internet konsumen global pada tahun 2017. Dalam konteks ini, dukungan browser untuk distribusi konten yang dilindungi mungkin akan semakin signifikan, karena vendor browser membatasi dukungan untuk API yang diandalkan oleh sebagian besar plugin media.

Bacaan lebih lanjut

Spesifikasi dan standar

Spesifikasi EME: Draf Editor terbaru Common Encryption (CENC) Media Source Extensions: Draf Editor terbaru standar DASH (ya, ini berupa PDF) Ringkasan standar DASH

Artikel

Webinar DTG (sebagian tidak berlaku lagi) What is EME?, oleh Henri Sivonen Pengantar Media Source Extensions Streaming Pengujian MPEG-DASH: Postingan blog BBC R&D

Demo

Demo Clear Key: simpl.info/ck Demo Media Source Extensions (MSE) Shaka Player Google menerapkan klien DASH dengan dukungan EME

Masukan