本文主要介绍了 ArrayBuffer、Blob、File、FileReader、MediaSource 之间的关系。ArrayBuffer 是固定长度的二进制数据缓冲区,通过 TypedArray 或 DataView 操作,常用于网络技术处理二进制数据。Blob 是类文件对象,File 是其子类。它们可通过特定方式创建、操作和应用。FileReader 用于异步读取文件内容。MediaSource 是媒体资源接口,与其他对象存在一定关联。

关联问题: 如何优化ArrayBuffer性能 FileReader使用注意事项 MediaSource的优势在哪

ArrayBuffer

ArrayBuffer 表示一个通用的、固定长度的原始二进制数据缓冲区。
ArrayBuffer 不能直接操作,而是通过类型化数组视图(TypedArray)(比如 Uint8ArrayFloat32Array 等)或者DataView 来操作。

应用:ArrayBuffer 经常与 Fetch API、WebSocket 等网络技术一起使用,用于处理二进制数据的接收和发送;可以用来处理文件、图像、音频、视频等二进制数据。

1. 创建实例

 1const buffer = new ArrayBuffer(16); 

2. 操作实例

1)类型化数组视图(TypedArray)
 1const view = new Uint8Array(buffer); 
 2view[0] = 255; 
2)DataView
 1const view = new DataView(buffer, 0);
 2view.setUint8(0, 255); 

3. 使用举例

刚好上一篇 前端实时播放摄像头RTSP流(H.265)解决方案 有用到

1)转换为字符串

我们不能直接将 ArrayBuffer 转换为字符串,但可以通过类型化数组视图等来实现:

 1private onWebSocketMessage = (buffer: ArrayBuffer) => { 
 2    const unit = new Uint8Array(buffer) 
 3    let unitCharCodeStr = '' 
 4    unit.forEach((u) => { 
 5        unitCharCodeStr += String.fromCharCode(u) 
 6    })
 7    console.log(unitCharCodeStr);
 8}
2)实时播放流媒体文件

SourceBuffer.appendBuffer:将来自 ArrayBufferTypedArray 或 DataView 对象的媒体片段数据附加到 SourceBuffer
官方示例:

 1const assetURL = "frag_bunny.mp4";
 2const mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
 3
 4if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
 5  const mediaSource = new MediaSource();
 6  
 7  mediaSource.addEventListener("sourceopen", sourceOpen);
 8  video.src = URL.createObjectURL(mediaSource);
 9} else {
10  console.error("Unsupported MIME type or codec: ", mimeCodec);
11}
12
13function sourceOpen() {
14  
15  const mediaSource = this;
16  const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
17  fetchAB(assetURL, function (buf) {
18    sourceBuffer.addEventListener("updateend", () => {
19      mediaSource.endOfStream();
20      video.play();
21      
22    });
23    sourceBuffer.appendBuffer(buf);
24  });
25}

Blob、File

Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。
File 是 Blob 的一个子类,表示文件系统中的文件,扩展了 name 、 lastModified 等属性,可以在 Blob 可以使用的任何上下文中使用。

应用:通常用于处理文件或二进制数据流,比如从网络下载文件或用户上传文件到服务器。

1. 创建实例

_new Blob(blobParts, options): _
blobParts:一个可迭代对象,比如 Array,包含 ArrayBufferTypedArrayDataViewBlob、字符串或者任意这些元素的混合,这些元素将会被放入 Blob中。
options:一个可以指定以下任意属性的对象,type(将会被存储到 blob 中的数据的 MIME 类型),endings(如果数据是文本,那么如何解释其中的换行符\n

_new File(blobParts, fileName, options): _
fileName:表示文件名或文件路径的字符串。
options:除typeendings外,还可指定lastModified(一个数字,表示 Unix 时间纪元与文件上次修改时间之间的毫秒数,默认值为 Date.now()返回值)

 1
 2const blobParts = ['<q id="a"><span id="b">hey!</span></q>']; 
 3const blob = new Blob(blobParts, { type: "text/html" }); 
 4
 5
 6const file = new File(["foo"], "foo.txt", {
 7  type: "text/plain",
 8});

在实际应用中,File 对象通常从用户使用<input>元素选择文件返回的FileList对象中检索,或者从拖放操作返回的DataTransfer对象中检索

2. 操作实例

File可以在 Blob 可以使用的任何上下文中使用

1)实例方法:可读取或切片数据

2)通过FileReader 读取数据
 1const reader = new FileReader();
 2reader.onload = function(event) {
 3  console.log(event.target.result); 
 4};
 5reader.readAsText(blob);

