restructuring and changes
This commit is contained in:
parent
d817d40ec2
commit
76cad0a25b
|
@ -1,7 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
"extends": "google",
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 6
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
67
Dockerfile
67
Dockerfile
|
@ -1,13 +1,9 @@
|
||||||
FROM jrottenberg/ffmpeg:centos
|
|
||||||
|
|
||||||
MAINTAINER Paul Visco <paul.visco@gmail.com>
|
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
#
|
#
|
||||||
# A Docker image to convert audio and video for web using web API
|
# A Docker image to convert audio and video for web using web API
|
||||||
#
|
#
|
||||||
# with
|
# with
|
||||||
# - Latest FFMPEG (built)
|
# - FFMPEG (built)
|
||||||
# - NodeJS
|
# - NodeJS
|
||||||
# - fluent-ffmpeg
|
# - fluent-ffmpeg
|
||||||
#
|
#
|
||||||
|
@ -15,47 +11,46 @@ MAINTAINER Paul Visco <paul.visco@gmail.com>
|
||||||
#
|
#
|
||||||
# https://github.com/fluent-ffmpeg/node-fluent-ffmpeg
|
# https://github.com/fluent-ffmpeg/node-fluent-ffmpeg
|
||||||
#
|
#
|
||||||
|
# Original image and FFMPEG API by Paul Visco
|
||||||
|
# https://github.com/surebert/docker-ffmpeg-service
|
||||||
|
#
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
|
||||||
# Add the following two dependencies for nodejs
|
FROM node:12.16.2-alpine3.11 as build
|
||||||
RUN yum install -y git
|
|
||||||
RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
|
|
||||||
RUN yum install -y nodejs npm --enablerepo=epel
|
|
||||||
|
|
||||||
WORKDIR /usr/local/src
|
RUN apk add --no-cache git
|
||||||
|
|
||||||
# Custom Builds go here
|
# install pkg
|
||||||
RUN npm install -g fluent-ffmpeg
|
RUN npm install -g pkg
|
||||||
|
|
||||||
# Remove all tmpfile and cleanup
|
ENV PKG_CACHE_PATH /usr/cache
|
||||||
# =================================
|
|
||||||
WORKDIR /usr/local/
|
|
||||||
RUN rm -rf /usr/local/src
|
|
||||||
RUN yum clean all
|
|
||||||
RUN rm -rf /var/cache/yum
|
|
||||||
|
|
||||||
# =================================
|
|
||||||
|
|
||||||
# Setup a working directory to allow for
|
|
||||||
# docker run --rm -ti -v ${PWD}:/work ...
|
|
||||||
# =======================================
|
|
||||||
WORKDIR /work
|
|
||||||
|
|
||||||
# Make sure Node.js is installed
|
|
||||||
RUN node -v
|
|
||||||
RUN npm -v
|
|
||||||
|
|
||||||
#Create app dir
|
|
||||||
RUN mkdir -p /usr/src/app
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
#Install Dependencies
|
# Bundle app source
|
||||||
COPY package.json /usr/src/app
|
COPY ./src .
|
||||||
RUN npm install
|
RUN npm install
|
||||||
|
|
||||||
#Bundle app source
|
# Create single binary file
|
||||||
COPY . /usr/src/app
|
RUN pkg --targets node12-alpine-x64 /usr/src/app/package.json
|
||||||
|
|
||||||
|
|
||||||
|
FROM jrottenberg/ffmpeg:4.2-alpine311
|
||||||
|
|
||||||
|
# Create user and change workdir
|
||||||
|
RUN adduser --disabled-password --home /home/ffmpgapi ffmpgapi
|
||||||
|
WORKDIR /home/ffmpgapi
|
||||||
|
|
||||||
|
# Copy files from build stage
|
||||||
|
COPY --from=build /usr/src/app/ffmpegapi .
|
||||||
|
COPY --from=build /usr/src/app/index.md .
|
||||||
|
RUN chown ffmpgapi:ffmpgapi * && chmod 755 ffmpegapi
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Change user
|
||||||
|
USER ffmpgapi
|
||||||
|
|
||||||
ENTRYPOINT []
|
ENTRYPOINT []
|
||||||
CMD [ "node", "app.js" ]
|
CMD [ "./ffmpegapi" ]
|
||||||
|
|
||||||
|
|
65
README.adoc
Normal file
65
README.adoc
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
= FFMPEG API
|
||||||
|
|
||||||
|
An web service for converting audio/video files using FFMPEG.
|
||||||
|
|
||||||
|
Based on:
|
||||||
|
|
||||||
|
* https://github.com/surebert/docker-ffmpeg-service
|
||||||
|
* https://github.com/jrottenberg/ffmpeg
|
||||||
|
|
||||||
|
FFMPEG API is provided as Docker image for easy consumption.
|
||||||
|
|
||||||
|
== Endpoints
|
||||||
|
|
||||||
|
* `POST /mp3` - Convert audio file in request body to mp3
|
||||||
|
* `POST /mp4` - Convert video file in request body to mp4
|
||||||
|
* `POST /jpg` - Convert image file to jpg
|
||||||
|
* `GET /' - API Readme
|
||||||
|
|
||||||
|
== Usage
|
||||||
|
|
||||||
|
Convert audio/video/image files using the API.
|
||||||
|
|
||||||
|
* `curl -F "file=@input.wav" 127.0.0.1:3000/mp3 > output.mp3`
|
||||||
|
* `curl -F "file=@input.m4a" 127.0.0.1:3000/mp3 > output.mp3`
|
||||||
|
* `curl -F "file=@input.mov" 127.0.0.1:3000/mp4 > output.mp4`
|
||||||
|
* `curl -F "file=@input.mp4" 127.0.0.1:3000/mp4 > output.mp4`
|
||||||
|
* `curl -F "file=@input.tiff" 127.0.0.1:3000/jpg > output.jpg`
|
||||||
|
* `curl -F "file=@input.png" 127.0.0.1:3000/jpg > output.jpg`
|
||||||
|
|
||||||
|
== Configuration and New Endpoints
|
||||||
|
|
||||||
|
You can change the ffmpeg conversion settings or add new endpoints by editing
|
||||||
|
the link:src/endpoints.js[src/endpoints.js] file.
|
||||||
|
|
||||||
|
== Docker image
|
||||||
|
|
||||||
|
=== Build your own
|
||||||
|
|
||||||
|
* Clone this repository.
|
||||||
|
* Build Docker image:
|
||||||
|
** `docker build -t ffmpeg-api .`
|
||||||
|
* Run image in foreground:
|
||||||
|
** `docker run -it --rm -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`
|
||||||
|
* Run image in background:
|
||||||
|
** `docker run -d --name ffmpeg-api -p 3000:3000 kazhar/ffmpeg-api`
|
||||||
|
|
||||||
|
=== Logging
|
||||||
|
|
||||||
|
Default log level is INFO. Set log level using environment variable.
|
||||||
|
|
||||||
|
- Set log level to debug:
|
||||||
|
- `docker run -it --rm -p 3000:3000 -e LOG_LEVEL=debug kazhar/ffmpeg-api`
|
||||||
|
|
||||||
|
== Background
|
||||||
|
|
||||||
|
Originally developed by https://github.com/surebert[Paul Visco].
|
||||||
|
|
||||||
|
Changes include updated Node.js version, Docker image based on Alpine, logging and others.
|
75
README.md
75
README.md
|
@ -1,75 +0,0 @@
|
||||||
# ffmpeg web service API
|
|
||||||
|
|
||||||
An web service for converting audio/video files using Nodejs, Express and FFMPEG
|
|
||||||
|
|
||||||
Based off of jrottenberg/ffmpeg container
|
|
||||||
|
|
||||||
## Endpoints
|
|
||||||
|
|
||||||
> POST /mp3 - Convert audio file in request body to mp3
|
|
||||||
|
|
||||||
> POST /mp4 - Convert video file in request body to mp4
|
|
||||||
|
|
||||||
> POST /jpg - Convert image file to jpg
|
|
||||||
|
|
||||||
> GET /, /readme - Web Service Readme
|
|
||||||
|
|
||||||
### /mp3, /m4a
|
|
||||||
|
|
||||||
Curl Ex:
|
|
||||||
|
|
||||||
> curl -F "file=@input.wav" 127.0.0.1:3000/mp3 > output.mp3
|
|
||||||
|
|
||||||
> curl -F "file=@input.m4a" 127.0.0.1:3000/mp3 > output.mp3
|
|
||||||
|
|
||||||
> curl -F "file=@input.mov" 127.0.0.1:3000/mp4 > output.mp4
|
|
||||||
|
|
||||||
> curl -F "file=@input.mp4" 127.0.0.1:3000/mp4 > output.mp4
|
|
||||||
|
|
||||||
> curl -F "file=@input.tiff" 127.0.0.1:3000/jpg > output.jpg
|
|
||||||
|
|
||||||
> curl -F "file=@input.png" 127.0.0.1:3000/jpg > output.jpg
|
|
||||||
|
|
||||||
## Configuration and New Endpoints
|
|
||||||
You can change the ffmpeg conversion settings or add new endpoints by editing
|
|
||||||
the /app/endpoints.js file
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Requires local Node and FFMPEG installation.
|
|
||||||
|
|
||||||
1) Install FFMPEG https://ffmpeg.org/download.html
|
|
||||||
|
|
||||||
2) Install node https://nodejs.org/en/download/
|
|
||||||
Using homebrew:
|
|
||||||
> $ brew install node
|
|
||||||
|
|
||||||
## Dev - Running Local Node.js Web Service
|
|
||||||
|
|
||||||
Navigate to project directory and:
|
|
||||||
|
|
||||||
Install dependencies:
|
|
||||||
> $ npm install
|
|
||||||
|
|
||||||
Start app:
|
|
||||||
> $ node app.js
|
|
||||||
|
|
||||||
Check for errors with ESLint:
|
|
||||||
> $ ./node_modules/.bin/eslint .
|
|
||||||
|
|
||||||
## Running Local Docker Container
|
|
||||||
|
|
||||||
Build Docker Image from Dockerfile with a set image tag. ex: docker-ffpmeg
|
|
||||||
> $ docker build -t surebert/docker-ffpmeg .
|
|
||||||
|
|
||||||
Launch Docker Container from Docker Image, exposing port 9025 on localhost only
|
|
||||||
|
|
||||||
> docker run -d \
|
|
||||||
--name ffmpeg-service \
|
|
||||||
--restart=always \
|
|
||||||
-v /storage/tmpfs:/usr/src/app/uploads \
|
|
||||||
-p 127.0.0.1:9025:3000 \
|
|
||||||
surebert/docker-ffpmeg
|
|
||||||
|
|
||||||
Launch Docker Container from Docker Image, exposing port 9026 on all IPs
|
|
||||||
> docker run -p 9025:3000 -d surebert/docker-ffpmeg
|
|
25
package.json
25
package.json
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
"name": "node-ffmpeg-av",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "media conversion utilities",
|
|
||||||
"main": "index.js",
|
|
||||||
"author": {
|
|
||||||
"name": "Paul Visco",
|
|
||||||
"email": "paul.visco@gmail.com"
|
|
||||||
},
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"busboy": "^0.2.14",
|
|
||||||
"compression": "^1.7.2",
|
|
||||||
"express": "^4.16.3",
|
|
||||||
"express-readme": "0.0.5",
|
|
||||||
"fluent-ffmpeg": "^2.1.2",
|
|
||||||
"fs": "0.0.1-security",
|
|
||||||
"unique-filename": "^1.1.0",
|
|
||||||
"winston": "^2.3.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^3.19.0",
|
|
||||||
"eslint-config-google": "^0.8.0"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,13 +5,41 @@ const Busboy = require('busboy');
|
||||||
const compression = require('compression');
|
const compression = require('compression');
|
||||||
const ffmpeg = require('fluent-ffmpeg');
|
const ffmpeg = require('fluent-ffmpeg');
|
||||||
const uniqueFilename = require('unique-filename');
|
const uniqueFilename = require('unique-filename');
|
||||||
const consts = require(__dirname + '/app/constants.js');
|
const consts = require('./constants.js');
|
||||||
const endpoints = require(__dirname + '/app/endpoints.js');
|
const endpoints = require('./endpoints.js');
|
||||||
const winston = require('winston');
|
|
||||||
|
//const winston = require('winston');
|
||||||
|
//setup custom logger
|
||||||
|
const { createLogger, format, transports } = require('winston');
|
||||||
|
const { combine, timestamp, label, printf } = format;
|
||||||
|
|
||||||
|
const logFormat = printf(({ level, message, label, timestamp }) => {
|
||||||
|
return `${timestamp} [${label}] ${level}: ${message}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const logger = createLogger({
|
||||||
|
format: combine(
|
||||||
|
label({ label: 'ffmpegapi' }),
|
||||||
|
timestamp(),
|
||||||
|
logFormat
|
||||||
|
),
|
||||||
|
transports: [new transports.Console({
|
||||||
|
level: process.env.LOG_LEVEL || 'info'
|
||||||
|
})]
|
||||||
|
});
|
||||||
|
|
||||||
|
// catch SIGINT and SIGTERM and exit
|
||||||
|
// Using a single function to handle multiple signals
|
||||||
|
function handle(signal) {
|
||||||
|
console.log(`Received ${signal}. Exiting...`);
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
//SIGINT is typically CTRL-C
|
||||||
|
process.on('SIGINT', handle);
|
||||||
|
//SIGTERM is sent to terminate process, for example docker stop sends SIGTERM
|
||||||
|
process.on('SIGTERM', handle);
|
||||||
|
|
||||||
app.use(compression());
|
app.use(compression());
|
||||||
winston.remove(winston.transports.Console);
|
|
||||||
winston.add(winston.transports.Console, {'timestamp': true});
|
|
||||||
|
|
||||||
for (let prop in endpoints.types) {
|
for (let prop in endpoints.types) {
|
||||||
if (endpoints.types.hasOwnProperty(prop)) {
|
if (endpoints.types.hasOwnProperty(prop)) {
|
||||||
|
@ -20,7 +48,8 @@ for (let prop in endpoints.types) {
|
||||||
app.post('/' + prop, function(req, res) {
|
app.post('/' + prop, function(req, res) {
|
||||||
let hitLimit = false;
|
let hitLimit = false;
|
||||||
let fileName = '';
|
let fileName = '';
|
||||||
let savedFile = uniqueFilename(__dirname + '/uploads/');
|
//let savedFile = uniqueFilename(__dirname + '/uploads/');
|
||||||
|
let savedFile = uniqueFilename('/tmp/');
|
||||||
let busboy = new Busboy({
|
let busboy = new Busboy({
|
||||||
headers: req.headers,
|
headers: req.headers,
|
||||||
limits: {
|
limits: {
|
||||||
|
@ -28,7 +57,7 @@ for (let prop in endpoints.types) {
|
||||||
fileSize: consts.fileSizeLimit,
|
fileSize: consts.fileSizeLimit,
|
||||||
}});
|
}});
|
||||||
busboy.on('filesLimit', function() {
|
busboy.on('filesLimit', function() {
|
||||||
winston.error(JSON.stringify({
|
logger.error(JSON.stringify({
|
||||||
type: 'filesLimit',
|
type: 'filesLimit',
|
||||||
message: 'Upload file size limit hit',
|
message: 'Upload file size limit hit',
|
||||||
}));
|
}));
|
||||||
|
@ -45,7 +74,7 @@ for (let prop in endpoints.types) {
|
||||||
hitLimit = true;
|
hitLimit = true;
|
||||||
let err = {file: filename, error: 'exceeds max size limit'};
|
let err = {file: filename, error: 'exceeds max size limit'};
|
||||||
err = JSON.stringify(err);
|
err = JSON.stringify(err);
|
||||||
winston.error(err);
|
logger.error(err);
|
||||||
res.writeHead(500, {'Connection': 'close'});
|
res.writeHead(500, {'Connection': 'close'});
|
||||||
res.end(err);
|
res.end(err);
|
||||||
});
|
});
|
||||||
|
@ -54,24 +83,24 @@ for (let prop in endpoints.types) {
|
||||||
encoding: encoding,
|
encoding: encoding,
|
||||||
mimetype: mimetype,
|
mimetype: mimetype,
|
||||||
};
|
};
|
||||||
winston.info(JSON.stringify(log));
|
logger.log('debug',JSON.stringify(log));
|
||||||
file.on('data', function(data) {
|
file.on('data', function(data) {
|
||||||
bytes += data.length;
|
bytes += data.length;
|
||||||
});
|
});
|
||||||
file.on('end', function(data) {
|
file.on('end', function(data) {
|
||||||
log.bytes = bytes;
|
log.bytes = bytes;
|
||||||
winston.info(JSON.stringify(log));
|
logger.log('debug',JSON.stringify(log));
|
||||||
});
|
});
|
||||||
|
|
||||||
fileName = filename;
|
fileName = filename;
|
||||||
winston.info(JSON.stringify({
|
logger.log('debug',JSON.stringify({
|
||||||
action: 'Uploading',
|
action: 'Uploading',
|
||||||
name: fileName,
|
name: fileName,
|
||||||
}));
|
}));
|
||||||
let written = file.pipe(fs.createWriteStream(savedFile));
|
let written = file.pipe(fs.createWriteStream(savedFile));
|
||||||
|
|
||||||
if (written) {
|
if (written) {
|
||||||
winston.info(JSON.stringify({
|
logger.log('debug',JSON.stringify({
|
||||||
action: 'saved',
|
action: 'saved',
|
||||||
path: savedFile,
|
path: savedFile,
|
||||||
}));
|
}));
|
||||||
|
@ -82,12 +111,12 @@ for (let prop in endpoints.types) {
|
||||||
fs.unlinkSync(savedFile);
|
fs.unlinkSync(savedFile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
winston.info(JSON.stringify({
|
logger.log('debug',JSON.stringify({
|
||||||
action: 'upload complete',
|
action: 'upload complete',
|
||||||
name: fileName,
|
name: fileName,
|
||||||
}));
|
}));
|
||||||
let outputFile = savedFile + '.' + ffmpegParams.extension;
|
let outputFile = savedFile + '.' + ffmpegParams.extension;
|
||||||
winston.info(JSON.stringify({
|
logger.log('debug',JSON.stringify({
|
||||||
action: 'begin conversion',
|
action: 'begin conversion',
|
||||||
from: savedFile,
|
from: savedFile,
|
||||||
to: outputFile,
|
to: outputFile,
|
||||||
|
@ -101,31 +130,31 @@ for (let prop in endpoints.types) {
|
||||||
type: 'ffmpeg',
|
type: 'ffmpeg',
|
||||||
message: err,
|
message: err,
|
||||||
});
|
});
|
||||||
winston.error(log);
|
logger.error(log);
|
||||||
fs.unlinkSync(savedFile);
|
fs.unlinkSync(savedFile);
|
||||||
res.writeHead(500, {'Connection': 'close'});
|
res.writeHead(500, {'Connection': 'close'});
|
||||||
res.end(log);
|
res.end(log);
|
||||||
})
|
})
|
||||||
.on('end', function() {
|
.on('end', function() {
|
||||||
fs.unlinkSync(savedFile);
|
fs.unlinkSync(savedFile);
|
||||||
winston.info(JSON.stringify({
|
logger.log('debug',JSON.stringify({
|
||||||
action: 'starting download to client',
|
action: 'starting download to client',
|
||||||
file: savedFile,
|
file: savedFile,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
res.download(outputFile, null, function(err) {
|
res.download(outputFile, null, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
winston.error(JSON.stringify({
|
logger.error(JSON.stringify({
|
||||||
type: 'download',
|
type: 'download',
|
||||||
message: err,
|
message: err,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
winston.info(JSON.stringify({
|
logger.log('debug',JSON.stringify({
|
||||||
action: 'deleting',
|
action: 'deleting',
|
||||||
file: outputFile,
|
file: outputFile,
|
||||||
}));
|
}));
|
||||||
if (fs.unlinkSync(outputFile)) {
|
if (fs.unlinkSync(outputFile)) {
|
||||||
winston.info(JSON.stringify({
|
logger.log('debug',JSON.stringify({
|
||||||
action: 'deleted',
|
action: 'deleted',
|
||||||
file: outputFile,
|
file: outputFile,
|
||||||
}));
|
}));
|
||||||
|
@ -140,21 +169,23 @@ for (let prop in endpoints.types) {
|
||||||
}
|
}
|
||||||
|
|
||||||
require('express-readme')(app, {
|
require('express-readme')(app, {
|
||||||
filename: 'README.md',
|
filename: 'index.md',
|
||||||
routes: ['/', '/readme'],
|
routes: ['/', '/readme'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const server = app.listen(consts.port, function() {
|
const server = app.listen(consts.port, function() {
|
||||||
let host = server.address().address;
|
let host = server.address().address;
|
||||||
let port = server.address().port;
|
let port = server.address().port;
|
||||||
winston.info(JSON.stringify({
|
logger.info(JSON.stringify({
|
||||||
action: 'listening',
|
action: 'listening',
|
||||||
url: 'http://'+host+':'+port,
|
url: 'http://'+host+':'+port,
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
server.on('connection', function(socket) {
|
server.on('connection', function(socket) {
|
||||||
winston.info(JSON.stringify({
|
logger.log('debug',JSON.stringify({
|
||||||
action: 'new connection',
|
action: 'new connection',
|
||||||
timeout: consts.timeout,
|
timeout: consts.timeout,
|
||||||
}));
|
}));
|
24
src/index.md
Normal file
24
src/index.md
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# ffmpeg API
|
||||||
|
|
||||||
|
An web service for converting audio/video files using FFMPEG.
|
||||||
|
|
||||||
|
Based on https://github.com/surebert/docker-ffmpeg-service and https://github.com/jrottenberg/ffmpeg
|
||||||
|
|
||||||
|
|
||||||
|
### Endpoints
|
||||||
|
|
||||||
|
- `POST /mp3` - Convert audio file in request body to mp3
|
||||||
|
- `POST /mp4` - Convert video file in request body to mp4
|
||||||
|
- `POST /jpg` - Convert image file to jpg
|
||||||
|
- `GET /` - Web Service Readme, this file
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
- `curl -F "file=@input.wav" 127.0.0.1:3000/mp3 > output.mp3`
|
||||||
|
- `curl -F "file=@input.m4a" 127.0.0.1:3000/mp3 > output.mp3`
|
||||||
|
- `curl -F "file=@input.mov" 127.0.0.1:3000/mp4 > output.mp4`
|
||||||
|
- `curl -F "file=@input.mp4" 127.0.0.1:3000/mp4 > output.mp4`
|
||||||
|
- `curl -F "file=@input.tiff" 127.0.0.1:3000/jpg > output.jpg`
|
||||||
|
- `curl -F "file=@input.png" 127.0.0.1:3000/jpg > output.jpg`
|
||||||
|
|
||||||
|
|
26
src/package.json
Normal file
26
src/package.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"name": "ffmpegapi",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"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",
|
||||||
|
"compression": "^1.7.4",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"express-readme": "0.0.5",
|
||||||
|
"fluent-ffmpeg": "^2.1.2",
|
||||||
|
"fs": "0.0.1-security",
|
||||||
|
"unique-filename": "^1.1.1",
|
||||||
|
"winston": "^3.2.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"eslint-config-google": "^0.14.0"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user