mirror of
https://github.com/GuerillaStudio/souvenir.git
synced 2024-11-09 23:31:52 +00:00
add capture and encode (this one is borken ah ah)
nik les workers ofc
This commit is contained in:
parent
beefe38b3b
commit
d468ad3728
10 changed files with 308 additions and 52 deletions
56
package-lock.json
generated
56
package-lock.json
generated
|
@ -5293,8 +5293,7 @@
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"aproba": {
|
"aproba": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
|
@ -5315,14 +5314,12 @@
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
|
@ -5337,20 +5334,17 @@
|
||||||
"code-point-at": {
|
"code-point-at": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
|
@ -5467,8 +5461,7 @@
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
|
@ -5480,7 +5473,6 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"number-is-nan": "^1.0.0"
|
"number-is-nan": "^1.0.0"
|
||||||
}
|
}
|
||||||
|
@ -5495,7 +5487,6 @@
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
|
@ -5503,14 +5494,12 @@
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.3.5",
|
"version": "2.3.5",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"yallist": "^3.0.0"
|
"yallist": "^3.0.0"
|
||||||
|
@ -5529,7 +5518,6 @@
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
|
@ -5610,8 +5598,7 @@
|
||||||
"number-is-nan": {
|
"number-is-nan": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
|
@ -5623,7 +5610,6 @@
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
|
@ -5709,8 +5695,7 @@
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
|
@ -5746,7 +5731,6 @@
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
"is-fullwidth-code-point": "^1.0.0",
|
"is-fullwidth-code-point": "^1.0.0",
|
||||||
|
@ -5766,7 +5750,6 @@
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-regex": "^2.0.0"
|
"ansi-regex": "^2.0.0"
|
||||||
}
|
}
|
||||||
|
@ -5810,14 +5793,12 @@
|
||||||
"wrappy": {
|
"wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -5869,6 +5850,11 @@
|
||||||
"assert-plus": "^1.0.0"
|
"assert-plus": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gif-writer": {
|
||||||
|
"version": "0.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/gif-writer/-/gif-writer-0.9.3.tgz",
|
||||||
|
"integrity": "sha1-0nbwlRBKMqC557tl4Mn9QPs1bQ8="
|
||||||
|
},
|
||||||
"glob": {
|
"glob": {
|
||||||
"version": "7.1.3",
|
"version": "7.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
||||||
|
@ -11626,6 +11612,16 @@
|
||||||
"errno": "~0.1.7"
|
"errno": "~0.1.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"worker-loader": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"loader-utils": "^1.0.0",
|
||||||
|
"schema-utils": "^0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"wrap-ansi": {
|
"wrap-ansi": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"gif-writer": "^0.9.3",
|
||||||
"register-service-worker": "^1.6.2",
|
"register-service-worker": "^1.6.2",
|
||||||
"vue": "^2.6.6",
|
"vue": "^2.6.6",
|
||||||
"vuex": "^3.0.1"
|
"vuex": "^3.0.1"
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.1",
|
||||||
"eslint": "^5.8.0",
|
"eslint": "^5.8.0",
|
||||||
"eslint-plugin-vue": "^5.0.0",
|
"eslint-plugin-vue": "^5.0.0",
|
||||||
"vue-template-compiler": "^2.5.21"
|
"vue-template-compiler": "^2.5.21",
|
||||||
|
"worker-loader": "^2.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,6 @@ export default {
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.makeLoading()
|
this.makeLoading()
|
||||||
window.setTimeout(() => {
|
|
||||||
this.$store.commit('stopEncoding')
|
|
||||||
this.$store.commit('startDownloading')
|
|
||||||
}, 2000)
|
|
||||||
},
|
},
|
||||||
destroyed: function () {
|
destroyed: function () {
|
||||||
window.clearTimeout(this.interval)
|
window.clearTimeout(this.interval)
|
||||||
|
|
73
src/services/capture.js
Normal file
73
src/services/capture.js
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
import {
|
||||||
|
makeRectangle,
|
||||||
|
crop
|
||||||
|
} from './rectangle.js'
|
||||||
|
|
||||||
|
const FRAMES_PER_SECOND = 10
|
||||||
|
const WIDTH = 200
|
||||||
|
const HEIGHT = WIDTH
|
||||||
|
|
||||||
|
const video = document.createElement('video')
|
||||||
|
|
||||||
|
const canvas = document.createElement('canvas')
|
||||||
|
const canvasContext = canvas.getContext('2d')
|
||||||
|
|
||||||
|
canvas.width = WIDTH
|
||||||
|
canvas.height = HEIGHT
|
||||||
|
|
||||||
|
export function capture (commit, mediaStream, duration) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const totalFrames = duration / 1000 * FRAMES_PER_SECOND
|
||||||
|
|
||||||
|
if (totalFrames < 1) {
|
||||||
|
resolve([])
|
||||||
|
}
|
||||||
|
|
||||||
|
const delayTime = 1000 / FRAMES_PER_SECOND
|
||||||
|
|
||||||
|
video.srcObject = mediaStream
|
||||||
|
|
||||||
|
const soureRectangle = crop(makeRectangle(0, 0, video.videoWidth, video.videoHeight))
|
||||||
|
const destinationRectangle = makeRectangle(0, 0, canvas.width, canvas.height)
|
||||||
|
|
||||||
|
const imageDataList = []
|
||||||
|
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
if (imageDataList.length < totalFrames) {
|
||||||
|
console.log(`Capturing frame ${imageDataList.length} / ${totalFrames}`)
|
||||||
|
|
||||||
|
canvasContext.drawImage(
|
||||||
|
video,
|
||||||
|
soureRectangle.x,
|
||||||
|
soureRectangle.y,
|
||||||
|
soureRectangle.width,
|
||||||
|
soureRectangle.height,
|
||||||
|
destinationRectangle.x,
|
||||||
|
destinationRectangle.y,
|
||||||
|
destinationRectangle.width,
|
||||||
|
destinationRectangle.height
|
||||||
|
)
|
||||||
|
|
||||||
|
const imageData = canvasContext.getImageData(
|
||||||
|
destinationRectangle.x,
|
||||||
|
destinationRectangle.y,
|
||||||
|
destinationRectangle.width,
|
||||||
|
destinationRectangle.height
|
||||||
|
)
|
||||||
|
|
||||||
|
imageDataList.push(imageData)
|
||||||
|
|
||||||
|
commit('updateCaptureState', imageDataList.length / totalFrames * 100)
|
||||||
|
} else {
|
||||||
|
clearInterval(intervalId)
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
imageDataList,
|
||||||
|
imageWidth: WIDTH,
|
||||||
|
imageHeight: HEIGHT,
|
||||||
|
delayTime
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, delayTime)
|
||||||
|
})
|
||||||
|
}
|
38
src/services/encode.js
Normal file
38
src/services/encode.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import EncodeWorker from './encode.worker.js'
|
||||||
|
|
||||||
|
const PALETTE_SIZE = 255
|
||||||
|
|
||||||
|
export function encode (imageDataList, imageWidth, imageHeight, paletteSize, delayTime) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const worker = new EncodeWorker()
|
||||||
|
|
||||||
|
worker.onerror = error => reject(error)
|
||||||
|
|
||||||
|
worker.onmessage = event => {
|
||||||
|
const { type, payload } = event.data
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
default:
|
||||||
|
reject(new Error(`Unexpected EncodeWorker message with type ${type}`))
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'progress':
|
||||||
|
console.log(`Encoding progress : ${payload.value}`)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'done':
|
||||||
|
const dataUrl = 'data:image/gif;base64,' + btoa(payload.buffer.map((b) => String.fromCharCode(b)).join(''))
|
||||||
|
resolve(dataUrl)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
worker.postMessage({
|
||||||
|
imageDataList,
|
||||||
|
imageWidth,
|
||||||
|
imageHeight,
|
||||||
|
paletteSize: PALETTE_SIZE,
|
||||||
|
delayTime
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
104
src/services/encode.worker.js
Normal file
104
src/services/encode.worker.js
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
import {
|
||||||
|
GifWriter,
|
||||||
|
MedianCutColorReducer,
|
||||||
|
IndexedColorImage
|
||||||
|
} from 'gif-writer'
|
||||||
|
|
||||||
|
onmessage = (event) => {
|
||||||
|
console.log(event.data)
|
||||||
|
const { imageDataList, imageWidth, imageHeight, paletteSize, delayTime } = event.data
|
||||||
|
|
||||||
|
console.log('Write GIF')
|
||||||
|
|
||||||
|
const outputStream = new OutputStream()
|
||||||
|
const writer = new GifWriter(outputStream)
|
||||||
|
|
||||||
|
postProgressMessage(0)
|
||||||
|
|
||||||
|
console.log(`Write header`)
|
||||||
|
writer.writeHeader()
|
||||||
|
|
||||||
|
console.log(`Write logical screen informations`)
|
||||||
|
writer.writeLogicalScreenInfo({
|
||||||
|
width: imageWidth,
|
||||||
|
height: imageHeight
|
||||||
|
})
|
||||||
|
|
||||||
|
writer.writeLoopControlInfo(0)
|
||||||
|
|
||||||
|
const indexedColorImages = imageDataList.map((imageData, index, { length }) => {
|
||||||
|
console.log(`Convert frame ${index} ImageData to IndexedColorImage`)
|
||||||
|
const indexedColorImage = imageDataToIndexedColorImage(imageData, paletteSize)
|
||||||
|
postProgressMessage(calcProgress(0, 0.9, length, index + 1))
|
||||||
|
return indexedColorImage
|
||||||
|
})
|
||||||
|
|
||||||
|
indexedColorImages.forEach((indexedColorImage, index, { length }) => {
|
||||||
|
console.log(`Write frame IndexedColorImage ${index}`)
|
||||||
|
writer.writeTableBasedImageWithGraphicControl(indexedColorImage, { delayTimeInMS: delayTime })
|
||||||
|
postProgressMessage(calcProgress(0.9, 1, length, index + 1))
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(`Write trailer`)
|
||||||
|
writer.writeTrailer()
|
||||||
|
|
||||||
|
postDoneMessage(outputStream.buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
class OutputStream {
|
||||||
|
constructor () {
|
||||||
|
this.buffer = []
|
||||||
|
}
|
||||||
|
|
||||||
|
writeByte (b) {
|
||||||
|
this.buffer.push(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
writeBytes (bb) {
|
||||||
|
Array.prototype.push.apply(this.buffer, bb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function imageDataToIndexedColorImage (imageData, paletteSize) {
|
||||||
|
var reducer = new MedianCutColorReducer(imageData, paletteSize)
|
||||||
|
var paletteData = reducer.process()
|
||||||
|
var dat = Array.prototype.slice.call(imageData.data)
|
||||||
|
|
||||||
|
var indexedColorImageData = []
|
||||||
|
|
||||||
|
for (var idx = 0, len = dat.length; idx < len; idx += 4) {
|
||||||
|
var d = dat.slice(idx, idx + 4) // r,g,b,a
|
||||||
|
indexedColorImageData.push(reducer.map(d[0], d[1], d[2]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return new IndexedColorImage(
|
||||||
|
{
|
||||||
|
width: imageData.width,
|
||||||
|
height: imageData.height
|
||||||
|
},
|
||||||
|
indexedColorImageData,
|
||||||
|
paletteData
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcProgress (from, to, steps, current) {
|
||||||
|
return from + ((to - from) / steps * current)
|
||||||
|
}
|
||||||
|
|
||||||
|
function postProgressMessage (value) {
|
||||||
|
postMessage({
|
||||||
|
type: 'progress',
|
||||||
|
payload: {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function postDoneMessage (buffer) {
|
||||||
|
postMessage({
|
||||||
|
type: 'done',
|
||||||
|
payload: {
|
||||||
|
buffer
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
18
src/services/rectangle.js
Normal file
18
src/services/rectangle.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
export function makeRectangle (x, y, width, height) {
|
||||||
|
return {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function crop ({ x, y, width: w, height: h }) {
|
||||||
|
if (w < h) {
|
||||||
|
return makeRectangle((h - w) / 2, y, h, h)
|
||||||
|
} else if (w > h) {
|
||||||
|
return makeRectangle((w - h) / 2, y, h, h)
|
||||||
|
} else {
|
||||||
|
return makeRectangle(x, y, w, h)
|
||||||
|
}
|
||||||
|
}
|
31
src/store.js
31
src/store.js
|
@ -1,6 +1,9 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
import { capture } from './services/capture.js'
|
||||||
|
import { encode } from './services/encode.js'
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
|
@ -61,6 +64,34 @@ export default new Vuex.Store({
|
||||||
commit('updateMediaStream', mediaStream)
|
commit('updateMediaStream', mediaStream)
|
||||||
})
|
})
|
||||||
.catch(error => console.error(error))
|
.catch(error => console.error(error))
|
||||||
|
},
|
||||||
|
capture ({ commit, dispatch, state }) {
|
||||||
|
commit('startCapture')
|
||||||
|
|
||||||
|
capture(commit, state.mediaStream, state.timer.selected * 1000)
|
||||||
|
.then(captureData => {
|
||||||
|
commit('stopCapture')
|
||||||
|
commit('updateCaptureState', 0)
|
||||||
|
dispatch('encode', captureData)
|
||||||
|
})
|
||||||
|
.catch(error => console.error(error))
|
||||||
|
},
|
||||||
|
encode ({ commit }, captureData) {
|
||||||
|
commit('startEncoding')
|
||||||
|
|
||||||
|
console.log(captureData)
|
||||||
|
|
||||||
|
encode(captureData)
|
||||||
|
.then(clipDataUrl => {
|
||||||
|
commit('stopEncoding')
|
||||||
|
commit('startDownloading')
|
||||||
|
console.log(clipDataUrl)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(error)
|
||||||
|
commit('stopEncoding')
|
||||||
|
commit('startDownloading')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -39,25 +39,11 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
startCapture () {
|
startCapture () {
|
||||||
this.$store.commit('startCapture')
|
this.$store.dispatch('capture')
|
||||||
this.fakeCapture()
|
|
||||||
},
|
|
||||||
fakeCapture () {
|
|
||||||
const interval = (this.timer.selected * 1000) / 100
|
|
||||||
const fakeProgress = window.setInterval(() => {
|
|
||||||
if (this.capturing.state < 100) {
|
|
||||||
this.$store.commit('updateCaptureState', this.capturing.state + 1)
|
|
||||||
} else {
|
|
||||||
window.clearInterval(fakeProgress)
|
|
||||||
this.$store.commit('stopCapture')
|
|
||||||
this.$store.commit('updateCaptureState', 0)
|
|
||||||
this.$store.commit('startEncoding')
|
|
||||||
}
|
|
||||||
}, interval)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.$refs.preview.srcObject = this.mediaStream
|
this.$refs.preview.srcObject = this.mediaStream
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -8,5 +8,17 @@ module.exports = {
|
||||||
workboxOptions: {
|
workboxOptions: {
|
||||||
importWorkboxFrom: 'local'
|
importWorkboxFrom: 'local'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
configureWebpack: {
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.worker\.js$/,
|
||||||
|
use: {
|
||||||
|
loader: 'worker-loader'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue