如何获取 JavaScript 中创建的音频元素的文件大小?
How can I get the file size of a created audio element in JavaScript?
如何获取非DOM创建的音频元素的文件大小?
我想我可以使用 HTML5 文件 API – 根据 Client Checking file size using HTML5? – 但它似乎不适用于不在 DOM 中的元素.
我在下面创建了一个示例 – 请参阅行 console.log(audio_file.files[0].size);
,它给出了一个错误:
TypeError: audio_file.files is undefined
// Create a non-dom allocated Audio element
var audio_file = document.createElement('audio');
// Define the URL of the MP3 audio file
audio_file.src = "https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3";
// Once the metadata has been loaded, display the duration in the console
audio_file.addEventListener('loadedmetadata', function(){
// Obtain the duration in seconds of the audio file
var duration = audio_file.duration;
const duration_hhmmss = new Date(duration * 1000).toISOString().substr(11, 8);
console.log("The duration of the song is of: " + duration_hhmmss);
console.log(audio_file.files[0].size);
},false);
我尝试进行 fetch
调用并从 blob 计算文件的大小。
但缺点是,在文件完全加载之前我们无法知道文件的大小,因为给定 mp3 url 的响应 headers 没有任何与大小相关的信息。
这里我设置了获取到音频元素后的音频数据,但这不是必须的。我只是添加它来播放音频文件。
(按下 运行 代码片段 后,您必须等到文件加载后才能看到结果。)
const audioEl = document.querySelector('audio');
fetch(
"https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3"
)
.then((response) => {
// console.log(response);
return response.body
})
.then((data) => {
var reader = data.getReader();
return new ReadableStream({
start(controller) {
return pump();
function pump() {
return reader.read().then(({ done, value }) => {
// When no more data needs to be consumed, close the stream
if (done) {
controller.close();
return;
}
// Enqueue the next data chunk into our target stream
controller.enqueue(value);
return pump();
});
}
}
});
})
.then((stream) => new Response(stream, {headers: {'Content-Type': 'audio/mpeg'}}))
.then((response) => response.blob())
.then(blob => {
// console.log(blob);
const reader = new FileReader();
reader.addEventListener('loadend', () => {
audioEl.src = reader.result; // output of reader.readAsDataURL
});
reader.readAsDataURL(blob);
const sizeInByte = blob.size;
const sizeInMB = sizeInByte / 1024 / 1024;
document.querySelector('#size').innerText = `Size of the loaded audio is ${sizeInMB.toFixed(2)}MB`;
});
<audio controls></audio>
<div id="size"></div>
如何获取非DOM创建的音频元素的文件大小?
我想我可以使用 HTML5 文件 API – 根据 Client Checking file size using HTML5? – 但它似乎不适用于不在 DOM 中的元素.
我在下面创建了一个示例 – 请参阅行 console.log(audio_file.files[0].size);
,它给出了一个错误:
TypeError: audio_file.files is undefined
// Create a non-dom allocated Audio element
var audio_file = document.createElement('audio');
// Define the URL of the MP3 audio file
audio_file.src = "https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3";
// Once the metadata has been loaded, display the duration in the console
audio_file.addEventListener('loadedmetadata', function(){
// Obtain the duration in seconds of the audio file
var duration = audio_file.duration;
const duration_hhmmss = new Date(duration * 1000).toISOString().substr(11, 8);
console.log("The duration of the song is of: " + duration_hhmmss);
console.log(audio_file.files[0].size);
},false);
我尝试进行 fetch
调用并从 blob 计算文件的大小。
但缺点是,在文件完全加载之前我们无法知道文件的大小,因为给定 mp3 url 的响应 headers 没有任何与大小相关的信息。
这里我设置了获取到音频元素后的音频数据,但这不是必须的。我只是添加它来播放音频文件。
(按下 运行 代码片段 后,您必须等到文件加载后才能看到结果。)
const audioEl = document.querySelector('audio');
fetch(
"https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3"
)
.then((response) => {
// console.log(response);
return response.body
})
.then((data) => {
var reader = data.getReader();
return new ReadableStream({
start(controller) {
return pump();
function pump() {
return reader.read().then(({ done, value }) => {
// When no more data needs to be consumed, close the stream
if (done) {
controller.close();
return;
}
// Enqueue the next data chunk into our target stream
controller.enqueue(value);
return pump();
});
}
}
});
})
.then((stream) => new Response(stream, {headers: {'Content-Type': 'audio/mpeg'}}))
.then((response) => response.blob())
.then(blob => {
// console.log(blob);
const reader = new FileReader();
reader.addEventListener('loadend', () => {
audioEl.src = reader.result; // output of reader.readAsDataURL
});
reader.readAsDataURL(blob);
const sizeInByte = blob.size;
const sizeInMB = sizeInByte / 1024 / 1024;
document.querySelector('#size').innerText = `Size of the loaded audio is ${sizeInMB.toFixed(2)}MB`;
});
<audio controls></audio>
<div id="size"></div>