前言
今天实现一个拖动音乐上传的demo(demo在线地址待补充)
准备工作
阅读这篇开发笔记之前,请读者具备以下知识点
源码解析
废话不多说,直接上码了
下面是vue里面template的内容
<div id="holder"
:class="{hover:isdragging}"
@drop.prevent="uploadMusic($event)"
@dragover.prevent="dragover($event)"
@dragend="dragend()">
</div>
这是vue,如果读者没有vue开发经验也没关系,这里主要绑定了三个事件,其中加了prevent的相当于最先加了一句preventdefault,不然拖文件到浏览器会直接打开url,让我们看看这三个事件的代码。
dragover(event) {
this.isdragging = true;
},
dragend() {
this.isdragging = false;
},
uploadMusic(event) {
let self = this
console.dir(event)
console.dir(event.dataTransfer)
console.dir(event.dataTransfer.files[0])
let file = event.dataTransfer.files[0]
if (file.type.match('audio*')) {
var reader = new FileReader()
// read the mp3 and decode the audio.
reader.onload = function(readEvent) {
self.context.decodeAudioData(readEvent.target.result)
.then(function(buffer) {
self.mediaBuffer = buffer;
self.playStream();
})
};
reader.readAsArrayBuffer(file);
}
},
注:context就是我存的一个this.context = new AudioContext();
dragover和dragend没啥好说的,核心在于触发drop后执行的uploadMusic函数。
拖动后event里面的dataTransfer就有我们拖动过去的文件了,具体读者可以参考drop事件及拖动文件里关于dataTransfer的部分或者自己查阅相关资料。
我们首先获取到了一个文件对象file
let file = event.dataTransfer.files[0]
然后我们新建了一个FileReader准备读取这个文件,读取完后调用decodeAudioData(AudioContect的方法)异步的解码ArrayBuffer里面的音频文件数据,解码完后我们调用了playStream方法,下面是其简化后的代码
playStream( {
this.mediaSource = this.context.createBufferSource(); //context是之前创建的一个AudioContext对象
this.mediaSource.buffer = this.mediaBuffer; //mediaBuffer是之前解码后保存下来的buffer
this.mediaSource.connect(this.context.destination);
this.mediaSource.start();
}
context.createBufferSource返回一个AudioBufferSourceNode对象
这里有个继承关系AudioBufferSourceNode < AudioScheduledSourceNode < AudioNode
connect是AudioNode的一个方法,用来连接一个输出,这里this.context.destination相当于客户端计算机上的一个音频播放设备,相当于把start之后输出到这个音频设备(也就是播放音乐)
如此,一个将音乐拖动到指定div后播放的demo完成喽。
在线demo
等我把整个骚东西弄完先
网友评论