FileReader 相关API介绍见后文

3)利用URL.createObjectURL(blob)将 Blob 转换为 URL
 1const url = URL.createObjectURL(blob);
 2
 3const img = document.createElement('img');
 4img.src = url;
 5img.onload = () => {
 6    URL.revokeObjectURL(img.src);
 7};
 8document.body.appendChild(img);

URL.createObjectURL(object):
该静态方法对 object 对象创建一个临时的、唯一的 URL,它指向一个内存中的文件对象,而不是实际的文件系统中的文件。这个 URL 可以用于 imgvideoaudio 等元素的 src 属性。
其中 object 指用于创建 URL 的 FileBlob 或 MediaSource对象。

3. 使用举例

 1<input type="file" id="fileInput">
1)本地图片预览(File
 1const fileInput = document.getElementById('fileInput');
 2
 3fileInput.addEventListener('change', (event) => {
 4  const files = event.target.files;
 5  if (files.length > 0) {
 6    const file = files[0];
 7    const img = document.createElement('img');
 8    
 9    
10    const url = URL.createObjectURL(file);
11    img.src = url; 
12    img.onload = () => { 
13        URL.revokeObjectURL(img.src); 
14    }; 
15    
16    
17    
18    
19    const reader = new FileReader();
20    reader.onload = function(e) {
21        img.src = e.target.result;
22    };
23    reader.readAsDataURL(file); 
24    
25    
26    document.body.appendChild(img);
27  }
28});
2)本地文件上传(File
 1const fileInput = document.getElementById('fileInput');
 2
 3fileInput.addEventListener('change', (event) => {
 4  const files = event.target.files;
 5  if (files.length > 0) {
 6    const file = files[0];
 7    const formData = new FormData();
 8    formData.append('file', file);
 9    fetch('xxxxx', {
10      method: 'POST',
11      body: formData
12    })
13    .then(response => response.json())
14  }
15});
16
3)文件下载(Blob
 1
 2fetch('xxxxxxx')
 3    .then(response => response.blob())
 4    .then(blob => {
 5        var url = URL.createObjectURL(blob);
 6        var a = document.createElement('a');
 7        a.href = url;
 8        a.download = 'filename.txt';
 9        document.body.appendChild(a);
10        a.click();
11        a.remove();
12        URL.revokeObjectURL(url);
13    })
 1
 2const testJson = {
 3    config: {"aa": 11, "bb": 22},
 4    inputDatas: [{"int1":23}, {"int2":34}]
 5};
 6const jsonBlob = new Blob([JSON.stringify(testJson, null, 2)], {type: 'application/json'});
 7
 8const url = window.URL.createObjectURL(jsonBlob);
 9let a = window.document.createElement('a');
10a.href = url;
11a.download = 'test.json';
12document.body.appendChild(a);
13a.click();
14document.body.removeChild(a);
15URL.revokeObjectURL(url);

FileReader

FileReader 允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
文件对象可以从 <input> 选择文件后的 FileList 中获取,或者从拖放的 DataTransfer 中获取。

应用:提供一种方便的方式在客户端处理文件,无需服务器的介入。使得可以实现如图片预览、文件内容编辑等客户端功能。

1. 创建实例

 1const reader = new FileReader();

2. 操作实例

当读取操作完成时,readyState 属性变为 DONE,并触发 loadend 事件

3. 使用举例

使用 FileReader 读取文本文件

 1document.getElementById('fileInput').addEventListener('change', function(event) {
 2  const file = event.target.files[0];
 3  if (file) {
 4    const reader = new FileReader();
 5    
 6    reader.onload = function(e) {
 7      console.log(e.target.result); 
 8    };
 9    reader.onerror = function(e) {
10      console.error('读取文件时出错:', e.target.error);
11    };
12    
13    reader.readAsText(file); 
14  }
15});

其他API使用,例如 readAsDataURL 已在上文提及,就不再赘述

MediaSource

MediaSourceMedia Source Extensions API(媒体源扩展 API(MSE))中用于表示媒体资源 HTMLMediaElement 对象的接口。
使用 MSE,媒体串流能够通过 JavaScript 创建,并且能通过使用 <audio> 和 <video> 元素进行播放。

由于这块内容涉及面广,且本文主要介绍 ArrayBufferMediaSource 的关系,就不在此对 MSE 做展开介绍。 感兴趣的也可以看下上一篇 前端实时播放摄像头RTSP流(H.265)解决方案,有涉及到相关介绍和应用。

总结

总体关系可大致为下面两条线:

个人笔记记录 2021 ~ 2025