Giới thiệu về Tiện ích phương tiện đã mã hoá

Tiện ích nội dung đa phương tiện được mã hoá (EME) cung cấp một API cho phép các ứng dụng web tương tác với các hệ thống bảo vệ nội dung để cho phép phát âm thanh và video được mã hoá.

EME được thiết kế để cho phép sử dụng cùng một ứng dụng và tệp đã mã hoá trong bất kỳ trình duyệt nào, bất kể hệ thống bảo vệ cơ bản. API và quy trình chuẩn hoá cho phép thực hiện phương thức trước, còn phương thức sau được thực hiện nhờ khái niệm Mã hoá chung.

EME là một phần mở rộng của quy cách HTMLMediaElement – do đó có tên như vậy. Là một "tiện ích" có nghĩa là trình duyệt không bắt buộc phải hỗ trợ EME: nếu không hỗ trợ nội dung đa phương tiện được mã hoá, trình duyệt sẽ không thể phát nội dung đa phương tiện được mã hoá, nhưng EME không bắt buộc phải tuân thủ thông số kỹ thuật HTML. Theo quy cách EME:

Các phương thức triển khai EME sử dụng các thành phần bên ngoài sau:

  • Hệ thống khoá: Cơ chế bảo vệ nội dung (DRM). EME không tự xác định Hệ thống khoá, ngoại trừ Clear Key (xem thêm về điều này ở bên dưới).
  • Bộ mô-đun giải mã nội dung (CDM): Cơ chế phần cứng hoặc phần mềm phía máy khách cho phép phát nội dung nghe nhìn được mã hoá. Giống như Hệ thống khoá, EME không xác định bất kỳ CDM nào, nhưng cung cấp giao diện để các ứng dụng tương tác với CDM hiện có.
  • Máy chủ cấp phép (khoá): Tương tác với CDM để cung cấp khoá giải mã nội dung nghe nhìn. Ứng dụng có trách nhiệm đàm phán với máy chủ cấp phép.
  • Dịch vụ đóng gói: Mã hoá và mã hoá nội dung nghe nhìn để phân phối/tiêu thụ.

Xin lưu ý rằng một ứng dụng sử dụng EME tương tác với máy chủ cấp phép để lấy khoá nhằm bật tính năng giải mã, nhưng danh tính và xác thực người dùng không thuộc EME. Quá trình truy xuất khoá để phát nội dung nghe nhìn sẽ diễn ra sau khi xác thực một người dùng (không bắt buộc). Các dịch vụ như Netflix phải xác thực người dùng trong ứng dụng web của họ: khi người dùng đăng nhập vào ứng dụng, ứng dụng sẽ xác định danh tính và đặc quyền của người dùng.

EME hoạt động như thế nào?

Dưới đây là cách các thành phần của EME tương tác, tương ứng với ví dụ về mã sau:

  1. Một ứng dụng web cố gắng phát âm thanh hoặc video có một hoặc nhiều luồng được mã hoá.
  2. Trình duyệt nhận ra rằng nội dung nghe nhìn được mã hoá (xem hộp bên dưới để biết cách thực hiện) và kích hoạt sự kiện encrypted có siêu dữ liệu (initData) thu được từ nội dung nghe nhìn về quá trình mã hoá.
  3. Ứng dụng xử lý sự kiện encrypted:
    1. Nếu chưa có đối tượng MediaKeys nào được liên kết với phần tử nội dung nghe nhìn, trước tiên, hãy chọn một Hệ thống khoá hiện có bằng cách sử dụng navigator.requestMediaKeySystemAccess() để kiểm tra xem có những Hệ thống khoá nào, sau đó tạo một đối tượng MediaKeys cho một Hệ thống khoá hiện có thông qua đối tượng MediaKeySystemAccess. Xin lưu ý rằng quá trình khởi chạy đối tượng MediaKeys phải diễn ra trước sự kiện encrypted đầu tiên. Ứng dụng sẽ lấy URL máy chủ cấp phép độc lập với việc chọn hệ thống khoá có sẵn. Đối tượng MediaKeys đại diện cho tất cả các khoá có sẵn để giải mã nội dung nghe nhìn cho một phần tử âm thanh hoặc video. Lớp này đại diện cho một thực thể CDM và cung cấp quyền truy cập vào CDM, đặc biệt là để tạo các phiên chính được dùng để lấy khoá từ máy chủ cấp phép.
    2. Sau khi tạo đối tượng MediaKeys, hãy gán đối tượng đó cho phần tử nội dung đa phương tiện: setMediaKeys() liên kết đối tượng MediaKeys với HTMLMediaElement để có thể sử dụng các khoá của đối tượng đó trong khi phát, tức là trong khi giải mã.
  4. Ứng dụng tạo MediaKeySession bằng cách gọi createSession() trên MediaKeys. Thao tác này sẽ tạo một MediaKeySession, đại diện cho thời gian hoạt động của giấy phép và (các) khoá của giấy phép đó.
  5. Ứng dụng tạo yêu cầu cấp phép bằng cách truyền dữ liệu nội dung nghe nhìn thu được trong trình xử lý encrypted đến CDM, bằng cách gọi generateRequest() trên MediaKeySession.
  6. CDM kích hoạt sự kiện message: một yêu cầu để lấy khoá từ máy chủ cấp phép.
  7. Đối tượng MediaKeySession nhận sự kiện message và ứng dụng gửi thông báo đến máy chủ cấp phép (ví dụ: thông qua XHR).
  8. Ứng dụng nhận được phản hồi từ máy chủ cấp phép và chuyển dữ liệu đến CDM bằng phương thức update() của MediaKeySession.
  9. CDM giải mã nội dung nghe nhìn bằng các khoá trong giấy phép. Bạn có thể sử dụng một khoá hợp lệ, từ bất kỳ phiên nào trong MediaKey được liên kết với phần tử nội dung nghe nhìn. CDM sẽ truy cập vào khoá và chính sách, được lập chỉ mục theo Mã khoá.
  10. Quá trình phát nội dung nghe nhìn sẽ tiếp tục.

