Encrypted Media Extensions (EME) menyediakan API yang memungkinkan aplikasi web berinteraksi dengan sistem perlindungan konten, untuk memungkinkan pemutaran audio dan video terenkripsi.
EME dirancang untuk memungkinkan aplikasi dan file terenkripsi yang sama digunakan di browser apa pun, terlepas dari sistem perlindungan yang mendasarinya. Yang pertama dimungkinkan oleh API dan alur standar, sedangkan yang kedua dimungkinkan oleh konsep Enkripsi Umum.
EME adalah ekstensi untuk spesifikasi HTMLMediaElement
- sehingga 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:
Implementasi EME menggunakan komponen eksternal berikut:
- Key System: Mekanisme perlindungan konten (DRM). EME tidak menentukan Sistem Kunci itu sendiri, selain Clear Key (selengkapnya di bawah).
- Content Decryption Module (CDM): Mekanisme software atau hardware sisi klien yang memungkinkan pemutaran media terenkripsi. Seperti Sistem Kunci, 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 guna mendekripsi media. Negosiasi dengan server lisensi adalah tanggung jawab aplikasi.
- Layanan pengemasan: Mengenkode dan mengenkripsi media untuk distribusi/konsumsi.
Perhatikan 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 terjadi setelah (opsional) mengautentikasi pengguna. Layanan seperti Netflix harus mengautentikasi pengguna dalam aplikasi web mereka: saat pengguna login ke aplikasi, aplikasi akan menentukan identitas dan hak istimewa pengguna.
Bagaimana cara kerja EME?
Berikut adalah cara komponen EME berinteraksi, sesuai dengan contoh kode berikut:
- Aplikasi web mencoba memutar audio atau video yang memiliki satu atau beberapa streaming terenkripsi.
- Browser mengenali bahwa media dienkripsi (lihat kotak di bawah untuk mengetahui cara melakukannya) dan memicu peristiwa
encrypted
dengan metadata (initData
) yang diperoleh dari media tentang enkripsi. - Aplikasi menangani peristiwa
encrypted
:- Jika tidak ada objek
MediaKeys
yang dikaitkan dengan elemen media, pilih terlebih dahulu Key System yang tersedia menggunakannavigator.requestMediaKeySystemAccess()
untuk memeriksa Key System yang tersedia, lalu buat objekMediaKeys
untuk Key System yang tersedia melalui objekMediaKeySystemAccess
. Perhatikan bahwa inisialisasi objek MediaKeys harus terjadi sebelum peristiwaencrypted
pertama. Mendapatkan URL server lisensi dilakukan oleh aplikasi secara terpisah dari memilih sistem kunci yang tersedia. ObjekMediaKeys
mewakili semua kunci yang tersedia untuk mendekripsi media untuk elemen audio atau video. Class ini mewakili instance CDM dan memberikan akses ke CDM, khususnya untuk membuat sesi kunci, yang digunakan untuk mendapatkan kunci dari server lisensi. - Setelah objek
MediaKeys
dibuat, tetapkan ke elemen media:setMediaKeys()
mengaitkan objekMediaKeys
dengan HTMLMediaElement, sehingga kuncinya dapat digunakan selama pemutaran, yaitu selama decoding.
- Jika tidak ada objek
- Aplikasi membuat
MediaKeySession
dengan memanggilcreateSession()
diMediaKeys
. Tindakan ini akan membuatMediaKeySession
, yang mewakili masa berlaku lisensi dan kuncinya. - Aplikasi membuat permintaan lisensi dengan meneruskan data media yang diperoleh di pengendali
encrypted
ke CDM, dengan memanggilgenerateRequest()
diMediaKeySession
. - CDM memicu peristiwa
message
: permintaan untuk memperoleh kunci dari server lisensi. - Objek
MediaKeySession
menerima peristiwamessage
dan aplikasi mengirimkan pesan ke server lisensi (misalnya melalui XHR). - Aplikasi menerima respons dari server lisensi dan meneruskan data ke CDM menggunakan metode
update()
dariMediaKeySession
. - CDM mendekripsi media menggunakan kunci dalam lisensi tersebut. Kunci yang valid dapat digunakan, dari sesi apa pun dalam
MediaKey
yang terkait dengan elemen media. CDM akan mengakses kunci dan kebijakan, yang diindeks oleh ID Kunci. - Pemutaran media dilanjutkan.
Fiuh…
Perhatikan bahwa mungkin ada beberapa pesan antara CDM dan server lisensi, dan semua komunikasi dalam proses ini buram bagi browser dan aplikasi: pesan hanya dipahami oleh CDM dan server lisensi, meskipun lapisan aplikasi dapat melihat jenis pesan yang dikirim CDM. Permintaan lisensi berisi bukti validitas CDM (dan hubungan kepercayaan) serta kunci yang akan digunakan saat mengenkripsi kunci konten dalam lisensi yang dihasilkan.
...tetapi apa yang sebenarnya dilakukan CDM?
Implementasi EME itu sendiri tidak menyediakan cara untuk mendekripsi media: implementasi ini hanya menyediakan API untuk aplikasi web agar dapat berinteraksi dengan Modul Dekripsi Konten.
Fungsi CDM sebenarnya tidak ditentukan oleh spesifikasi EME, dan CDM dapat menangani decoding (dekompresi) media serta dekripsi. Dari yang paling tidak andal hingga yang paling andal, ada beberapa opsi potensial untuk fungsi CDM:
- Hanya dekripsi, yang memungkinkan pemutaran menggunakan pipeline media normal, misalnya melalui elemen
<video>
. - Dekripsi dan decoding, yang meneruskan frame video ke browser untuk dirender.
- Dekripsi dan decoding, yang dirender langsung di hardware (misalnya, GPU).
Ada beberapa cara untuk menyediakan CDM ke aplikasi web:
- Gabungkan CDM dengan browser.
- Mendistribusikan CDM secara terpisah.
- Build CDM ke dalam sistem operasi.
- Menyertakan CDM dalam firmware.
- Menyematkan CDM di hardware.
Bagaimana CDM tersedia 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 umum, konten akan dienkripsi dan dienkode menggunakan layanan atau alat pengemasan. Setelah media terenkripsi disediakan 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 dapat 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="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')
);
}
Enkripsi Umum
Solusi Enkripsi Umum memungkinkan penyedia konten mengenkripsi dan memaketkan konten mereka satu kali per penampung/codec dan menggunakannya dengan berbagai Sistem Kunci, CDM, dan klien: yaitu, CDM apa pun yang mendukung Enkripsi Umum. Misalnya, video yang dikemas menggunakan Playready dapat diputar di browser menggunakan CDM Widevine yang 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, spesifikasi saat ini mewajibkan semua browser yang mendukung EME harus menerapkan Clear Key. Dengan sistem ini, media dapat dienkripsi dengan kunci, lalu diputar hanya dengan memberikan kunci tersebut. Clear Key dapat di-build 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. Hal ini juga berguna untuk menguji penerapan EME, dan aplikasi yang menggunakan EME, tanpa perlu meminta kunci konten dari server lisensi. Ada contoh Clear Key sederhana di simpl.info/ck. Berikut adalah panduan kode, yang sejajar 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.
Teknologi terkait #1
Ekstensi Sumber Media (MSE)
HTMLMediaElement adalah makhluk yang sangat menarik.
Kita dapat memuat, mendekode, dan memutar media cukup dengan memberikan URL src:
<video src='foo.webm'></video>
Media Source API adalah ekstensi untuk HTMLMediaElement yang memungkinkan kontrol lebih mendetail atas sumber media, dengan memungkinkan JavaScript membuat streaming untuk pemutaran dari 'bagian' 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 juga harus dapat menyesuaikan penayangan konten dengan kondisi jaringan dan persyaratan lainnya. Netflix, misalnya, mengubah kecepatan bit streaming secara dinamis saat kondisi jaringan berubah. EME berfungsi dengan pemutaran streaming media yang disediakan oleh implementasi MSE, sama seperti media yang disediakan melalui atribut src
.
Bagaimana cara mengelompokkan dan memutar media yang dienkode dengan kecepatan bit yang berbeda? Lihat bagian DASH di bawah ini.
Anda dapat melihat cara kerja MSE di simpl.info/mse; untuk tujuan contoh ini, video WebM dibagi menjadi lima bagian menggunakan File API. Dalam aplikasi produksi, potongan video akan diambil melalui Ajax.
Pertama, SourceBuffer dibuat:
var sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
Seluruh film kemudian 'di-streaming' ke elemen video dengan menambahkan setiap bagian menggunakan metode 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);
}
};
Cari tahu MSE lebih lanjut di artikel HTML5 Rocks.
Teknologi terkait #2
Dynamic Adaptive Streaming over HTTP (DASH)
Multiperangkat, multi-platform, seluler - apa pun namanya, web sering kali digunakan dalam kondisi konektivitas yang dapat berubah. Pengiriman dinamis dan adaptif sangat penting untuk mengatasi keterbatasan bandwidth dan variabilitas di dunia multiperangkat.
DASH (alias MPEG-DASH) dirancang untuk memungkinkan pengiriman media terbaik dalam dunia yang tak stabil, baik untuk streaming maupun download. Beberapa teknologi lain melakukan hal yang 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 merasa lapar, menggunakan infrastruktur HTTP yang ada.
Dengan kata lain, DASH memungkinkan penyedia konten komersial untuk melakukan streaming adaptif konten yang dilindungi.
DASH melakukan apa yang tertulis di kaleng:
- Dinamis: merespons kondisi yang berubah.
- Adaptif: beradaptasi untuk memberikan kecepatan bit audio atau video yang sesuai.
- Streaming: memungkinkan streaming serta download.
- HTTP: memungkinkan pengiriman konten dengan keunggulan HTTP, tanpa kelemahan server streaming tradisional.
BBC telah mulai menyediakan streaming pengujian menggunakan DASH:
Ringkasnya:
- Media dienkode dengan kecepatan bit yang berbeda.
- File dengan berbagai kecepatan bit disediakan dari server HTTP.
- Aplikasi web klien memilih kecepatan bit mana yang akan diambil dan diputar dengan DASH.
Sebagai bagian dari proses segmentasi video, manifes XML yang dikenal sebagai Deskripsi Presentasi Media (MPD) dibuat secara terprogram. Ini menjelaskan Set Adaptasi dan Representasi, dengan 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, file MPD secara teori dapat digunakan sebagai src
untuk video. Namun, untuk memberikan fleksibilitas yang lebih besar kepada developer web, vendor browser memilih untuk menyerahkan dukungan DASH kepada library JavaScript yang menggunakan MSE seperti dash.js. Menerapkan DASH di JavaScript memungkinkan algoritma adaptasi berkembang tanpa memerlukan update browser. Penggunaan MSE juga memungkinkan eksperimen dengan format manifes dan mekanisme pengiriman alternatif tanpa memerlukan perubahan browser. Shaka Player Google mengimplementasikan klien DASH dengan dukungan EME.
Mozilla Developer Network memiliki petunjuk tentang cara menggunakan alat WebM dan FFmpeg untuk menyegmentasikan video dan membuat MPD.
Kesimpulan
Penggunaan web untuk menayangkan video dan audio berbayar berkembang dengan kecepatan yang sangat tinggi. Sepertinya 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 video akan mencapai 80 hingga 90 persen traffic internet konsumen global pada tahun 2017. Dalam konteks ini, dukungan browser untuk distribusi konten yang dilindungi kemungkinan akan semakin signifikan, karena vendor browser mengurangi dukungan untuk API yang digunakan sebagian besar plugin media.
Bacaan lebih lanjut
Spesifikasi dan standar
- Spesifikasi EME: Draf Editor terbaru<
- Enkripsi Umum (CENC)
- Ekstensi Sumber Media
- Standar DASH (ya, ini adalah PDF)
- Tentang standar DASH
Artikel
- Webinar DTG (sebagian tidak digunakan lagi)
- What is EME?, oleh Henri Sivonen
- Artikel Ekstensi Sumber Media HTML5 Rocks
- Streaming Pengujian MPEG-DASH: Postingan blog BBC R&D