added probe and refactoring
This commit is contained in:
parent
b1df41c8b0
commit
ce44d17ebc
102
README.adoc
102
README.adoc
|
@ -12,23 +12,20 @@ FFMPEG API is provided as Docker image for easy consumption.
|
|||
|
||||
== Endpoints
|
||||
|
||||
* `POST /convert/audio/to/mp3` - Convert audio file in request body to mp3
|
||||
* `POST /convert/video/to/mp4` - Convert video file in request body to mp4
|
||||
* `POST /convert/image/to/jpg` - Convert image file to jpg
|
||||
* `GET /` - API Readme
|
||||
|
||||
== Usage
|
||||
|
||||
=== Convert
|
||||
|
||||
Convert audio/video/image files using the API.
|
||||
|
||||
* `curl -F "file=@input.wav" 127.0.0.1:3000/convert/audio/to/mp3 > output.mp3`
|
||||
* `curl -F "file=@input.m4a" 127.0.0.1:3000/convert/audio/to/mp3 > output.mp3`
|
||||
* `curl -F "file=@input.mov" 127.0.0.1:3000/convert/video/to/mp4 > output.mp4`
|
||||
* `curl -F "file=@input.mp4" 127.0.0.1:3000/convert/videp/to/mp4 > output.mp4`
|
||||
* `curl -F "file=@input.tiff" 127.0.0.1:3000/convert/image/to/jpg > output.jpg`
|
||||
* `curl -F "file=@input.png" 127.0.0.1:3000/convert/image/to/jpg > output.jpg`
|
||||
* `GET /` - API Readme.
|
||||
* `GET /endpoints` - Service endpoints as JSON.
|
||||
* `POST /convert/audio/to/mp3` - Convert audio file in request body to mp3. Returns mp3-file.
|
||||
* `POST /convert/audio/to/wav` - Convert audio file in request body to wav. Returns wav-file.
|
||||
* `POST /convert/video/to/mp4` - Convert video file in request body to mp4. Returns mp4-file.
|
||||
* `POST /convert/image/to/jpg` - Convert image file to jpg. Returns jpg-file.
|
||||
* `POST /video/extract/audio` - Extract audio track from POSTed video file. Returns audio track as 1-channel wav-file.
|
||||
** Query param: `mono=no` - Returns audio track, all channels.
|
||||
* `POST /video/extract/images` - Extract images from POSTed video file as PNG. Default FPS is 1. Returns JSON that includes download links to extracted images.
|
||||
** Query param: `compress=zip|gzip` - Returns extracted images as _zip_ or _tar.gz_ (gzip).
|
||||
** Query param: `fps=2` - Extract images using specified FPS.
|
||||
* `GET /video/extract/download/:filename` - Downloads extracted image file and deletes it from server.
|
||||
** Query param: `delete=no` - does not delete file.
|
||||
* `POST /probe` - Probe media file, return JSON metadata.
|
||||
|
||||
== Docker image
|
||||
|
||||
|
@ -38,32 +35,85 @@ Convert audio/video/image files using the API.
|
|||
* Build Docker image:
|
||||
** `docker build -t ffmpeg-api .`
|
||||
* Run image in foreground:
|
||||
** `docker run -it --rm -p 3000:3000 ffmpeg-api`
|
||||
** `docker run -it --rm --name ffmpeg-api -p 3000:3000 ffmpeg-api`
|
||||
* Run image in background:
|
||||
** `docker run -d -name ffmpeg-api -p 3000:3000 ffmpeg-api`
|
||||
|
||||
=== Use existing
|
||||
|
||||
* Run image in foreground:
|
||||
** `docker run -it --rm -p 3000:3000 kazhar/ffmpeg-api`
|
||||
** `docker run -it --rm --name ffmpeg-api -p 3000:3000 kazhar/ffmpeg-api`
|
||||
* Run image in background:
|
||||
** `docker run -d --name ffmpeg-api -p 3000:3000 kazhar/ffmpeg-api`
|
||||
|
||||
=== Environment variables
|
||||
|
||||
Default log level is INFO. Set log level using environment variable, _LOG_LEVEL_.
|
||||
* Default log level is _info_. Set log level using environment variable, _LOG_LEVEL_.
|
||||
** Set log level to debug:
|
||||
** `docker run -it --rm -p 3000:3000 -e LOG_LEVEL=debug kazhar/ffmpeg-api`
|
||||
* Default maximum file size of uploaded files is 512MB. Use environment variable _FILE_SIZE_LIMIT_BYTES_ to change it:
|
||||
** Set max file size to 1MB:
|
||||
** `docker run -it --rm -p 3000:3000 -e FILE_SIZE_LIMIT_BYTES=1048576 kazhar/ffmpeg-api`
|
||||
* All uploaded and converted files are deleted when they've been downloaded. Use environment variable _KEEP_ALL_FILES_ to keep all files inside the container /tmp-directory:
|
||||
** `docker run -it --rm -p 3000:3000 -e KEEP_ALL_FILES=true kazhar/ffmpeg-api`
|
||||
|
||||
- Set log level to debug:
|
||||
- `docker run -it --rm -p 3000:3000 -e LOG_LEVEL=debug kazhar/ffmpeg-api`
|
||||
|
||||
Default maximum file size of uploaded files is 512MB. Use environment variable _FILE_SIZE_LIMIT_BYTES_ to change it:
|
||||
== Usage
|
||||
|
||||
- Set max file size to 1MB:
|
||||
- `docker run -it --rm -p 3000:3000 -e FILE_SIZE_LIMIT_BYTES=1048576 kazhar/ffmpeg-api`
|
||||
Input file to FFMPEG API can be anything that ffmpeg supports. See https://www.ffmpeg.org/general.html#Supported-File-Formats_002c-Codecs-or-Features[ffmpeg docs for supported formats].
|
||||
|
||||
=== Convert
|
||||
|
||||
Convert audio/video/image files using the API.
|
||||
|
||||
* `curl -F "file=@input.wav" 127.0.0.1:3000/convert/audio/to/mp3 > output.mp3`
|
||||
* `curl -F "file=@input.m4a" 127.0.0.1:3000/convert/audio/to/wav > output.wav`
|
||||
* `curl -F "file=@input.mov" 127.0.0.1:3000/convert/video/to/mp4 > output.mp4`
|
||||
* `curl -F "file=@input.mp4" 127.0.0.1:3000/convert/videp/to/mp4 > output.mp4`
|
||||
* `curl -F "file=@input.tiff" 127.0.0.1:3000/convert/image/to/jpg > output.jpg`
|
||||
* `curl -F "file=@input.png" 127.0.0.1:3000/convert/image/to/jpg > output.jpg`
|
||||
|
||||
=== Extract images
|
||||
|
||||
Extract images from video using the API.
|
||||
|
||||
* `curl -F "file=@input.mov" 127.0.0.1:3000/video/extract/images`
|
||||
** Returns JSON that lists image download URLs for each extracted image.
|
||||
** Default FPS is 1.
|
||||
** Images are in PNG-format.
|
||||
** See sample: link:./samples/extracted_images.json[extracted_images.json].
|
||||
* `curl 127.0.0.1:3000/video/extract/download/ba0f565c-0001.png`
|
||||
** Downloads exracted image and deletes it from server.
|
||||
* `curl 127.0.0.1:3000/video/extract/download/ba0f565c-0001.png?delete=no`
|
||||
** Downloads exracted image but does not deletes it from server.
|
||||
* `curl -F "file=@input.mov" 127.0.0.1:3000/video/extract/images?compress=zip > images.zip`
|
||||
** Returns ZIP package of all extracted images.
|
||||
* `curl -F "file=@input.mov" 127.0.0.1:3000/video/extract/images?compress=gzip > images.tar.gz`
|
||||
** Returns GZIP (tar.gz) package of all extracted images.
|
||||
* `curl -F "file=@input.mov" 127.0.0.1:3000/video/extract/images?fps=0.5`
|
||||
** Sets FPS to extract images. FPS=0.5 is every two seconds, FPS=4 is four images per seconds, etc.
|
||||
|
||||
=== Extract audio
|
||||
|
||||
Extract audio track from video using the API.
|
||||
|
||||
* `curl -F "file=@input.mov" 127.0.0.1:3000/video/extract/audio`
|
||||
** Returns 1-channel WAV-file of video's audio track.
|
||||
* `curl -F "file=@input.mov" 127.0.0.1:3000/video/extract/audio?mono=no`
|
||||
** Returns WAV-file of video's audio track, with all the channels as in input video.
|
||||
|
||||
=== Probe
|
||||
|
||||
Probe audio/video/image files using the API.
|
||||
|
||||
* `curl -F "file=@input.mov" 127.0.0.1:3000/probe`
|
||||
** Returns JSON metadata of media file.
|
||||
** The same JSON metadata as in ffprobe command: `ffprobe -of json -show_streams -show_format input.mov`.
|
||||
** See sample of MOV-video metadata: link:./samples/probe_metadata.json[probe_metadata.json].
|
||||
|
||||
|
||||
== Background
|
||||
|
||||
Originally developed by https://github.com/surebert[Paul Visco].
|
||||
|
||||
Changes include updated Node.js version, Docker image based on Alpine, logging and others.
|
||||
Changes include new functionality, updated Node.js version, Docker image based on Alpine, logging and other major refactoring.
|
||||
|
|
20
src/app.js
20
src/app.js
|
@ -26,28 +26,27 @@ app.use(compression());
|
|||
var upload = require('./routes/uploadfile.js');
|
||||
app.use(upload);
|
||||
|
||||
//test route for development
|
||||
var test = require('./routes/test.js');
|
||||
app.use('/test', test);
|
||||
|
||||
//routes to convert audio/video/image files to mp3/mp4/jpg
|
||||
var convert = require('./routes/convert.js');
|
||||
app.use('/convert', convert);
|
||||
|
||||
//routes to extract images or audio from video
|
||||
var extract = require('./routes/extract.js');
|
||||
app.use('/video/extract', extract);
|
||||
|
||||
//routes to probe file info
|
||||
var probe = require('./routes/probe.js');
|
||||
app.use('/probe', probe);
|
||||
|
||||
require('express-readme')(app, {
|
||||
filename: 'index.md',
|
||||
routes: ['/'],
|
||||
});
|
||||
|
||||
|
||||
const server = app.listen(constants.serverPort, function() {
|
||||
let host = server.address().address;
|
||||
let port = server.address().port;
|
||||
logger.info('listening http://'+host+':'+port)
|
||||
logger.info('Server started and listening http://'+host+':'+port)
|
||||
});
|
||||
|
||||
server.on('connection', function(socket) {
|
||||
|
@ -58,9 +57,9 @@ server.on('connection', function(socket) {
|
|||
});
|
||||
|
||||
app.get('/endpoints', function(req, res) {
|
||||
let code = 200;
|
||||
res.writeHead(code, {'content-type' : 'text/plain'});
|
||||
res.end("Endpoints:\n\n"+JSON.stringify(all_routes(app),null,2)+'\n');
|
||||
res.status(200).send(all_routes(app));
|
||||
//res.writeHead(200, {'content-type' : 'text/plain'});
|
||||
//res.end("Endpoints:\n\n"+JSON.stringify(all_routes(app),null,2)+'\n');
|
||||
});
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
|
@ -76,6 +75,3 @@ app.use(function(err, req, res, next){
|
|||
res.end(`${err.message}\n`);
|
||||
|
||||
});
|
||||
|
||||
|
||||
logger.debug(JSON.stringify(all_routes(app)));
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
exports.fileSizeLimit = parseInt(process.env.FILE_SIZE_LIMIT_BYTES || "536870912"); //536870912 = 512MB
|
||||
exports.defaultFFMPEGProcessPriority=10;
|
||||
exports.serverPort = 3000;//port to listen, NOTE: if using Docker/Kubernetes this port may not be the one clients are using
|
||||
exports.keepAllFiles = process.env.KEEP_ALL_FILES || "false"; //if true, do not delete any uploaded/generated files
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
"description": "API for FFMPEG, media conversion utility",
|
||||
"main": "app.js",
|
||||
"bin" : { "ffmpegapi" : "./app.js" },
|
||||
"author": {
|
||||
"name": "Paul Visco",
|
||||
"email": "paul.visco@gmail.com"
|
||||
},
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"busboy": "~0.3.1",
|
||||
|
|
|
@ -1,33 +1,40 @@
|
|||
var express = require('express')
|
||||
const fs = require('fs');
|
||||
const ffmpeg = require('fluent-ffmpeg');
|
||||
|
||||
const constants = require('../constants.js');
|
||||
const logger = require('../utils/logger.js')
|
||||
const utils = require('../utils/utils.js')
|
||||
|
||||
var router = express.Router()
|
||||
const logger = require('../utils/logger.js')
|
||||
|
||||
|
||||
//routes for /convert
|
||||
//adds conversion type and format to res.locals. to be used in final post function
|
||||
router.post('/audio/to/mp3', function (req, res,next) {
|
||||
|
||||
res.locals.conversion="audio"
|
||||
res.locals.format="mp3"
|
||||
res.locals.conversion="audio";
|
||||
res.locals.format="mp3";
|
||||
return convert(req,res,next);
|
||||
});
|
||||
|
||||
router.post('/audio/to/wav', function (req, res,next) {
|
||||
|
||||
res.locals.conversion="audio";
|
||||
res.locals.format="wav";
|
||||
return convert(req,res,next);
|
||||
});
|
||||
|
||||
router.post('/video/to/mp4', function (req, res,next) {
|
||||
|
||||
res.locals.conversion="video"
|
||||
res.locals.format="mp4"
|
||||
res.locals.conversion="video";
|
||||
res.locals.format="mp4";
|
||||
return convert(req,res,next);
|
||||
});
|
||||
|
||||
router.post('/image/to/jpg', function (req, res,next) {
|
||||
|
||||
res.locals.conversion="image"
|
||||
res.locals.format="jpg"
|
||||
res.locals.conversion="image";
|
||||
res.locals.format="jpg";
|
||||
return convert(req,res,next);
|
||||
});
|
||||
|
||||
|
@ -36,22 +43,24 @@ function convert(req,res,next) {
|
|||
let format = res.locals.format;
|
||||
let conversion = res.locals.conversion;
|
||||
logger.debug(`path: ${req.path}, conversion: ${conversion}, format: ${format}`);
|
||||
if (conversion == undefined || format == undefined)
|
||||
{
|
||||
res.status(400).send("Invalid convert URL. Use one of: /convert/image/to/jpg, /convert/audio/to/mp3 or /convert/video/to/mp4.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
let ffmpegParams ={
|
||||
extension: format
|
||||
};
|
||||
if (conversion == "image")
|
||||
{
|
||||
ffmpegParams.outputOptions= ['-pix_fmt yuv422p']
|
||||
ffmpegParams.outputOptions= ['-pix_fmt yuv422p'];
|
||||
}
|
||||
if (conversion == "audio")
|
||||
{
|
||||
ffmpegParams.outputOptions=['-codec:a libmp3lame' ]
|
||||
if (format === "mp3")
|
||||
{
|
||||
ffmpegParams.outputOptions=['-codec:a libmp3lame' ];
|
||||
}
|
||||
if (format === "wav")
|
||||
{
|
||||
ffmpegParams.outputOptions=['-codec:a pcm_s16le' ];
|
||||
}
|
||||
}
|
||||
if (conversion == "video")
|
||||
{
|
||||
|
@ -88,16 +97,7 @@ function convert(req,res,next) {
|
|||
})
|
||||
.on('end', function() {
|
||||
utils.deleteFile(savedFile);
|
||||
logger.debug(`starting download to client ${savedFile}`);
|
||||
|
||||
res.download(outputFile, null, function(err) {
|
||||
if (err) {
|
||||
logger.error(`download ${err}`);
|
||||
}
|
||||
else {
|
||||
utils.deleteFile(`${outputFile}`);
|
||||
}
|
||||
});
|
||||
return utils.downloadFile(outputFile,null,req,res,next);
|
||||
})
|
||||
.save(outputFile);
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@ const uniqueFilename = require('unique-filename');
|
|||
var archiver = require('archiver');
|
||||
|
||||
const constants = require('../constants.js');
|
||||
const logger = require('../utils/logger.js');
|
||||
const utils = require('../utils/utils.js');
|
||||
|
||||
var router = express.Router()
|
||||
const logger = require('../utils/logger.js')
|
||||
const utils = require('../utils/utils.js')
|
||||
var router = express.Router();
|
||||
|
||||
|
||||
//routes for /video/extract
|
||||
|
@ -29,24 +29,8 @@ router.post('/images', function (req, res,next) {
|
|||
router.get('/download/:filename', function (req, res,next) {
|
||||
//download extracted image
|
||||
let filename = req.params.filename;
|
||||
let deleteFile = req.query.delete || "true";
|
||||
|
||||
let file = `/tmp/${filename}`
|
||||
logger.debug(`starting download to client ${file}`);
|
||||
res.download(file, filename, function(err) {
|
||||
if (err) {
|
||||
logger.error(`download ${err}`);
|
||||
}
|
||||
else
|
||||
{
|
||||
//delete file if no delete=no query parameter
|
||||
if (deleteFile === "true" || deleteFile === "yes")
|
||||
{
|
||||
utils.deleteFile(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return utils.downloadFile(file,null,req,res,next);
|
||||
});
|
||||
|
||||
// extract audio or images from video
|
||||
|
@ -68,9 +52,18 @@ function extract(req,res,next) {
|
|||
if (extract === "audio"){
|
||||
format = "wav"
|
||||
ffmpegParams.outputOptions=[
|
||||
`-ac 1` ,
|
||||
'-vn',
|
||||
`-f ${format}`
|
||||
];
|
||||
let monoAudio = req.query.mono || "yes";
|
||||
if (monoAudio === "yes" || monoAudio === "true")
|
||||
{
|
||||
logger.debug("extracting audio, 1 channel only")
|
||||
ffmpegParams.outputOptions.push('-ac 1')
|
||||
}
|
||||
else{
|
||||
logger.debug("extracting audio, all channels")
|
||||
}
|
||||
}
|
||||
|
||||
ffmpegParams.extension = format;
|
||||
|
@ -82,7 +75,7 @@ function extract(req,res,next) {
|
|||
var uniqueFileNamePrefix = outputFile.replace("/tmp/","");
|
||||
logger.debug(`uniqueFileNamePrefix ${uniqueFileNamePrefix}`);
|
||||
|
||||
//ffmpeg processing... converting file...
|
||||
//ffmpeg processing...
|
||||
var ffmpegCommand = ffmpeg(savedFile);
|
||||
ffmpegCommand = ffmpegCommand
|
||||
.renice(constants.defaultFFMPEGProcessPriority)
|
||||
|
@ -94,6 +87,21 @@ function extract(req,res,next) {
|
|||
res.end(JSON.stringify({error: `${err}`}));
|
||||
})
|
||||
|
||||
//extract audio track from video as wav
|
||||
if (extract === "audio"){
|
||||
let wavFile = `${outputFile}.${format}`;
|
||||
ffmpegCommand
|
||||
.on('end', function() {
|
||||
logger.debug(`ffmpeg process ended`);
|
||||
|
||||
utils.deleteFile(savedFile)
|
||||
return utils.downloadFile(wavFile,null,req,res,next);
|
||||
})
|
||||
.save(wavFile);
|
||||
|
||||
}
|
||||
|
||||
//extract png images from video
|
||||
if (extract === "images"){
|
||||
ffmpegCommand
|
||||
.output(`${outputFile}-%04d.png`)
|
||||
|
@ -154,20 +162,8 @@ function extract(req,res,next) {
|
|||
utils.deleteFile(file);
|
||||
}
|
||||
|
||||
//return tar.gz
|
||||
logger.debug(`starting download to client ${compressFilePath}`);
|
||||
res.download(compressFilePath, compressFileName, function(err) {
|
||||
if (err) {
|
||||
logger.error(`download gzip error: ${err}`);
|
||||
return next(err);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.debug(`download complete ${compressFilePath}`);
|
||||
utils.deleteFile(compressFilePath);
|
||||
}
|
||||
});
|
||||
|
||||
//return compressed file
|
||||
return utils.downloadFile(compressFilePath,compressFileName,req,res,next);
|
||||
|
||||
});
|
||||
// Wait for streams to complete
|
||||
|
@ -181,7 +177,7 @@ function extract(req,res,next) {
|
|||
logger.debug(`output files in /tmp`);
|
||||
var responseJson = {};
|
||||
responseJson["totalfiles"] = files.length;
|
||||
responseJson["description"] = "Extracted image files and URLs to download them. By default, downloading image also deletes the image from server. Note port in the URL may be different if server is running on Docker/Kubernetes.";
|
||||
responseJson["description"] = `Extracted image files and URLs to download them. By default, downloading image also deletes the image from server. Note that port ${constants.serverPort} in the URL may not be the same as the real port, especially if server is running on Docker/Kubernetes.`;
|
||||
var filesArray=[];
|
||||
for (var i=0; i < files.length; i++) {
|
||||
var file = files[i];
|
||||
|
@ -197,13 +193,9 @@ function extract(req,res,next) {
|
|||
}
|
||||
})
|
||||
.run();
|
||||
// .save(outputFile);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
module.exports = router
|
33
src/routes/probe.js
Normal file
33
src/routes/probe.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
var express = require('express')
|
||||
const ffmpeg = require('fluent-ffmpeg');
|
||||
|
||||
const logger = require('../utils/logger.js');
|
||||
const utils = require('../utils/utils.js');
|
||||
|
||||
var router = express.Router();
|
||||
|
||||
//probe input file and return metadata
|
||||
router.post('/', function (req, res,next) {
|
||||
|
||||
let savedFile = res.locals.savedFile;
|
||||
logger.debug(`Probing ${savedFile}`);
|
||||
|
||||
//ffmpeg processing...
|
||||
var ffmpegCommand = ffmpeg(savedFile)
|
||||
|
||||
ffmpegCommand.ffprobe(function(err, metadata) {
|
||||
if (err)
|
||||
{
|
||||
next(err);
|
||||
}
|
||||
else
|
||||
{
|
||||
utils.deleteFile(savedFile);
|
||||
res.status(200).send(metadata);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
module.exports = router
|
|
@ -1,22 +0,0 @@
|
|||
var express = require('express')
|
||||
|
||||
|
||||
var router = express.Router()
|
||||
const logger = require('../utils/logger.js')
|
||||
|
||||
//route to handle file upload in all POST requests
|
||||
|
||||
|
||||
// convert audio or video or image to mp3 or mp4 or jpg
|
||||
router.post("/",function (req, res,next) {
|
||||
logger.debug("path: " + req.path);
|
||||
logger.debug("req.params: ");
|
||||
for (const key in req.params) {
|
||||
logger.debug(`${key}: ${req.params[key]}`);
|
||||
}
|
||||
logger.debug("res.locals.savedFile: " + res.locals.savedFile);
|
||||
res.status(200).send("Test OK.");
|
||||
|
||||
});
|
||||
|
||||
module.exports = router;
|
|
@ -1,12 +1,44 @@
|
|||
const fs = require('fs');
|
||||
const logger = require('./logger.js')
|
||||
|
||||
const constants = require('../constants.js');
|
||||
|
||||
function deleteFile (filepath) {
|
||||
fs.unlinkSync(filepath);
|
||||
logger.debug(`deleted ${filepath}`);
|
||||
if (constants.keepAllFiles === "false")
|
||||
{
|
||||
fs.unlinkSync(filepath);
|
||||
logger.debug(`deleted ${filepath}`);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.debug(`NOT deleted ${filepath}`);
|
||||
}
|
||||
}
|
||||
|
||||
function downloadFile (filepath,filename,req,res,next) {
|
||||
|
||||
logger.debug(`starting download to client. file: ${filepath}`);
|
||||
|
||||
res.download(filepath, filename, function(err) {
|
||||
if (err) {
|
||||
logger.error(`download error: ${err}`);
|
||||
return next(err);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.debug(`download complete ${filepath}`);
|
||||
let doDelete = req.query.delete || "true";
|
||||
//delete file if doDelete is true
|
||||
if (doDelete === "true" || doDelete === "yes")
|
||||
{
|
||||
deleteFile(filepath);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
deleteFile
|
||||
deleteFile,
|
||||
downloadFile
|
||||
}
|
Loading…
Reference in New Issue
Block a user