Phù…

Xin lưu ý rằng có thể có nhiều thông báo giữa CDM và máy chủ cấp phép, đồng thời tất cả thông tin giao tiếp trong quy trình này đều không rõ ràng đối với trình duyệt và ứng dụng: chỉ CDM và máy chủ cấp phép mới hiểu được thông báo, mặc dù lớp ứng dụng có thể xem loại thông báo mà CDM đang gửi. Yêu cầu cấp phép chứa bằng chứng về tính hợp lệ của CDM (và mối quan hệ tin cậy) cũng như khoá để sử dụng khi mã hoá (các) khoá nội dung trong giấy phép thu được.

...nhưng CDM thực sự làm gì?

Việc triển khai EME tự nó không cung cấp cách giải mã nội dung nghe nhìn: nó chỉ cung cấp một API để ứng dụng web tương tác với Mô-đun giải mã nội dung.

Quy cách EME không xác định những gì CDM thực sự làm, và CDM có thể xử lý việc giải mã (giải nén) nội dung nghe nhìn cũng như giải mã. Từ ít đến nhiều chức năng, có một số lựa chọn tiềm năng cho chức năng CDM:

  • Chỉ giải mã, cho phép phát bằng quy trình truyền dẫn nội dung đa phương tiện thông thường, ví dụ: thông qua phần tử <video>.
  • Giải mã và giải mã, truyền khung hình video đến trình duyệt để kết xuất.
  • Giải mã và giải mã, kết xuất trực tiếp trong phần cứng (ví dụ: GPU).

Có nhiều cách để cung cấp CDM cho ứng dụng web:

  • Gói CDM với trình duyệt.
  • Phân phối riêng một CDM.
  • Tạo CDM vào hệ điều hành.
  • Đưa CDM vào chương trình cơ sở.
  • Nhúng CDM vào phần cứng.

Cách cung cấp CDM không được quy định trong thông số kỹ thuật EME, nhưng trong mọi trường hợp, trình duyệt đều chịu trách nhiệm kiểm tra và hiển thị CDM.

EME không bắt buộc phải sử dụng một Hệ thống khoá cụ thể; trong số các trình duyệt hiện tại dành cho máy tính và thiết bị di động, Chrome hỗ trợ Widevine và IE11 hỗ trợ PlayReady.

Nhận khoá từ máy chủ cấp phép

Trong trường hợp sử dụng thương mại thông thường, nội dung sẽ được mã hoá và mã hoá bằng một dịch vụ hoặc công cụ đóng gói. Sau khi nội dung đa phương tiện được mã hoá được cung cấp trực tuyến, ứng dụng web có thể lấy khoá (có trong giấy phép) từ máy chủ cấp phép và sử dụng khoá đó để bật tính năng giải mã và phát nội dung.

Mã sau đây (được điều chỉnh từ ví dụ về thông số kỹ thuật) cho thấy cách một ứng dụng có thể chọn hệ thống khoá thích hợp và lấy khoá từ máy chủ cấp phép.

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

Mã hoá phổ biến

