openvidu-browser: fix LocalRecorder

pull/690/head
pabloFuente 2022-01-26 17:23:16 +01:00
parent 18f3f76b22
commit 4ca3839821
2 changed files with 34 additions and 37 deletions

View File

@ -4,6 +4,7 @@
"freeice": "2.2.2",
"hark": "1.2.3",
"jsnlog": "2.30.0",
"mime-types": "2.1.34",
"platform": "1.3.6",
"semver": "7.3.5",
"uuid": "8.3.2",
@ -13,6 +14,7 @@
"devDependencies": {
"@types/node": "17.0.8",
"@types/platform": "1.3.4",
"@types/mime-types": "2.1.1",
"browserify": "17.0.0",
"grunt": "1.4.1",
"grunt-cli": "1.4.3",

View File

@ -19,12 +19,8 @@ import { Stream } from './Stream';
import { LocalRecorderState } from '../OpenViduInternal/Enums/LocalRecorderState';
import { OpenViduLogger } from '../OpenViduInternal/Logger/OpenViduLogger';
import { PlatformUtils } from '../OpenViduInternal/Utils/Platform';
import * as mime from 'mime-types';
/**
* @hidden
*/
declare var MediaRecorder: any;
/**
* @hidden
*/
@ -38,17 +34,13 @@ let platform: PlatformUtils;
/**
* Easy recording of [[Stream]] objects straightaway from the browser. Initialized with [[OpenVidu.initLocalRecorder]] method
*
* > WARNINGS:
* - Performing browser local recording of **remote streams** may cause some troubles. A long waiting time may be required after calling _LocalRecorder.stop()_ in this case
* - Only Chrome and Firefox support local stream recording
*/
export class LocalRecorder {
state: LocalRecorderState;
private connectionId: string;
private mediaRecorder: any;
private mediaRecorder: MediaRecorder;
private chunks: any[] = [];
private blob?: Blob;
private id: string;
@ -69,46 +61,54 @@ export class LocalRecorder {
/**
* Starts the recording of the Stream. [[state]] property must be `READY`. After method succeeds is set to `RECORDING`
*
* @param mimeType The [MediaRecorder.mimeType](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/mimeType) to be used to record this Stream.
* Make sure the platform supports it or the promise will return an error. If this parameter is not provided, the MediaRecorder will use the default codecs available in the platform
* @param options The [MediaRecorder.options](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/MediaRecorder#parameters) to be used to record this Stream.
* For example:
*
* ```javascript
* var OV = new OpenVidu();
* var publisher = await OV.initPublisherAsync();
* var localRecorder = OV.initLocalRecorder(publisher.stream);
* var options = {
* mimeType: 'video/webm;codecs=vp8',
* audioBitsPerSecond:128000,
* videoBitsPerSecond:2500000
* };
* localRecorder.record(options);
* ```
*
* If not specified, the default options preferred by the platform will be used.
*
* @returns A Promise (to which you can optionally subscribe to) that is resolved if the recording successfully started and rejected with an Error object if not
*/
record(mimeType?: string): Promise<void> {
record(options?: any): Promise<void> {
return new Promise((resolve, reject) => {
try {
if (typeof MediaRecorder === 'undefined') {
logger.error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder');
throw (Error('MediaRecorder not supported on your browser. See compatibility in https://caniuse.com/#search=MediaRecorder'));
logger.error('MediaRecorder not supported on your device. See compatibility in https://caniuse.com/#search=MediaRecorder');
throw (Error('MediaRecorder not supported on your device. See compatibility in https://caniuse.com/#search=MediaRecorder'));
}
if (this.state !== LocalRecorderState.READY) {
throw (Error('\'LocalRecord.record()\' needs \'LocalRecord.state\' to be \'READY\' (current value: \'' + this.state + '\'). Call \'LocalRecorder.clean()\' or init a new LocalRecorder before'));
}
logger.log("Starting local recording of stream '" + this.stream.streamId + "' of connection '" + this.connectionId + "'");
let options = {};
if (typeof MediaRecorder.isTypeSupported === 'function') {
if (!!mimeType) {
if (!MediaRecorder.isTypeSupported(mimeType)) {
return reject(new Error('mimeType "' + mimeType + '" is not supported'));
}
options = { mimeType };
} else {
logger.log('No mimeType parameter provided. Using default codecs');
}
} else {
logger.warn('MediaRecorder#isTypeSupported is not supported. Using default codecs');
if (!options) {
options = { mimeType: 'video/webm' };
} else if (!options.mimeType) {
options.mimeType = 'video/webm';
}
this.mediaRecorder = new MediaRecorder(this.stream.getMediaStream(), options);
this.mediaRecorder.start(10);
this.mediaRecorder.start();
} catch (err) {
return reject(err);
}
this.mediaRecorder.ondataavailable = (e) => {
this.chunks.push(e.data);
if (e.data.size > 0) {
this.chunks.push(e.data);
}
};
this.mediaRecorder.onerror = (e) => {
@ -131,10 +131,6 @@ export class LocalRecorder {
logger.log('MediaRecorder resumed (state=' + this.mediaRecorder.state + ')');
};
this.mediaRecorder.onwarning = (e) => {
logger.log('MediaRecorder warning: ' + e);
};
this.state = LocalRecorderState.RECORDING;
return resolve();
@ -243,7 +239,6 @@ export class LocalRecorder {
const f = () => {
delete this.blob;
this.chunks = [];
delete this.mediaRecorder;
this.state = LocalRecorderState.READY;
};
if (this.state === LocalRecorderState.RECORDING || this.state === LocalRecorderState.PAUSED) {
@ -267,7 +262,7 @@ export class LocalRecorder {
const url = window.URL.createObjectURL(<any>this.blob);
a.href = url;
a.download = this.id + '.webm';
a.download = this.id + '.' + mime.extension(this.blob!.type);
a.click();
window.URL.revokeObjectURL(url);
@ -352,7 +347,7 @@ export class LocalRecorder {
}
const sendable = new FormData();
sendable.append('file', this.blob!, this.id + '.webm');
sendable.append('file', this.blob!, this.id + '.' + mime.extension(this.blob!.type));
http.onreadystatechange = () => {
if (http.readyState === 4) {
@ -376,7 +371,7 @@ export class LocalRecorder {
private onStopDefault(): void {
logger.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')');
this.blob = new Blob(this.chunks, { type: 'video/webm' });
this.blob = new Blob(this.chunks, { type: this.mediaRecorder.mimeType });
this.chunks = [];
this.videoPreviewSrc = window.URL.createObjectURL(this.blob);