Refactor how download works. Cleaner filenames.

This commit is contained in:
Radium Zheng 2018-08-04 02:06:11 +10:00
parent 49bdd53bee
commit b284f25fde
7 changed files with 59 additions and 44 deletions

View File

@ -5,7 +5,8 @@ import { i18next } from '../../base/i18n';
import { import {
FlacAdapter, FlacAdapter,
OggAdapter, OggAdapter,
WavAdapter WavAdapter,
downloadBlob
} from '../recording'; } from '../recording';
import { sessionManager } from '../session'; import { sessionManager } from '../session';
@ -320,7 +321,19 @@ class RecordingController {
*/ */
downloadRecordedData(sessionToken: number) { downloadRecordedData(sessionToken: number) {
if (this._adapters[sessionToken]) { if (this._adapters[sessionToken]) {
this._adapters[sessionToken].download(); this._adapters[sessionToken].exportRecordedData()
.then(args => {
const { data, format } = args;
const filename = `session_${sessionToken}`
+ `_${this._conference.myUserId()}.${format}`;
downloadBlob(data, filename);
})
.catch(error => {
logger.error('Failed to download audio for'
+ ` session ${sessionToken}. Error: ${error}`);
});
} else { } else {
logger.error(`Invalid session token for download ${sessionToken}`); logger.error(`Invalid session token for download ${sessionToken}`);
} }

View File

@ -1,5 +1,4 @@
import { RecordingAdapter } from './RecordingAdapter'; import { RecordingAdapter } from './RecordingAdapter';
import { downloadBlob, timestampString } from './Utils';
const logger = require('jitsi-meet-logger').getLogger(__filename); const logger = require('jitsi-meet-logger').getLogger(__filename);
@ -11,14 +10,22 @@ export class OggAdapter extends RecordingAdapter {
/** /**
* Instance of MediaRecorder. * Instance of MediaRecorder.
* @private
*/ */
_mediaRecorder = null; _mediaRecorder = null;
/** /**
* Initialization promise. * Initialization promise.
* @private
*/ */
_initPromise = null; _initPromise = null;
/**
* The recorded audio file.
* @private
*/
_recordedData = null;
/** /**
* Implements {@link RecordingAdapter#start()}. * Implements {@link RecordingAdapter#start()}.
* *
@ -52,16 +59,19 @@ export class OggAdapter extends RecordingAdapter {
} }
/** /**
* Implements {@link RecordingAdapter#download()}. * Implements {@link RecordingAdapter#exportRecordedData()}.
* *
* @inheritdoc * @inheritdoc
*/ */
download() { exportRecordedData() {
if (this._recordedData !== null) { if (this._recordedData !== null) {
const audioURL = window.URL.createObjectURL(this._recordedData); return Promise.resolve({
data: this._recordedData,
downloadBlob(audioURL, `recording${timestampString()}.ogg`); format: 'ogg'
});
} }
return Promise.reject('No audio data recorded.');
} }
/** /**

View File

@ -26,11 +26,11 @@ export class RecordingAdapter {
} }
/** /**
* Initiates download of the recorded and encoded audio file. * Export the recorded and encoded audio file.
* *
* @returns {void} * @returns {Promise<Object>}
*/ */
download() { exportRecordedData() {
throw new Error('Not implemented'); throw new Error('Not implemented');
} }

View File

@ -1,33 +1,20 @@
/** /**
* Force download of Blob in browser by faking an <a> tag. * Force download of Blob in browser by faking an <a> tag.
* *
* @param {string} blob - Base64 URL. * @param {Blob} blob - Base64 URL.
* @param {string} fileName - The filename to appear in the download dialog. * @param {string} fileName - The filename to appear in the download dialog.
* @returns {void} * @returns {void}
*/ */
export function downloadBlob(blob, fileName = 'recording.ogg') { export function downloadBlob(blob, fileName = 'recording.ogg') {
const base64Url = window.URL.createObjectURL(blob);
// fake a anchor tag // fake a anchor tag
const a = document.createElement('a'); const a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none'; a.style = 'display: none';
a.href = blob; a.href = base64Url;
a.download = fileName; a.download = fileName;
document.body.appendChild(a);
a.click(); a.click();
} document.body.removeChild(a);
/**
* Obtains a timestamp of now. Used in filenames.
*
* @returns {string}
*/
export function timestampString() {
const timeStampInMs = window.performance
&& window.performance.now
&& window.performance.timing
&& window.performance.timing.navigationStart
? window.performance.now() + window.performance.timing.navigationStart
: Date.now();
return timeStampInMs.toString();
} }

View File

@ -1,5 +1,4 @@
import { RecordingAdapter } from './RecordingAdapter'; import { RecordingAdapter } from './RecordingAdapter';
import { downloadBlob, timestampString } from './Utils';
const logger = require('jitsi-meet-logger').getLogger(__filename); const logger = require('jitsi-meet-logger').getLogger(__filename);
@ -98,16 +97,19 @@ export class WavAdapter extends RecordingAdapter {
} }
/** /**
* Implements {@link RecordingAdapter#download()}. * Implements {@link RecordingAdapter#exportRecordedData()}.
* *
* @inheritdoc * @inheritdoc
*/ */
download() { exportRecordedData() {
if (this._data !== null) { if (this._data !== null) {
const audioURL = window.URL.createObjectURL(this._data); return Promise.resolve({
data: this._data,
downloadBlob(audioURL, `recording${timestampString()}.wav`); format: 'wav'
});
} }
return Promise.reject('No audio data recorded.');
} }
/** /**

View File

@ -1,5 +1,4 @@
import { RecordingAdapter } from '../RecordingAdapter'; import { RecordingAdapter } from '../RecordingAdapter';
import { downloadBlob, timestampString } from '../Utils';
import { import {
DEBUG, DEBUG,
MAIN_THREAD_FINISH, MAIN_THREAD_FINISH,
@ -93,16 +92,19 @@ export class FlacAdapter extends RecordingAdapter {
} }
/** /**
* Implements {@link RecordingAdapter#download()}. * Implements {@link RecordingAdapter#exportRecordedData()}.
* *
* @inheritdoc * @inheritdoc
*/ */
download() { exportRecordedData() {
if (this._data !== null) { if (this._data !== null) {
const audioURL = window.URL.createObjectURL(this._data); return Promise.resolve({
data: this._data,
downloadBlob(audioURL, `recording${timestampString()}.flac`); format: 'flac'
});
} }
return Promise.reject('No audio data recorded.');
} }
/** /**

View File

@ -1,4 +1,5 @@
export * from './RecordingAdapter';
export * from './flac';
export * from './OggAdapter'; export * from './OggAdapter';
export * from './RecordingAdapter';
export * from './Utils';
export * from './WavAdapter'; export * from './WavAdapter';
export * from './flac';