diff --git a/src/api.js b/src/api.js index 006c8ae..cc75df8 100644 --- a/src/api.js +++ b/src/api.js @@ -303,6 +303,10 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService ) { try { db['ffmpeg-settings'].update({ _id: req.body._id }, req.body) let ffmpeg = db['ffmpeg-settings'].find()[0] + let err = fixupFFMPEGSettings(ffmpeg); + if (typeof(err) !== 'undefined') { + return res.status(400).send(err); + } res.send(ffmpeg) } catch(err) { console.error(err); @@ -323,6 +327,14 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService ) { }) + function fixupFFMPEGSettings(ffmpeg) { + if (typeof(ffmpeg.maxFPS) === 'undefined') { + ffmpeg.maxFPS = 60; + } else if ( isNaN(ffmpeg.maxFPS) ) { + return "maxFPS should be a number"; + } + } + // PLEX SETTINGS router.get('/api/plex-settings', (req, res) => { try { diff --git a/src/database-migration.js b/src/database-migration.js index 90f9995..ded452d 100644 --- a/src/database-migration.js +++ b/src/database-migration.js @@ -20,7 +20,7 @@ const path = require('path'); var fs = require('fs'); -const TARGET_VERSION = 600; +const TARGET_VERSION = 601; const STEPS = [ // [v, v2, x] : if the current version is v, call x(db), and version becomes v2 @@ -31,6 +31,7 @@ const STEPS = [ [ 400, 500, (db,channels) => splitServersSingleChannels(db, channels) ], [ 500, 501, (db) => fixCorruptedServer(db) ], [ 501, 600, () => extractFillersFromChannels() ], + [ 600, 601, (db) => addFPS(db) ], ] const { v4: uuidv4 } = require('uuid'); @@ -392,6 +393,7 @@ function ffmpeg() { normalizeAudioCodec: true, normalizeResolution: true, normalizeAudio: true, + maxFPS: 60, } } @@ -662,6 +664,13 @@ function extractFillersFromChannels() { } +function addFPS(db) { + let ffmpegSettings = db['ffmpeg-settings'].find()[0]; + let f = path.join(process.env.DATABASE, 'ffmpeg-settings.json'); + ffmpegSettings.maxFPS = 60; + fs.writeFileSync( f, JSON.stringify( [ffmpegSettings] ) ); +} + module.exports = { initDB: initDB, defaultFFMPEG: ffmpeg, diff --git a/src/ffmpeg.js b/src/ffmpeg.js index 801b9ba..59b9485 100644 --- a/src/ffmpeg.js +++ b/src/ffmpeg.js @@ -2,6 +2,7 @@ const spawn = require('child_process').spawn const events = require('events') const MAXIMUM_ERROR_DURATION_MS = 60000; +const REALLY_RIDICULOUSLY_HIGH_FPS_FOR_DIZQUETVS_USECASE = 120; class FFMPEG extends events.EventEmitter { constructor(opts, channel) { @@ -9,7 +10,7 @@ class FFMPEG extends events.EventEmitter { this.opts = opts; this.errorPicturePath = `http://localhost:${process.env.PORT}/images/generic-error-screen.png`; if (! this.opts.enableFFMPEGTranscoding) { - //this ensures transcoding is completely disabled even if + //this ensures transcoding is completely disabled even if // some settings are true this.opts.normalizeAudio = false; this.opts.normalizeAudioCodec = false; @@ -17,6 +18,7 @@ class FFMPEG extends events.EventEmitter { this.opts.errorScreen = 'kill'; this.opts.normalizeResolution = false; this.opts.audioVolumePercent = 100; + this.opts.maxFPS = REALLY_RIDICULOUSLY_HIGH_FPS_FOR_DIZQUETVS_USECASE; } this.channel = channel this.ffmpegPath = opts.ffmpegPath @@ -129,6 +131,11 @@ class FFMPEG extends events.EventEmitter { // When adding filters, make sure that // videoComplex always begins wiht ; and doesn't end with ; + if ( streamStats.videoFramerate >= this.opts.maxFPS + 0.000001 ) { + videoComplex += `;${currentVideo}fps=${this.opts.maxFPS}[fpchange]`; + currentVideo ="[fpchange]"; + } + // prepare input streams if ( typeof(streamUrl.errorTitle) !== 'undefined') { doOverlay = false; //never show icon in the error screen @@ -263,7 +270,7 @@ class FFMPEG extends events.EventEmitter { currentVideo = "blackpadded"; } let name = "siz"; - if (! this.ensureResolution) { + if (! this.ensureResolution && (beforeSizeChange != '[fpchange]') ) { name = "minsiz"; } videoComplex += `;[${currentVideo}]setsar=1[${name}]`; diff --git a/web/directives/ffmpeg-settings.js b/web/directives/ffmpeg-settings.js index 23dfdc4..cebdf4f 100644 --- a/web/directives/ffmpeg-settings.js +++ b/web/directives/ffmpeg-settings.js @@ -59,6 +59,17 @@ {value:"sine", description:"Beep"}, {value:"silent", description:"No Audio"}, ] + scope.fpsOptions = [ + {id: 23.976, description: "23.976 frames per second"}, + {id: 24, description: "24 frames per second"}, + {id: 25, description: "25 frames per second"}, + {id: 29.97, description: "29.97 frames per second"}, + {id: 30, description: "30 frames per second"}, + {id: 50, description: "50 frames per second"}, + {id: 59.94, description: "59.94 frames per second"}, + {id: 60, description: "60 frames per second"}, + {id: 120, description: "120 frames per second"}, + ]; } } } \ No newline at end of file diff --git a/web/public/templates/ffmpeg-settings.html b/web/public/templates/ffmpeg-settings.html index 2dec9a5..61d8735 100644 --- a/web/public/templates/ffmpeg-settings.html +++ b/web/public/templates/ffmpeg-settings.html @@ -91,6 +91,10 @@
+ + + Will transcode videos that have FPS higher than this.