JS 媒体相关类型介绍以及相互转换

637 阅读2分钟

类型介绍

Blob

Blob 对象表示一个不可变、原始数据的类文件对象。

type BlobPart = ArrayBufferView | ArrayBuffer | Blob | string;

interface BlobPropertyBag {
  endings?: EndingType;
  type?: string;
}

declare var Blob: {
  prototype: Blob;
  new(blobParts?: BlobPart[], options?: BlobPropertyBag): Blob;
};

new Blob(array, options);
// 试一试
fetch('http://storage.icyc.cc/avatar/fe5c41e74c316188d95768a837996b5b')
  .then(v => v.blob())
  .then(v => {
    // Blob
    console.log('Blob', v)
    // ReadableStream
    console.log('stream', v.stream())
    // ArrayBuffer
    v.arrayBuffer().then(buffer => console.log('buffer', buffer))
    // String
    v.text().then(text => console.log('text', text))
  })

File

File 接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容。

File 对象是特殊类型的 Blob 。 FileReader, URL.createObjectURL(), createImageBitmap() (en-US), 及 XMLHttpRequest.send() 都能处理 Blob 和 File。

type BlobPart = ArrayBufferView | ArrayBuffer | Blob | string;

interface BlobPropertyBag {
  endings?: EndingType;
  type?: string;
}

interface FilePropertyBag extends BlobPropertyBag {
  lastModified?: number;
}

interface File extends Blob {
  readonly lastModified: number;
  readonly name: string;
  readonly webkitRelativePath: string;
}

declare var File: {
  prototype: File;
  new(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): File;
};

Data URLs

Data URLs,即前缀为 data: 协议的 URL,其允许内容创建者向文档中嵌入小文件。

data:[<mediatype>][;base64],<data>

Object URL

URL.createObjectURL() 返回一个DOMString ,包含一个唯一的 blob 链接(该链接协议为以 blob:,后跟唯一标识浏览器中的对象的掩码)。

declare var URL: {
  prototype: URL;
  new(url: string | URL, base?: string | URL): URL;
  createObjectURL(obj: Blob | MediaSource): string;
  revokeObjectURL(url: string): void;
};

objectURL = URL.createObjectURL(object);

Base64

What: Base64 是一组相似的二进制到文本(binary-to-text)的编码规则。

When: 普遍应用于传输二进制数据的场景。

Why: 由于 ASCII 字符串的 128~255 之间值不可见,所以使用 Base64 可以防止传输过程中被不同平台修改。

How: btoa() 编码, atob() 解码。

ArrayBuffer

ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。

new ArrayBuffer(length)

Uint8Array

Uint8Array 数组类型表示一个 8 位无符号整型数组。

new Uint8Array(); // ES2017 最新语法
new Uint8Array(length); // 创建初始化为 0 的,包含 length 个元素的无符号整型数组
new Uint8Array(typedArray);
new Uint8Array(object);
new Uint8Array(buffer [, byteOffset [, length]]);

MediaStream

MediaStream 接口是一个媒体内容的流.。一个流包含几个轨道,比如视频和音频轨道。

例如下面 getUserMedia 返回的就是 MediaStream 。

'use strict';

// Put variables in global scope to make them available to the browser console.
var video = document.querySelector('video');
var constraints = window.constraints = {
  audio: false,
  video: true
};
var errorElement = document.querySelector('#errorMsg');

navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  var videoTracks = stream.getVideoTracks();
  console.log('Got stream with constraints:', constraints);
  console.log('Using video device: ' + videoTracks[0].label);
  stream.onended = function() {
    console.log('Stream ended');
  };
  window.stream = stream; // make variable available to browser console
  video.srcObject = stream;
})
.catch(function(error) {
  if (error.name === 'ConstraintNotSatisfiedError') {
    errorMsg('The resolution ' + constraints.video.width.exact + 'x' +
        constraints.video.width.exact + ' px is not supported by your device.');
  } else if (error.name === 'PermissionDeniedError') {
    errorMsg('Permissions have not been granted to use your camera and ' +
      'microphone, you need to allow the page access to your devices in ' +
      'order for the demo to work.');
  }
  errorMsg('getUserMedia error: ' + error.name, error);
});

function errorMsg(msg, error) {
  errorElement.innerHTML += '<p>' + msg + '</p>';
  if (typeof error !== 'undefined') {
    console.error(error);
  }
}

相互转换

注意:file 是 特殊的 blob ,blob 的转换,同样适用于 file 。

File 转 DataURL

// 通过 FileReader
var reader = new FileReader();
reader.onload = function(evt) {
  console.log(evt.target.result); // DataURL
};
reader.readAsDataURL(file);

// 通过 file.arrayBuffer
file.arrayBuffer().then((buffer) => {
  const str = String.fromCharCode(...new Uint8Array(buffer));
  const dataUrl = `data:${file.type};base64,${window.btoa(str)}`;
  console.log(dataUrl); // DataURL
});

DataUrl 转 Blob

function dataURLToBlob(dataURL) {
  // Code taken from https://github.com/ebidel/filer.js
  var parts = dataURL.split(';base64,');
  var contentType = parts[0].split(":")[1];
  var raw = window.atob(parts[1]);
  var rawLength = raw.length;
  var uInt8Array = new Uint8Array(rawLength);

  for (var i = 0; i < rawLength; ++i) {
    uInt8Array[i] = raw.charCodeAt(i);
  }

  return new Blob([uInt8Array], { type: contentType });
}

Blob 转 ArrayBuffer

Blob API 即可

blob.arrayBuffer().then(buffer => console.log('buffer', buffer))
``