6 Commits

Author SHA1 Message Date
Gennady Grishkovtsov
206216643a Update version to 2.1.0 2018-09-30 16:01:51 +03:00
Gennady Grishkovtsov
fc0c9c824a Add record removing feature 2018-09-30 15:54:50 +03:00
Gennady Grishkovtsov
261d7a80ec Add decorator for all player buttons 2018-09-30 15:54:50 +03:00
Gennady Grishkovtsov
860f7e6158 Add random ID for each record 2018-09-30 15:54:42 +03:00
Gennady Grishkovtsov
83ccce2374 Merge pull request #1 from Tomotoes/var-fs
Add :key attribute for "v-for" to recorder.vue
2018-08-20 11:59:20 +03:00
JinmaQAQ
cb7a410ae5 Modify recorder.vue 2018-08-20 11:14:14 +08:00
6 changed files with 76 additions and 46 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
{
"name": "vue-audio-recorder",
"description": "Audio recorder for Vue.js. It allows to create, play, download and store records on a server",
"version": "2.0.0",
"version": "2.1.0",
"author": "Gennady Grishkovtsov <grishkovelli@gmail.com>",
"license": "MIT",
"scripts": {

View File

@@ -88,20 +88,20 @@
id="download"
class="ar-icon ar-icon__sm"
name="download"
@click.native="download"/>
@click.native="decorator(download)"/>
<icon-button
id="play"
class="ar-icon ar-icon__lg ar-player__play"
:name="playBtnIcon"
:class="{'ar-player__play--active': isPlaying}"
@click.native="playback"/>
@click.native="decorator(playback)"/>
<icon-button
id="upload"
class="ar-icon ar-icon__sm"
name="save"
@click.native="upload"/>
@click.native="decorator(upload)"/>
</div>
<div class="ar-player-bar">
@@ -163,22 +163,23 @@
this.player.addEventListener('timeupdate', this._onTimeUpdate)
},
computed: {
audioSource () {
let url = this.src || this.record.url
if (url) {
return url
} else {
this._resetProgress()
}
},
playBtnIcon () {
return this.isPlaying ? 'pause' : 'play'
},
audioSource () {
return this.src || this.record.url
},
playerUniqId () {
return `audio-player${this._uid}`
}
},
methods: {
playback () {
if (!this.audioSource) {
return
}
if (this.isPlaying) {
this.player.pause()
} else {
@@ -188,10 +189,6 @@
this.isPlaying = !this.isPlaying
},
upload () {
if (!this.audioSource) {
return
}
if (this.startUpload) {
this.startUpload()
}
@@ -216,18 +213,27 @@
})
},
download () {
if (!this.audioSource) {
return
}
let link = document.createElement('a')
link.href = this.record.url
link.download = 'record.wav'
link.click()
},
decorator (func) {
if (!this.audioSource) {
return
}
func()
},
_resetProgress () {
this.isPlaying = false
this.progress = 0
if (this.isPlaying) {
this.player.pause()
}
setTimeout(() => {
this.duration = convertTimeMMSS(0)
this.playedTime = convertTimeMMSS(0)
this.progress = 0
this.isPlaying = false
}, 0)
},
_onTimeUpdate () {
this.playedTime = convertTimeMMSS(this.player.currentTime)

View File

@@ -23,12 +23,14 @@
&__record {
width: 320px;
height: 45px;
padding: 0 10px;
margin: 0 auto;
line-height: 45px;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #E8E8E8;
position: relative;
&--selected {
border: 1px solid #E8E8E8;
@@ -105,7 +107,7 @@
@keyframes blink {
0% { opacity: .2; }
20% { opacity: 1; }
20% { opacity: 1; }
100% { opacity: .2; }
}
}
@@ -144,6 +146,20 @@
color: red;
}
}
&__rm {
cursor: pointer;
position: absolute;
width: 6px;
height: 6px;
padding: 6px;
line-height: 6px;
margin: auto;
left: 10px;
bottom: 0;
top: 0;
color: rgb(244, 120, 90);
}
}
@import '../scss/icons';
@@ -182,9 +198,14 @@
<div class="ar-records">
<div
class="ar-records__record"
:class="{'ar-records__record--selected': idx === selectedRecord.idx}"
:class="{'ar-records__record--selected': record.id === selected.id}"
:key="record.id"
v-for="(record, idx) in recordList"
@click="selectRecord(idx, record)">
@click="selected = record">
<div
class="ar__rm"
v-if="record.id === selected.id"
@click="removeRecord(idx)">&times;</div>
<div class="ar__text">Record {{idx + 1}}</div>
<div class="ar__text">{{record.duration}}</div>
</div>
@@ -192,7 +213,7 @@
<audio-player
:compact="compact"
:record="selectedRecord"
:record="selected"
:upload-url="uploadUrl"
:start-upload="startUpload"
:successful-upload="successfulUpload"
@@ -244,7 +265,7 @@
time: this.time
}),
recordList: [],
selectedRecord: {},
selected: {},
uploadStatus: null
}
},
@@ -277,8 +298,9 @@
this.recorder.stop()
},
selectRecord (idx, record) {
this.selectedRecord = { idx: idx, url: record.url, blob: record.blob }
removeRecord (idx) {
this.recordList.splice(idx, 1)
this.$set(this.selected, 'url', null)
},
onStartUpload () {
this.isUploading = true

View File

@@ -23,7 +23,7 @@ export default class {
navigator.mediaDevices.getUserMedia({audio: true})
.then(this._micCaptured.bind(this))
.catch(this._micError.bind(this))
this.isPause = false
this.isPause = false
this.isRecording = true
}
@@ -34,26 +34,28 @@ export default class {
this.context.close()
let encoder = new WavEncoder({
bufferSize: this.bufferSize,
sampleRate: this.context.sampleRate,
samples: this.samples
bufferSize : this.bufferSize,
sampleRate : this.context.sampleRate,
samples : this.samples
})
let audioBlob = encoder.getData()
let audioUrl = URL.createObjectURL(audioBlob)
let audioUrl = URL.createObjectURL(audioBlob)
this.samples = []
this.records.push({
blob: audioBlob,
url: audioUrl,
duration: convertTimeMMSS(this.duration)
id : Date.now(),
blob : audioBlob,
duration : convertTimeMMSS(this.duration),
url : audioUrl
})
this.isPause = false
this.isRecording = false
this._duration = 0
this.duration = 0
this.duration = 0
this.isPause = false
this.isRecording = false
if (this.afterStop) {
this.afterStop()
@@ -79,11 +81,11 @@ export default class {
}
_micCaptured (stream) {
this.context = new(window.AudioContext || window.webkitAudioContext)()
this.input = this.context.createMediaStreamSource(stream)
this.processor = this.context.createScriptProcessor(this.bufferSize, 1, 1)
this.duration = this._duration
this.stream = stream
this.context = new(window.AudioContext || window.webkitAudioContext)()
this.duration = this._duration
this.input = this.context.createMediaStreamSource(stream)
this.processor = this.context.createScriptProcessor(this.bufferSize, 1, 1)
this.stream = stream
this.processor.onaudioprocess = (ev) => {
let sample = ev.inputBuffer.getChannelData(0)