UNPKG

@lumen5/beamcoder

Version:

Node.js native bindings to FFmpeg.

56 lines (46 loc) 2.63 kB
/* Aerostat Beam Coder - Node.js native bindings for FFmpeg. Copyright (C) 2019 Streampunk Media Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. https://www.streampunk.media/ mailto:furnace@streampunk.media 14 Ormiscaig, Aultbea, Achnasheen, IV22 2JJ U.K. */ /* Main example from the README.md. Run in a folder of media files. Only supports 8-bit YUV 4:2:2 or 4:2:0 pixel formats. */ const beamcoder = require('../index.js'); // Use require('beamcoder') externally const Koa = require('koa'); // Add koa to package.json dependencies const app = new Koa(); app.use(async (ctx) => { // Assume HTTP GET with path /<file_name>/<time_in_s> let parts = ctx.path.split('/'); // Split the path into filename and time if ((parts.length < 3) || (isNaN(+parts[2]))) return; // Ignore favicon etc.. let dm = await beamcoder.demuxer('file:' + parts[1]); // Probe the file await dm.seek({ time: +parts[2] }); // Seek to the closest keyframe to time let packet = await dm.read(); // Find the next video packet (assumes stream 0) for ( ; packet.stream_index !== 0 ; packet = await dm.read() ); let dec = beamcoder.decoder({ demuxer: dm, stream_index: 0 }); // Create a decoder let decResult = await dec.decode(packet); // Decode the frame if (decResult.frames.length === 0) // Frame may be buffered, so flush it out decResult = await dec.flush(); // Filtering could be used to transform the picture here, e.g. scaling let enc = beamcoder.encoder({ // Create an encoder for JPEG data name : 'mjpeg', // FFmpeg does not have an encoder called 'jpeg' width : dec.width, height: dec.height, pix_fmt: dec.pix_fmt.indexOf('422') >= 0 ? 'yuvj422p' : 'yuvj420p', time_base: [1, 1] }); let jpegResult = await enc.encode(decResult.frames[0]); // Encode the frame await enc.flush(); // Tidy the encoder ctx.type = 'image/jpeg'; // Set the Content-Type of the data ctx.body = jpegResult.packets[0].data; // Return the JPEG image data }); app.listen(3000); // Start the server on port 3000