Reading/writing/copying 一个 ArrayBuffer 到另一个具有偏移量的 ArrayBuffer
Reading/writing/copying an ArrayBuffer into another ArrayBuffer with an offset
假设我有一个 ArrayBuffer
,它是一个 mp4
文件。我想用一些额外的字节创建一个新的 ArrayBuffer
用作 header 信息,然后将 mp4
缓冲区存储在新 ArrayBuffer
的剩余部分中.
// ... assume the `data` variable is an existing ArrayBuffer with the contents
// of the mp4 video file.
var ab = new ArrayBuffer(10 + data.byteLength)
var view = new DataView(ab);
view.setInt32(0, 29102); // header information 1
view.setInt32(4, 18282); // header information 2
view.setInt16(8, 576); // header information 3
现在,在这一点上,我不知道如何将 data
的内容写入新的 ab
缓冲区,所以,最后我有一个 ArrayBuffer
其中包含开头的3组数字,以及视频的全部内容。
我尝试使用以下方法:
view.setInt32(10, data.buffer)
虽然我没有收到任何错误,但数据实际上并没有写入缓冲区。我无法将视频写入文件并播放:
function readPayload(ab) {
var view = new DataView(ab);
console.log(' first header: ' + view.getInt32(0)); // correct
console.log('second header: ' + view.getInt32(4)); // correct
console.log(' third header: ' + view.getInt16(8)); // correct
var data = new Buffer(ab.slice(10));
console.log('new file size: ' + data.byteLength); // correct length of mp4 file
var ws = fs.createWriteStream('test.mp4'); // this wrote a corrupt file
ws.write(data);
ws.end();
}
在上面的函数中,我检索到的所有数字都是正确的,但是当我尝试将有效负载数据写入文件时,文件大小正确,但文件已损坏。
file size: 5253880
buffer size: 5253890
-- reading data
first header: 29102
second header: 18282
third header: 576
new file size: 5253880
所以我无法判断它是否被错误地存储在新的 ArrayBuffer
中,或者我是否错误地提取了缓冲区 - 但是写入的 test.mp4
不包含正确的二进制数据。
经过更多的挖掘,我终于能够拼凑出一个可行的解决方案。这成功地将 mp4
ArrayBuffer
的内容从偏移量 (具有 header 信息) 复制到新的 ArrayBuffer
:
new Uint8Array(ab, 0, ab.byteLength).set(new Uint8Array(data), 10);
在这里,我在 ArrayBuffer
上创建了一个 Uint8Array
类型的视图,其中还包含 header 信息 (ab
)。指定我用来创建 ArrayBuffer
.
的相同大小
有了那个新创建的视图,然后我调用了 .set
函数,第一个参数是原来的 mp4
ArrayBuffer
我 也 给出 Uint8Array
视图,并告诉 set
命令从偏移量 10
.
开始
这会将 data
的所有内容从 10
的偏移量分配给 ab
。
假设我有一个 ArrayBuffer
,它是一个 mp4
文件。我想用一些额外的字节创建一个新的 ArrayBuffer
用作 header 信息,然后将 mp4
缓冲区存储在新 ArrayBuffer
的剩余部分中.
// ... assume the `data` variable is an existing ArrayBuffer with the contents
// of the mp4 video file.
var ab = new ArrayBuffer(10 + data.byteLength)
var view = new DataView(ab);
view.setInt32(0, 29102); // header information 1
view.setInt32(4, 18282); // header information 2
view.setInt16(8, 576); // header information 3
现在,在这一点上,我不知道如何将 data
的内容写入新的 ab
缓冲区,所以,最后我有一个 ArrayBuffer
其中包含开头的3组数字,以及视频的全部内容。
我尝试使用以下方法:
view.setInt32(10, data.buffer)
虽然我没有收到任何错误,但数据实际上并没有写入缓冲区。我无法将视频写入文件并播放:
function readPayload(ab) {
var view = new DataView(ab);
console.log(' first header: ' + view.getInt32(0)); // correct
console.log('second header: ' + view.getInt32(4)); // correct
console.log(' third header: ' + view.getInt16(8)); // correct
var data = new Buffer(ab.slice(10));
console.log('new file size: ' + data.byteLength); // correct length of mp4 file
var ws = fs.createWriteStream('test.mp4'); // this wrote a corrupt file
ws.write(data);
ws.end();
}
在上面的函数中,我检索到的所有数字都是正确的,但是当我尝试将有效负载数据写入文件时,文件大小正确,但文件已损坏。
file size: 5253880
buffer size: 5253890
-- reading data
first header: 29102
second header: 18282
third header: 576
new file size: 5253880
所以我无法判断它是否被错误地存储在新的 ArrayBuffer
中,或者我是否错误地提取了缓冲区 - 但是写入的 test.mp4
不包含正确的二进制数据。
经过更多的挖掘,我终于能够拼凑出一个可行的解决方案。这成功地将 mp4
ArrayBuffer
的内容从偏移量 (具有 header 信息) 复制到新的 ArrayBuffer
:
new Uint8Array(ab, 0, ab.byteLength).set(new Uint8Array(data), 10);
在这里,我在 ArrayBuffer
上创建了一个 Uint8Array
类型的视图,其中还包含 header 信息 (ab
)。指定我用来创建 ArrayBuffer
.
有了那个新创建的视图,然后我调用了 .set
函数,第一个参数是原来的 mp4
ArrayBuffer
我 也 给出 Uint8Array
视图,并告诉 set
命令从偏移量 10
.
这会将 data
的所有内容从 10
的偏移量分配给 ab
。