【问题标题】:Saving Audio to localStorage for Playback将音频保存到 localStorage 以供播放
【发布时间】:2017-10-04 14:29:24
【问题描述】:

我正在尝试创建一个从中提取 mp3 文件的函数

<input type="file" id="sound" accept="audio/*"/>

并存储在 Chrome 中的 localStorage 中。 (我知道 localStorage 的大小是有限的,但我将使用的音频文件将小于 2mb。)一旦这个音频文件被存储,它将被播放:

var audio = new Audio('audioFile');
audio.play();

我还是网络开发的新手,所以任何指针都会很棒!

注意:这不是 HTML5 record audio to file 的副本。我正在尝试从我的 HDD 中获取一个预先存在的 mp3 文件并将其存储到 localStorage 以便可以播放。

【问题讨论】:

  • 到目前为止您尝试过什么?请展示你的作品。
  • 目前我只提供用户可以选择的各种 mp3 文件。到目前为止,我尝试的是使用 getElementById 从“文件”获取路径,然后在新音频中使用该路径,但这是不正确的。我什至还没有尝试保存到 localStorage。
  • 未来,在来SO之前至少要尝试一下。这不是一个建议论坛,而是具体的问答。
  • 我已经搜索了几个小时才来到这里。我更喜欢在来这里被骂之前弄清楚一个过程。

标签: javascript html audio local-storage


【解决方案1】:

localStorage 并不意味着存储此类数据。相反,您应该使用用于存储此类数据的IndexedDB API

使用 Mozilla 的 localForage 库高度简化了 indexedDB 的处理,它提供了类似于 localStorage 的语法。

Fiddle 因为 StackSnippets® 不允许访问 indexedDB 和 localStorage。


但是要将文件(或 Blob)转换为字符串,根据 localStorage API 的需要,您可以使用FileReader 及其readAsDataURL() 方法,该方法将提供dataURI,可由MediaElements 直接播放.

f.onchange = e =>{
  if(f.files[0].type.indexOf('audio/') !== 0){
    console.warn('not an audio file');
    return;
    }
  const reader = new FileReader();
  reader.onload = function(){
    var str = this.result;
    // this is a string, so you can store it in localStorage, even if it's really not a good idea
    console.log(str);
    const aud = new Audio(str);
    aud.play();
    };
  reader.readAsDataURL(f.files[0]);
  }
&lt;input type="file" id="f"&gt;

【讨论】:

  • 我希望我可以使用它,但遗憾的是,每当我将 localforage 添加到脚本源时,我都会收到此错误:“拒绝加载脚本,因为它违反了以下内容安全策略指令:”script- src 'self' syndication.twitter.com"."
  • @RockGuitarist1,您是否也尝试从 rawgit 加载脚本?您的 CSP 似乎配置为仅允许与您的页面和来自 twitter 的来源相同的脚本。因此,如果您在服务器上下载脚本并从服务器加载它,它应该可以工作。
  • 其实我下载了localforage并导入到项目中。然后我使用:&lt;script src="../localforage/dist/localforage.js"&gt;&lt;/script&gt; &lt;script&gt;localforage.getItem('something', myCallback);&lt;/script&gt;,它仍然抛出错误。我实际上正在开发一个开源的 Chrome 扩展程序。
  • 那么我猜你必须将它包含在你的扩展清单中,但我对扩展的了解非常有限。请注意,可能还有一个更好的 API 可以从扩展中保存文件,您可以访问比我们这些可怜的 web 开发人员更强大的 API。但这会完全改变你的问题。
  • 听起来这是我必须做的事情。我已经让以前的方法按照我想要的方式工作,但是这种方法会更好,因为我可以控制音量。
【解决方案2】:

这不是 localStorage 的用途。 localStorage 只能存储字符串,只能容纳少量的日期。

如果你真的决心这样做,你需要:

请注意,Base64 编码通常会使源素材的大小增加约 33%。这是因为它可以接受任何类型的数据,包括二进制数据,并将其转换为与标准 ASCII 字符串兼容的 64 字符集组成的字符串。

要播放它,你需要相反

  • 从 localStorage 中检索 Base64 编码的字符串
  • 将 Base64 字符串解码为 ArrayBuffer
  • 将 ArrayBuffer 加载到音频对象中
  • 将 Audio 对象分配给 &lt;audio&gt; 元素

还需要注意的是,localStorage 通常只分配 5-10MB 的存储空间,具体取决于浏览器。这可以是tested here,但通常,通过使用较低的比特率对其进行编码来保持您的 mp3 文件较小,尽可能使用单声道而不是立体声声道,如果音频只是口语而不是音乐,则降低采样率。

【讨论】:

  • 这就是我要找的。谢谢!
  • 哇,不要通过 ArrayBuffer 也不要自己进行 b64 转换...您可以简单地使用 FileReader 及其 readAsDataURL 方法。而且您也不需要将 dataURI 传递给 arrayBuffer 来播放它,您只需将 b64 dataURI 传递给 Audio 元素即可。如果它不是AudioElement,你必须解释什么是音频对象
  • @Kaiido 如果您有更好的方法,请写另一个答案并附上完整的解释,或者添加您所说的内容作为编辑,因为您有足够的代表。
猜你喜欢
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
  • 1970-01-01
  • 2016-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多