kudlav/videoeditor

Upload file from link

Opened this issue · 2 comments

Upload file from link

@kudlav I tried to implement this feature.

I added this code section to controllers/apiController.js.

const download = require('download');
...
exports.projectRemoteFilePOST = (req, res, next) => {
	let url = req.body.url;
	let filename = url.split('/');
	filename = filename[filename.length - 1];
	const fileID = nanoid();
	const extension = path.extname(filename);
	let filepath = path.join(config.projectPath, req.params.projectID, fileID);
	if (extension.length > 1) filepath += extension;

	log.info(`Save of "${filename}" from "${url}" started`);

	console.log('save remote file ', url);

	// // Create a write stream of the new file
	let mimeType = 'video/mp4';

	const fstream = fs.createWriteStream(filepath);
	fstream.on('finish', () => {
		log.info(`Save of "${filename}" from "${url}" finished`);
		console.log('download finished');
		fileManager.getDuration(filepath, mimeType).then(
			length => {
				projectManager.load(req.params.projectID, 'w').then(
					([document, , release]) => {
						const node = document.createElement('producer');
						node.id = 'producer' + fileID;
						node.innerHTML = `<property name="resource">${path.resolve(filepath)}</property>`;
						node.innerHTML += `<property name="musecut:mime_type">${mimeType}</property>`;
						node.innerHTML += `<property name="musecut:name">${filename}</property>`;
						if (length !== null) {
							if (timeManager.isValidDuration(length))
								node.innerHTML += `<property name="length">${length}</property>`;
							else {
								length = null;
								log.fatal(`Unable to get duration of ${mimeType}: ${filepath}`);
							}
						}

						const root = document.getElementsByTagName('mlt').item(0);
						root.prepend(node);
						projectManager.save(req.params.projectID, root.outerHTML, release).then(
							() => res.json({
								msg: `Upload of "${filename}" OK`,
								resource_id: fileID,
								resource_mime: mimeType,
								length: length,
							}),
							err => next(err)
						);
					},
					err => fileErr(err, res)
				);
			}
		);
	})
	fstream.on('error', () => errorResponse(error.projectNotFound404, res));

	try {
		download(url).pipe(fstream);
	} catch (_) {
		console.log('download failed')
	}
};

And I added route
router.post('/api/project/:projectID/url', apiController.projectRemoteFilePOST);

I can't confirm that this way is absolutely right.
Anyway, it works properly.

Hi @pegasus1982, thanks for the code. It looks simply, with some changes I will implement it. I would rather use "node-fetch" library as I already have this library as dev-dependency and it allow me to access Content-Type header containing mime-type (you have mime-type hardcoded to 'video/mp4').