The DTP Sites web app development engine.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

100 lines
2.6 KiB

// article.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0
'use strict';
const util = require('util');
const execFile = util.promisify(require('child_process').execFile);
const { SiteService } = require('../../lib/site-lib');
class MediaService extends SiteService {
constructor (dtp) {
super(dtp, module.exports);
}
async ffmpeg (ffmpegArgs) {
try {
await execFile(process.env.DTP_FFMPEG_PATH, ffmpegArgs, {
cwd: this.dtp.config.root,
encoding: 'utf8',
});
} catch (error) {
this.log.error('failed to execute ffprobe', { ffmpegArgs, error });
throw error;
}
}
async ffprobe (input, options) {
options = Object.assign({
streams: true,
format: true,
error: true,
}, options);
const ffprobeOpts = ['-print_format', 'json'];
if (options.streams) {
ffprobeOpts.push('-show_streams');
}
if (options.format) {
ffprobeOpts.push('-show_format');
}
if (options.error) {
ffprobeOpts.push('-show_error');
}
ffprobeOpts.push(input);
try {
const { stdout } = await execFile(process.env.DTP_FFPROBE_PATH, ffprobeOpts, {
cwd: this.dtp.config.root,
encoding: 'utf8',
});
const probe = JSON.parse(stdout);
if (probe.format && probe.format.tags) {
let keys = Object.keys(probe.format.tags);
keys.forEach((key) => {
probe.format.tags[key.replace(/\./g, '_')] = probe.format.tags[key];
delete probe.format.tags[key];
});
}
probe.duration = probe.format.duration;
probe.width = probe.format.width;
if (Array.isArray(probe.streams) && probe.streams.length) {
const stream = probe.streams
.find((stream) => stream.codec_type === 'video') || probe.streams[0];
if (stream.duration) {
probe.duration = parseFloat(stream.duration);
} else {
probe.duration = parseFloat(probe.format.duration);
}
probe.width = stream.width;
probe.height = stream.height;
const fpsFraction = stream.avg_frame_rate.split('/').map((value) => parseInt(value, 10));
if (Array.isArray(fpsFraction) && fpsFraction[1] !== 0) {
probe.fps = fpsFraction[0] / fpsFraction[1];
}
} else {
probe.duration = undefined;
probe.width = undefined;
probe.height = undefined;
}
return probe;
} catch (error) {
this.log.error('failed to execute ffprobe', { input, error });
throw error;
}
}
}
module.exports = {
slug: 'media',
name: 'media',
create: (dtp) => { return new MediaService(dtp); },
};