本文主要介绍了 ArrayBuffer、Blob、File、FileReader、MediaSource 之间的关系。ArrayBuffer 是固定长度的二进制数据缓冲区,通过 TypedArray 或 DataView 操作,常用于网络技术处理二进制数据。Blob 是类文件对象,File 是其子类。它们可通过特定方式创建、操作和应用。FileReader 用于异步读取文件内容。MediaSource 是媒体资源接口,与其他对象存在一定关联。
关联问题: 如何优化ArrayBuffer性能 FileReader使用注意事项 MediaSource的优势在哪
ArrayBuffer
ArrayBuffer
表示一个通用的、固定长度的原始二进制数据缓冲区。
ArrayBuffer
不能直接操作,而是通过类型化数组视图(TypedArray)(比如 Uint8Array
、Float32Array
等)或者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:将来自 ArrayBuffer
、TypedArray
或 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
,包含ArrayBuffer
、TypedArray
、DataView
、Blob
、字符串或者任意这些元素的混合,这些元素将会被放入Blob
中。
options:一个可以指定以下任意属性的对象,type
(将会被存储到 blob 中的数据的 MIME 类型),endings
(如果数据是文本,那么如何解释其中的换行符\n
)
_new File(blobParts, fileName, options): _
fileName:表示文件名或文件路径的字符串。
options:除type
、endings
外,还可指定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 可以用于img
、video
、audio
等元素的src
属性。
其中object
指用于创建 URL 的File
、Blob
或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
MediaSource
是 Media Source Extensions API(媒体源扩展 API(MSE))中用于表示媒体资源 HTMLMediaElement
对象的接口。
使用 MSE,媒体串流能够通过 JavaScript 创建,并且能通过使用 <audio>
和 <video>
元素进行播放。
由于这块内容涉及面广,且本文主要介绍 ArrayBuffer
和 MediaSource
的关系,就不在此对 MSE
做展开介绍。 感兴趣的也可以看下上一篇 前端实时播放摄像头RTSP流(H.265)解决方案,有涉及到相关介绍和应用。
总结
总体关系可大致为下面两条线: