我为getUserMedia创建了一个类。只要我想将记录的Blob添加到Dropzone中,一切都可以正常工作。
我已经初始化了Dropzone对象,例如:
var threadUpload = $("#thread-upload form").dropzone({...});
初始化的对象UserMediaRecorder如下:
var recorder = new UserMediaRecorder({
openbutton: '#video-tab',
containerClass: 'noSwipe noSwipe2',
constraints: {
audio: false,
video: {
width: { max: 1920 },
height: { max: 1920 },
facingMode:"user",
frameRate: {ideal: 30, min:10},
aspectRatio : 1920/1080
}
},
limit: 10,
onfileupload: function(blob, threadUpload){
console.log(blob);
threadUpload.addFile(blob);
}
});
整个课程UserMediaRecorder
可以在这里看到:https://jsfiddle.net/igor77/zkqg27eh/31/
我的问题是我无法将blob传递给Dropzone对象threadUpload
。我试图将其作为参数传递,但未更改任何内容,但仍显示为未定义。有什么方法可以从其他类内部将blob传递到Dropzone吗?
答案 0 :(得分:0)
将点击事件侦听器绑定到sendButton
上时,您将失去当前作用域。
要解决此问题,请将evenListener中的函数作为类中的方法,然后将其传递给绑定类作用域的eventListener。
例如:
this.sendButton.addEventListener('click', this.sendVideo.bind(this));
,然后在您的班级中添加sendVideo
方法:
sendVideo() {
var blob;
if (this.sendButton.textContent === 'Send Picture') {
blob = this.dataURItoBlob(this.canvas.toDataURL( 'image/jpeg' ))
this.clearCanvas();
console.log('sending pic');
}else if(this.sendButton.textContent === 'Send Video'){
blob = new Blob(this.recordedBlobs, {type: 'video/mp4'});
console.log('sending vid');
}
this.onfileupload(blob);
this.sendButton.disabled = true;
}
这是完整的代码。请注意,由于安全性限制,它将无法运行,但是可以将其粘贴回您的小提琴中。
class UserMediaRecorder {
constructor(options) {
this.openbutton = '#openRecordPanel';
if (typeof options.openbutton !== 'undefined'){
this.openbutton = options.openbutton;
}
this.lengthSeconds = false;
if (typeof options.limit !== 'undefined'){
this.lengthSeconds = options.limit;
}
this.msecondsLeft;
this.isPaused = false;
this.constraints = {audio: true, video: true};
if (typeof options.constraints !== 'undefined'){
this.constraints = options.constraints;
}
this.containerClass = '';
if (typeof options.containerClass !== 'undefined'){
this.containerClass = options.containerClass;
}
if (typeof options.onfileupload !== 'undefined'){
this.onfileupload = options.onfileupload.bind(this);
}
this.openVideoPanelButton = document.querySelector(this.openbutton);
this.openVideoPanelButton.addEventListener('click', async (e) => {
e.preventDefault();
this.openVideoPanel();
});
console.log('initialized');
}
async bindElements(){
this.closeVideoPanelButton = this.overlay.querySelector('button.close-record-panel');
this.video = this.overlay.querySelector('video');
this.canvas = window.canvas = this.overlay.querySelector('canvas');
this.switchCameraButton = this.overlay.querySelector('button.switch-camera');
this.stopButton = this.overlay.querySelector('button.stop-recording');
this.recordButton = this.overlay.querySelector('button.start-recording');
this.snapshotButton = this.overlay.querySelector('button.snapshot');
this.sendButton = this.overlay.querySelector('button.send-recording');
this.counterBlock = this.overlay.querySelector('div.counter');
console.log('elements defined');
}
async bindEvents(){
this.closeVideoPanelButton.addEventListener('click', () => {
this.closeVideoPanel();
});
this.switchCameraButton.addEventListener('click', async () => {
this.switchCamera();
});
this.stopButton.addEventListener('click', () => {
this.stopRecording();
});
this.recordButton.addEventListener('click', (e) => {
if (this.recordButton.textContent === 'Start') {
this.canvas.style.display = "none";
this.startRecording();
}else if(this.recordButton.textContent === 'Pause'){
this.pauseRecording();
}else if(this.recordButton.textContent === 'Resume'){
this.resumeRecording();
}
});
this.snapshotButton.addEventListener('click', () => {
if (this.snapshotButton.textContent === 'Snapshot') {
this.canvas.style.display = "block";
this.canvas.width = this.video.videoWidth;
this.canvas.height = this.video.videoHeight;
this.canvas.getContext('2d').drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
this.snapshotButton.textContent = 'Cancel';
this.sendButton.disabled = false;
this.sendButton.textContent = 'Send Picture';
}else if(this.snapshotButton.textContent === 'Cancel'){
this.clearCanvas();
}
});
this.sendButton.addEventListener('click', this.sendVideo.bind(this));
window.addEventListener('onfileupload', this.onfileupload.bind(this));
console.log('events bound');
}
sendVideo() {
var blob;
if (this.sendButton.textContent === 'Send Picture') {
blob = this.dataURItoBlob(this.canvas.toDataURL( 'image/jpeg' ))
this.clearCanvas();
console.log('sending pic');
}else if(this.sendButton.textContent === 'Send Video'){
blob = new Blob(this.recordedBlobs, {type: 'video/mp4'});
console.log('sending vid');
}
this.onfileupload(blob);
this.sendButton.disabled = true;
}
async openVideoPanel(){
this.overlay = document.createElement('div');
this.overlay.style.cssText = 'position:fixed;top:0;bottom:0;left:0;right:0;background:rgba(0,0,0,.3);z-index:1100;';
document.body.appendChild(this.overlay);
this.overlay.innerHTML = '<div class="' + this.containerClass + '" style="width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;">' +
'<div style="position:relative">' +
'<video autoplay playsinline muted style="max-width:100vw;max-height:100vh"></video>' +
'<canvas style="position:absolute;top:0;left:0;max-width:100vw;max-height:100vh;display:none"></canvas>' +
'<div style="position:absolute;width:100%;top:auto;bottom:20px;display:flex;flex-wrap: wrap;justify-content:center;">' +
'<div style="width:auto"><button class="switch-camera">Switch Camera</button></div>' +
'<div style="width:auto"><button class="stop-recording" disabled>Stop</button></div>' +
'<div style="width:auto"><button class="start-recording">Start</button></div>' +
'<div style="width:auto"><button class="snapshot">Snapshot</button></div>' +
'<div style="width:auto"><button class="send-recording" disabled>Send</button></div>' +
'<div class="counter" style="width: 100%;text-align: center;">00:00:00</div>' +
'</div>' +
'</div>' +
'<button class="close-record-panel" style="position:absolute;top:20px;left:auto;right:20px;">Close</button>' +
'</div>';
await this.bindElements();
await this.bindEvents();
await this.initStream();
console.log('opened');
}
closeVideoPanel() {
if (this.stream) {
this.stream.getTracks().forEach(track => {
track.stop();
});
}
this.overlay.remove();
}
async initStream() {
try {
this.stream = await navigator.mediaDevices.getUserMedia(this.constraints);
this.handleSuccess(this.stream);
} catch (e) {
console.error('navigator.getUserMedia error:', e);
}
}
handleSuccess() {
window.stream = this.stream;
this.video.srcObject = this.stream;
}
async switchCamera() {
console.log('getUserMedia() switching camera:', this.stream);
if(this.constraints.video.facingMode === "user"){
this.constraints.video.facingMode = "environment";
}else{
this.constraints.video.facingMode = "user";
}
console.log('Camera changed to ' + this.constraints.video.facingMode);
await this.initStream(this.constraints);
}
startRecording() {
this.snapshotButton.disabled = true;
this.sendButton.disabled = true;
this.stopButton.disabled = false;
this.recordButton.textContent = 'Pause';
this.recordedBlobs = [];
let options = {mimeType: 'video/webm;codecs=vp9'};
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
console.error(`${options.mimeType} is not Supported`);
options = {mimeType: 'video/webm;codecs=vp8'};
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
console.error(`${options.mimeType} is not Supported`);
options = {mimeType: 'video/webm'};
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
console.error(`${options.mimeType} is not Supported`);
options = {mimeType: ''};
}
}
}
try {
this.mediaRecorder = new MediaRecorder(window.stream, options);
} catch (e) {
console.error('Exception while creating MediaRecorder:', e);
return;
}
console.log('Created MediaRecorder', this.mediaRecorder, 'with options', options);
this.mediaRecorder.onstop = (event) => {
console.log('Recorder stopped: ', event);
};
console.log(this);
this.mediaRecorder.ondataavailable = (event) => {
if (event.data && event.data.size > 0) {
this.recordedBlobs.push(event.data);
}
};
this.mediaRecorder.start(10); // collect 10ms of data
console.log('MediaRecorder started', this.mediaRecorder);
this.startTimer();
return this.recordedBlobs;
}
stopRecording() {
this.mediaRecorder.stop();
this.stopTimer();
this.recordButton.textContent = 'Start';
this.snapshotButton.disabled = false;
this.sendButton.disabled = false;
this.sendButton.textContent = 'Send Video';
this.stopButton.disabled = true;
console.log('Recorded Blobs: ', this.recordedBlobs);
}
pauseRecording(){
this.mediaRecorder.pause();
this.pauseTimer();
this.recordButton.textContent = 'Resume';
}
resumeRecording(){
this.mediaRecorder.resume();
this.resumeTimer();
this.recordButton.textContent = 'Pause';
}
clearCanvas(){
this.snapshotButton.textContent = 'Snapshot';
this.canvas.style.display = 'none';
this.canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
this.sendButton.disabled = true;
}
dataURItoBlob(dataURI) {
var byteString,
mimestring
if(dataURI.split(',')[0].indexOf('base64') !== -1 ) {
byteString = atob(dataURI.split(',')[1])
} else {
byteString = decodeURI(dataURI.split(',')[1])
}
mimestring = dataURI.split(',')[0].split(':')[1].split(';')[0]
var content = new Array();
for (var i = 0; i < byteString.length; i++) {
content[i] = byteString.charCodeAt(i)
}
return new Blob([new Uint8Array(content)], {type: mimestring});
}
startTimer(){
if (!this.isPaused && this.lengthSeconds){
this.msecondsLeft = this.lengthSeconds * 100;
}else if(!this.lengthSeconds){
this.msecondsLeft = 1;
}
var that = this;
var counter = function(){
if (that.msecondsLeft > 0){
if(!that.lengthSeconds){
that.msecondsLeft++;
}else{
that.msecondsLeft--;
}
var ms = that.msecondsLeft % 100;
if(ms < 10){ ms = "0" + ms}
var s = ((that.msecondsLeft - ms) / 100) % 60;
if(s < 10){ s = "0" + s}
var m = ((that.msecondsLeft - ms - (s * 100)) / 100) /60;
if(m < 10){ m = "0" + m}
that.counterBlock.innerHTML = m + ":" + s + ":" + ms;
}else{
that.stopRecording();
that.isPaused = false;
}
};
this.timer = setInterval(counter,10);
}
resumeTimer(){
this.isPaused = true;
this.startTimer();
}
pauseTimer(){
this.isPaused = true;
this.stopTimer();
}
stopTimer(){
clearInterval(this.timer);
}
}
var recorder = new UserMediaRecorder({
openbutton: '#openRecordPanel',
containerClass: 'noSwipe noSwipe2',
constraints: {
audio: false,
video: {
width: { max: 1920 },
height: { max: 1920 },
facingMode:"user",
frameRate: {ideal: 30, min:10},
aspectRatio : 1920/1080
}
},
limit: 10,
onfileupload: function(blob){
console.log(blob);
// threadUpload.addFile(blob);
}
});