Giải pháp Mã hoá chung cho phép nhà cung cấp nội dung mã hoá và đóng gói nội dung của họ một lần cho mỗi vùng chứa/bộ mã hoá và giải mã, đồng thời sử dụng nội dung đó với nhiều Hệ thống khoá, CDM và ứng dụng: tức là mọi CDM hỗ trợ Mã hoá chung. Ví dụ: một video được đóng gói bằng Playready có thể được phát trong trình duyệt bằng cách sử dụng CDM Widevine lấy khoá từ máy chủ cấp phép Widevine.

Điều này trái ngược với các giải pháp cũ chỉ hoạt động với một ngăn xếp dọc hoàn chỉnh, bao gồm một ứng dụng thường cũng bao gồm thời gian chạy ứng dụng.

Common mã hoá (CENC) là một tiêu chuẩn ISO xác định cơ chế bảo vệ cho ISO BMFF; một khái niệm tương tự áp dụng cho WebM.

Xoá khoá

Mặc dù EME không xác định chức năng DRM, nhưng quy cách hiện tại yêu cầu tất cả trình duyệt hỗ trợ EME phải triển khai Clear Key. Khi sử dụng hệ thống này, bạn có thể mã hoá nội dung nghe nhìn bằng một khoá, sau đó phát lại nội dung đó chỉ bằng cách cung cấp khoá đó. Bạn có thể tích hợp Clear Key vào trình duyệt: không cần sử dụng mô-đun giải mã riêng biệt.

Mặc dù có thể không được dùng cho nhiều loại nội dung thương mại, nhưng Clear Key có khả năng tương tác đầy đủ trên tất cả trình duyệt hỗ trợ EME. Công cụ này cũng rất hữu ích để kiểm thử việc triển khai EME và các ứng dụng sử dụng EME mà không cần yêu cầu khoá nội dung từ máy chủ cấp phép. Có một ví dụ đơn giản về Khoá xoá tại simpl.info/ck. Dưới đây là hướng dẫn từng bước về mã, tương tự như các bước được mô tả ở trên, mặc dù không có hoạt động tương tác với máy chủ cấp phép.

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

Để kiểm tra mã này, bạn cần có một video đã mã hoá để phát. Bạn có thể mã hoá video để sử dụng với Clear Key cho WebM theo hướng dẫn về webm_crypt. Dịch vụ thương mại cũng được cung cấp (tối thiểu là cho ISO BMFF/MP4) và các giải pháp khác đang được phát triển.

Tiện ích nguồn nội dung nghe nhìn (MSE)

HTMLMediaElement là một thành phần có vẻ đẹp đơn giản.

Chúng ta có thể tải, giải mã và phát nội dung nghe nhìn chỉ bằng cách cung cấp URL src:

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

Media Source API là một tiện ích mở rộng cho HTMLMediaElement, cho phép kiểm soát chi tiết hơn nguồn nội dung đa phương tiện bằng cách cho phép JavaScript tạo luồng để phát từ "các đoạn" video. Điều này giúp hỗ trợ các kỹ thuật như truyền trực tuyến thích ứng và dịch chuyển thời gian.

Tại sao MSE lại quan trọng đối với EME? Vì ngoài việc phân phối nội dung được bảo vệ, nhà cung cấp nội dung thương mại phải có khả năng điều chỉnh việc phân phối nội dung cho phù hợp với điều kiện mạng và các yêu cầu khác. Ví dụ: Netflix thay đổi động tốc độ bit của luồng khi điều kiện mạng thay đổi. EME hoạt động với chế độ phát luồng nội dung nghe nhìn do quá trình triển khai MSE cung cấp, giống như với nội dung nghe nhìn được cung cấp thông qua thuộc tính src.

Làm cách nào để phân đoạn và phát lại nội dung nghe nhìn được mã hoá ở các tốc độ bit khác nhau? Hãy xem phần DASH ở bên dưới.

Bạn có thể thấy MSE trong thực tế tại simpl.info/mse; trong ví dụ này, một video WebM được chia thành 5 phần bằng cách sử dụng File API (API tệp). Trong ứng dụng chính thức, các đoạn video sẽ được truy xuất thông qua Ajax.

Trước tiên, hãy tạo một SourceBuffer:

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

Sau đó, toàn bộ bộ phim sẽ được "truyền trực tuyến" đến một phần tử video bằng cách thêm từng phần bằng phương thức 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);
  }
};

Tìm hiểu thêm về MSE trong bài viết về HTML5 Rocks.

Truyền phát thích ứng động qua HTTP (DASH)

Đa thiết bị, đa nền tảng, thiết bị di động – dù bạn gọi thế nào, web thường được trải nghiệm trong điều kiện kết nối có thể thay đổi. Việc phân phối linh động, thích ứng là yếu tố quan trọng để đối phó với các hạn chế về băng thông và sự biến động trong thế giới đa thiết bị.

DASH (còn gọi là MPEG-DASH) được thiết kế để cung cấp dịch vụ phân phối nội dung nghe nhìn tốt nhất có thể trong một thế giới không ổn định, cho cả nội dung phát trực tuyến và nội dung tải xuống. Một số công nghệ khác cũng làm được điều tương tự – chẳng hạn như Phát trực tuyến qua HTTP (HLS) của Apple và Truyền phát mượt mà của Microsoft – nhưng DASH là phương thức duy nhất để truyền phát tốc độ bit thích ứng qua HTTP dựa trên một tiêu chuẩn mở. DASH đã được các trang web như YouTube sử dụng.

Điều này có liên quan gì đến EME và MSE? Việc triển khai DASH dựa trên MSE có thể phân tích cú pháp tệp kê khai, tải các phân đoạn video xuống ở tốc độ bit thích hợp và cấp dữ liệu vào phần tử video khi đói – bằng cách sử dụng cơ sở hạ tầng HTTP hiện có.

Nói cách khác, DASH cho phép các nhà cung cấp nội dung thương mại truyền trực tuyến nội dung được bảo vệ theo cách thích ứng.

DASH làm đúng như những gì được giới thiệu:

  • Động: phản hồi các điều kiện thay đổi.
  • Thích ứng: thích ứng để cung cấp tốc độ bit âm thanh hoặc video phù hợp.
  • Phát trực tuyến: cho phép phát trực tuyến cũng như tải xuống.
  • HTTP: hỗ trợ phân phối nội dung với ưu điểm của HTTP mà không có các nhược điểm của máy chủ truyền trực tuyến truyền thống.

BBC đã bắt đầu cung cấp các luồng thử nghiệm bằng DASH:

Tóm tắt:

  1. Nội dung nghe nhìn được mã hoá ở nhiều tốc độ bit.
  2. Các tệp có tốc độ bit khác nhau đều được cung cấp từ máy chủ HTTP.
  3. Một ứng dụng web sẽ chọn tốc độ bit để truy xuất và phát bằng DASH.

Trong quá trình phân đoạn video, tệp kê khai XML còn được gọi là Mô tả bản trình bày nội dung nghe nhìn (MPD) được xây dựng theo chương trình. Phần này mô tả Tập điều chỉnh và Đại diện, cùng với thời lượng và URL. MPD có dạng như sau:

<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>

(Tệp XML này được lấy từ tệp .mpd dùng cho trình phát minh hoạ YouTube DASH)

Theo thông số kỹ thuật DASH, về lý thuyết, tệp MPD có thể được dùng làm src cho video. Tuy nhiên, để mang lại sự linh hoạt hơn cho nhà phát triển web, các nhà cung cấp trình duyệt đã chọn để lại việc hỗ trợ DASH cho các thư viện JavaScript sử dụng MSE, chẳng hạn như dash.js. Việc triển khai DASH trong JavaScript cho phép thuật toán thích ứng phát triển mà không cần cập nhật trình duyệt. Việc sử dụng MSE cũng cho phép thử nghiệm với các định dạng tệp kê khai và cơ chế phân phối thay thế mà không cần thay đổi trình duyệt. Shaka Player của Google triển khai một ứng dụng DASH có hỗ trợ EME.

Mạng nhà phát triển Mozilla có hướng dẫn về cách sử dụng các công cụ WebM và FFmpeg để phân đoạn video và tạo MPD.

Kết luận

Việc sử dụng web để phân phối video và âm thanh có tính phí đang tăng lên với tốc độ rất lớn. Có vẻ như mọi thiết bị mới, cho dù là máy tính bảng, máy chơi trò chơi, TV thông minh hay hộp giải mã tín hiệu số, đều có thể truyền trực tuyến nội dung nghe nhìn từ các nhà cung cấp nội dung chính qua HTTP. Hơn 85% trình duyệt dành cho thiết bị di động và máy tính hiện hỗ trợ <video><audio>. Theo ước tính của Cisco, video sẽ chiếm 80 đến 90% lưu lượng truy cập Internet của người tiêu dùng trên toàn cầu vào năm 2017. Trong bối cảnh này, khả năng hỗ trợ của trình duyệt đối với việc phân phối nội dung được bảo vệ có thể ngày càng trở nên quan trọng, vì các nhà cung cấp trình duyệt sẽ cắt giảm khả năng hỗ trợ đối với các API mà hầu hết trình bổ trợ nội dung nghe nhìn đều dựa vào.

Tài liệu đọc thêm

Thông số kỹ thuật và tiêu chuẩn

Bài viết