FFMpeg path is now set by environment var or file..
This commit is contained in:
parent
7daad9e33f
commit
caf3b3b72c
@ -10,5 +10,6 @@ FROM akashisn/ffmpeg:4.4.5
|
||||
EXPOSE 8000
|
||||
WORKDIR /home/node/app
|
||||
ENTRYPOINT [ "./dizquetv" ]
|
||||
ENV DIZQUETV_FFMPEG_PATH=/usr/bin/ffmpeg
|
||||
COPY --from=0 /home/node/app/dist/dizquetv /home/node/app/
|
||||
RUN ln -s /usr/local/bin/ffmpeg /usr/bin/ffmpeg
|
||||
|
||||
@ -10,5 +10,6 @@ FROM jrottenberg/ffmpeg:4.4.5-nvidia2204
|
||||
EXPOSE 8000
|
||||
WORKDIR /home/node/app
|
||||
ENTRYPOINT [ "./dizquetv" ]
|
||||
ENV DIZQUETV_FFMPEG_PATH=/usr/bin/ffmpeg
|
||||
COPY --from=0 /home/node/app/dist/dizquetv /home/node/app/
|
||||
RUN ln -s /usr/local/bin/ffmpeg /usr/bin/ffmpeg
|
||||
|
||||
13
index.js
13
index.js
@ -34,6 +34,7 @@ const ProgramPlayTimeDB = require('./src/dao/program-play-time-db')
|
||||
const FfmpegSettingsService = require('./src/services/ffmpeg-settings-service')
|
||||
const PlexProxyService = require('./src/services/plex-proxy-service')
|
||||
const PlexServerDB = require('./src/dao/plex-server-db');
|
||||
const FFMPEGInfo = require('./src/ffmpeg-info');
|
||||
|
||||
const onShutdown = require("node-graceful-shutdown").onShutdown;
|
||||
|
||||
@ -53,16 +54,12 @@ if (NODE < 12) {
|
||||
console.error(`WARNING: Your nodejs version ${process.version} is lower than supported. dizqueTV has been tested best on nodejs 12.16.`);
|
||||
}
|
||||
|
||||
unlockPath = false;
|
||||
for (let i = 0, l = process.argv.length; i < l; i++) {
|
||||
if ((process.argv[i] === "-p" || process.argv[i] === "--port") && i + 1 !== l)
|
||||
process.env.PORT = process.argv[i + 1]
|
||||
if ((process.argv[i] === "-d" || process.argv[i] === "--database") && i + 1 !== l)
|
||||
process.env.DATABASE = process.argv[i + 1]
|
||||
|
||||
if (process.argv[i] === "--unlock") {
|
||||
unlockPath = true;
|
||||
}
|
||||
}
|
||||
|
||||
process.env.DATABASE = process.env.DATABASE || path.join(".", ".dizquetv")
|
||||
@ -94,6 +91,8 @@ if(!fs.existsSync(path.join(process.env.DATABASE, 'cache','images'))) {
|
||||
fs.mkdirSync(path.join(process.env.DATABASE, 'cache','images'))
|
||||
}
|
||||
|
||||
const ffmpegInfo = new FFMPEGInfo(process.env, process.env.DATABASE);
|
||||
ffmpegInfo.initialize();
|
||||
|
||||
channelDB = new ChannelDB( path.join(process.env.DATABASE, 'channels') );
|
||||
|
||||
@ -108,7 +107,7 @@ channelService = new ChannelService(channelDB);
|
||||
fillerDB = new FillerDB( path.join(process.env.DATABASE, 'filler') , channelService );
|
||||
customShowDB = new CustomShowDB( path.join(process.env.DATABASE, 'custom-shows') );
|
||||
let programPlayTimeDB = new ProgramPlayTimeDB( path.join(process.env.DATABASE, 'play-cache') );
|
||||
let ffmpegSettingsService = new FfmpegSettingsService(db, unlockPath);
|
||||
let ffmpegSettingsService = new FfmpegSettingsService(db);
|
||||
let plexServerDB = new PlexServerDB(channelService, fillerDB, customShowDB, db);
|
||||
let plexProxyService = new PlexProxyService(plexServerDB);
|
||||
|
||||
@ -324,12 +323,12 @@ app.use('/favicon.svg', express.static(
|
||||
app.use('/custom.css', express.static(path.join(process.env.DATABASE, 'custom.css')))
|
||||
|
||||
// API Routers
|
||||
app.use(api.router(db, channelService, fillerDB, customShowDB, xmltvInterval, guideService, m3uService, eventService, ffmpegSettingsService, plexServerDB, plexProxyService))
|
||||
app.use(api.router(db, channelService, fillerDB, customShowDB, xmltvInterval, guideService, m3uService, eventService, ffmpegSettingsService, plexServerDB, plexProxyService, ffmpegInfo))
|
||||
app.use('/api/cache/images', cacheImageService.apiRouters())
|
||||
app.use('/' + fontAwesome, express.static(path.join(process.env.DATABASE, fontAwesome)))
|
||||
app.use('/' + bootstrap, express.static(path.join(process.env.DATABASE, bootstrap)))
|
||||
|
||||
app.use(video.router( channelService, fillerDB, db, programmingService, activeChannelService, programPlayTimeDB ))
|
||||
app.use(video.router( channelService, fillerDB, db, programmingService, activeChannelService, programPlayTimeDB, ffmpegInfo ))
|
||||
app.use(hdhr.router)
|
||||
app.listen(process.env.PORT, () => {
|
||||
console.log(`HTTP server running on port: http://*:${process.env.PORT}`)
|
||||
|
||||
19
src/api.js
19
src/api.js
@ -4,8 +4,6 @@ const path = require('path')
|
||||
const fs = require('fs')
|
||||
const constants = require('./constants');
|
||||
const JSONStream = require('JSONStream');
|
||||
const FFMPEGInfo = require('./ffmpeg-info');
|
||||
const PlexServerDB = require('./dao/plex-server-db');
|
||||
const Plex = require("./plex.js");
|
||||
|
||||
const timeSlotsService = require('./services/time-slots-service');
|
||||
@ -24,14 +22,13 @@ function safeString(object) {
|
||||
}
|
||||
|
||||
module.exports = { router: api }
|
||||
function api(db, channelService, fillerDB, customShowDB, xmltvInterval, guideService, _m3uService, eventService, ffmpegSettingsService, plexServerDB, plexProxyService ) {
|
||||
function api(db, channelService, fillerDB, customShowDB, xmltvInterval, guideService, _m3uService, eventService, ffmpegSettingsService, plexServerDB, plexProxyService, ffmpegInfo ) {
|
||||
let m3uService = _m3uService;
|
||||
const router = express.Router()
|
||||
|
||||
router.get('/api/version', async (req, res) => {
|
||||
try {
|
||||
let ffmpegSettings = db['ffmpeg-settings'].find()[0];
|
||||
let v = await (new FFMPEGInfo(ffmpegSettings)).getVersion();
|
||||
let v = await ffmpegInfo.getVersion();
|
||||
res.send( {
|
||||
"dizquetv" : constants.VERSION_NAME,
|
||||
"ffmpeg" : v,
|
||||
@ -616,6 +613,18 @@ function api(db, channelService, fillerDB, customShowDB, xmltvInterval, guideSe
|
||||
|
||||
})
|
||||
|
||||
router.get('/api/ffmpeg-info', async (req, res) => {
|
||||
try {
|
||||
let ffmpeg = await ffmpegInfo.getPath();
|
||||
let obj = { ffmpegPath: ffmpeg }
|
||||
res.send(obj)
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// PLEX SETTINGS
|
||||
router.get('/api/plex-settings', (req, res) => {
|
||||
try {
|
||||
|
||||
@ -20,8 +20,7 @@
|
||||
const path = require('path');
|
||||
var fs = require('fs');
|
||||
|
||||
const TARGET_VERSION = 805;
|
||||
const DAY_MS = 1000 * 60 * 60 * 24;
|
||||
const TARGET_VERSION = 900;
|
||||
|
||||
const STEPS = [
|
||||
// [v, v2, x] : if the current version is v, call x(db), and version becomes v2
|
||||
@ -44,8 +43,9 @@ const STEPS = [
|
||||
[ 800, 801, (db) => addImageCache(db) ],
|
||||
[ 801, 802, () => addGroupTitle() ],
|
||||
[ 802, 803, () => fixNonIntegerDurations() ],
|
||||
[ 803, 805, (db) => addFFMpegLock(db) ],
|
||||
[ 804, 805, (db) => addFFMpegLock(db) ],
|
||||
[ 803, 900, (db) => fixFFMpegPathSetting(db) ],
|
||||
[ 804, 900, (db) => fixFFMpegPathSetting(db) ],
|
||||
[ 805, 900, (db) => fixFFMpegPathSetting(db) ],
|
||||
]
|
||||
|
||||
const { v4: uuidv4 } = require('uuid');
|
||||
@ -75,7 +75,7 @@ function appNameChange(db) {
|
||||
|
||||
function basicDB(db) {
|
||||
//this one should either try recovering the db from a very old version
|
||||
//or buildl a completely empty db at version 0
|
||||
//or build a completely empty db at version 0
|
||||
let ffmpegSettings = db['ffmpeg-settings'].find()
|
||||
let plexSettings = db['plex-settings'].find()
|
||||
|
||||
@ -386,8 +386,6 @@ function ffmpeg() {
|
||||
return {
|
||||
//How default ffmpeg settings should look
|
||||
configVersion: 5,
|
||||
ffmpegPath: "/usr/bin/ffmpeg",
|
||||
ffmpegPathLockDate: new Date().getTime() + DAY_MS,
|
||||
threads: 4,
|
||||
concatMuxDelay: "0",
|
||||
logFfmpeg: false,
|
||||
@ -769,19 +767,23 @@ function addScalingAlgorithm(db) {
|
||||
fs.writeFileSync( f, JSON.stringify( [ffmpegSettings] ) );
|
||||
}
|
||||
|
||||
function addFFMpegLock(db) {
|
||||
function fixFFMpegPathSetting(db) {
|
||||
let ffmpegSettings = db['ffmpeg-settings'].find()[0];
|
||||
let f = path.join(process.env.DATABASE, 'ffmpeg-settings.json');
|
||||
if ( typeof(ffmpegSettings.ffmpegPathLockDate) === 'undefined' || ffmpegSettings.ffmpegPathLockDate == null ) {
|
||||
let f2 = path.join(process.env.DATABASE, 'ffmpeg-path.json');
|
||||
delete ffmpegSettings.ffmpegPathLockDate;
|
||||
let fpath = ffmpegSettings.ffmpegPath;
|
||||
delete ffmpegSettings.ffmpegPath;
|
||||
|
||||
console.log("Adding ffmpeg lock. For your security it will not be possible to modify the ffmpeg path using the UI anymore unless you launch dizquetv by following special instructions..");
|
||||
// We are migrating an existing db that had a ffmpeg path. Make sure
|
||||
// it's already locked.
|
||||
ffmpegSettings.ffmpegPathLockDate = new Date().getTime() - 2 * DAY_MS;
|
||||
if (typeof(fpath) === "string" ) {
|
||||
console.log(`Found existing setting ffmpegPath=${fpath}, creating setting file (This file will get ignored if you are already setting an environment variable (the docker images do that)).`);
|
||||
let pathJson = { ffmpegPath : fpath };
|
||||
fs.writeFileSync( f2, JSON.stringify( pathJson ) );
|
||||
}
|
||||
fs.writeFileSync( f, JSON.stringify( [ffmpegSettings] ) );
|
||||
}
|
||||
|
||||
|
||||
function moveBackup(path) {
|
||||
if (fs.existsSync(`${process.env.DATABASE}${path}`) ) {
|
||||
let i = 0;
|
||||
|
||||
@ -1,13 +1,98 @@
|
||||
const exec = require('child_process').exec;
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
class FFMPEGInfo {
|
||||
constructor(opts) {
|
||||
this.ffmpegPath = opts.ffmpegPath
|
||||
|
||||
constructor(env, dbPath) {
|
||||
this.initialized = false;
|
||||
this.env = env;
|
||||
this.dbPath = dbPath;
|
||||
this.ffmpegPath = null;
|
||||
this.origin = "Not found";
|
||||
}
|
||||
async getVersion() {
|
||||
|
||||
async initialize() {
|
||||
let selectedPath = null;
|
||||
if (typeof(this.env.DIZQUETV_FFMPEG_PATH) === "string") {
|
||||
selectedPath = this.env.DIZQUETV_FFMPEG_PATH;
|
||||
this.origin = "env.DIZQUETV_FFMPEG_PATH";
|
||||
} else {
|
||||
selectedPath = await this.getPathFromFile(this.dbPath, 'ffmpeg-path.json');
|
||||
this.origin = "ffmpeg-path.json";
|
||||
}
|
||||
if (selectedPath == null) {
|
||||
//windows Path environment var
|
||||
let paths = this.env.Path;
|
||||
if (typeof(paths) === "string") {
|
||||
let maybe = paths.split(";").filter(
|
||||
(str) => str.contains("ffmpeg" )
|
||||
)[0];
|
||||
if (typeof(maybe) === "string") {
|
||||
selectedPath = path.join(maybe, "ffmpeg.exe");
|
||||
this.origin = "Widnows Env. Path";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selectedPath == null) {
|
||||
//Default install path for ffmpeg in n*x OSes.
|
||||
// if someone has built ffmpeg manually or wants an alternate
|
||||
// path, they are most likely capable of configuring it manually.
|
||||
selectedPath = "/usr/bin/ffmpeg";
|
||||
this.origin = "Default";
|
||||
}
|
||||
|
||||
if (selectedPath != null) {
|
||||
let version = await this.checkVersion(selectedPath);
|
||||
if (version == null) {
|
||||
selectedPath = null;
|
||||
} else {
|
||||
console.log(`FFmpeg found: ${selectedPath} from: ${this.origin}. version: ${version}`);
|
||||
this.ffmpegPath = selectedPath;
|
||||
}
|
||||
}
|
||||
this.initialized = true;
|
||||
|
||||
}
|
||||
|
||||
async getPath() {
|
||||
if (! this.initialized) {
|
||||
await this.initialize();
|
||||
}
|
||||
return this.ffmpegPath;
|
||||
}
|
||||
|
||||
async getPathFromFile(folder, fileName) {
|
||||
let f = path.join(folder, fileName);
|
||||
try {
|
||||
let json = await new Promise( (resolve, reject) => {
|
||||
fs.readFile(f, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
try {
|
||||
resolve( JSON.parse(data) )
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
})
|
||||
});
|
||||
let ffmpeg = json["ffmpegPath"];
|
||||
if (typeof(ffmpeg) === "string") {
|
||||
return ffmpeg;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async checkVersion(ffmpegPath) {
|
||||
try {
|
||||
let s = await new Promise( (resolve, reject) => {
|
||||
exec( `"${this.ffmpegPath}" -version`, function(error, stdout, stderr){
|
||||
exec( `"${ffmpegPath}" -version`, function(error, stdout, stderr){
|
||||
if (error !== null) {
|
||||
reject(error);
|
||||
} else {
|
||||
@ -23,7 +108,20 @@ class FFMPEGInfo {
|
||||
return m[1];
|
||||
} catch (err) {
|
||||
console.error("Error getting ffmpeg version", err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async getVersion() {
|
||||
if (! this.initialized) {
|
||||
await this.initialize();
|
||||
}
|
||||
let version = await this.checkVersion(this.ffmpegPath);
|
||||
if (version == null) {
|
||||
return "Error";
|
||||
} else {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ const REALLY_RIDICULOUSLY_HIGH_FPS_FOR_DIZQUETVS_USECASE = 120;
|
||||
class FFMPEG extends events.EventEmitter {
|
||||
constructor(opts, channel) {
|
||||
super()
|
||||
this.ffmpegPath = opts.ffmpegPath;
|
||||
this.opts = opts;
|
||||
this.errorPicturePath = `http://localhost:${process.env.PORT}/images/generic-error-screen.png`;
|
||||
this.ffmpegName = "unnamed ffmpeg";
|
||||
@ -22,7 +23,6 @@ class FFMPEG extends events.EventEmitter {
|
||||
this.opts.maxFPS = REALLY_RIDICULOUSLY_HIGH_FPS_FOR_DIZQUETVS_USECASE;
|
||||
}
|
||||
this.channel = channel
|
||||
this.ffmpegPath = opts.ffmpegPath
|
||||
|
||||
let resString = opts.targetResolution;
|
||||
if (
|
||||
@ -601,7 +601,7 @@ class FFMPEG extends events.EventEmitter {
|
||||
return;
|
||||
}
|
||||
if (! this.sentData) {
|
||||
this.emit('error', { code: code, cmd: `${this.opts.ffmpegPath} ${ffmpegArgs.join(' ')}` })
|
||||
this.emit('error', { code: code, cmd: `${this.ffmpegPath} ${ffmpegArgs.join(' ')}` })
|
||||
}
|
||||
console.log( `${this.ffmpegName} exited with code 255.` );
|
||||
this.emit('close', code)
|
||||
|
||||
@ -4,11 +4,8 @@ const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
class FfmpegSettingsService {
|
||||
constructor(db, unlock) {
|
||||
constructor(db) {
|
||||
this.db = db;
|
||||
if (unlock) {
|
||||
this.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
get() {
|
||||
@ -21,13 +18,6 @@ class FfmpegSettingsService {
|
||||
return ffmpeg;
|
||||
}
|
||||
|
||||
unlock() {
|
||||
let ffmpeg = this.getCurrentState();
|
||||
console.log("ffmpeg path UI unlocked for another day...");
|
||||
ffmpeg.ffmpegPathLockDate = new Date().getTime() + DAY_MS;
|
||||
this.db['ffmpeg-settings'].update({ _id: ffmpeg._id }, ffmpeg)
|
||||
}
|
||||
|
||||
|
||||
update(attempt) {
|
||||
let ffmpeg = this.getCurrentState();
|
||||
@ -62,7 +52,6 @@ class FfmpegSettingsService {
|
||||
}
|
||||
|
||||
reset() {
|
||||
// Even if reseting, it's impossible to unlock the ffmpeg path
|
||||
let ffmpeg = databaseMigration.defaultFFMPEG() ;
|
||||
this.update(ffmpeg);
|
||||
return this.get();
|
||||
|
||||
31
src/video.js
31
src/video.js
@ -18,17 +18,18 @@ async function shutdown() {
|
||||
stopPlayback = true;
|
||||
}
|
||||
|
||||
function video( channelService, fillerDB, db, programmingService, activeChannelService, programPlayTimeDB ) {
|
||||
function video( channelService, fillerDB, db, programmingService, activeChannelService, programPlayTimeDB, ffmpegInfo ) {
|
||||
var router = express.Router()
|
||||
|
||||
router.get('/setup', (req, res) => {
|
||||
router.get('/setup', async (req, res) => {
|
||||
let ffmpegSettings = db['ffmpeg-settings'].find()[0]
|
||||
// Check if ffmpeg path is valid
|
||||
if (!fs.existsSync(ffmpegSettings.ffmpegPath)) {
|
||||
res.status(500).send("FFMPEG path is invalid. The file (executable) doesn't exist.")
|
||||
console.error("The FFMPEG Path is invalid. Please check your configuration.")
|
||||
let ffmpegPath = await ffmpegInfo.getPath();
|
||||
if (ffmpegPath == null) {
|
||||
res.status(500).send("Missing FFmpeg.")
|
||||
return
|
||||
}
|
||||
ffmpegSettings.ffmpegPath = ffmpegPath;
|
||||
|
||||
console.log(`\r\nStream starting. Channel: 1 (dizqueTV)`)
|
||||
|
||||
@ -72,14 +73,14 @@ function video( channelService, fillerDB, db, programmingService, activeChannelS
|
||||
return
|
||||
}
|
||||
|
||||
let ffmpegSettings = db['ffmpeg-settings'].find()[0]
|
||||
|
||||
// Check if ffmpeg path is valid
|
||||
if (!fs.existsSync(ffmpegSettings.ffmpegPath)) {
|
||||
res.status(500).send("FFMPEG path is invalid. The file (executable) doesn't exist.")
|
||||
console.error("The FFMPEG Path is invalid. Please check your configuration.")
|
||||
let ffmpegSettings = db['ffmpeg-settings'].find()[0]
|
||||
let ffmpegPath = await ffmpegInfo.getPath();
|
||||
if (ffmpegPath == null) {
|
||||
res.status(500).send("Missing FFmpeg.")
|
||||
return
|
||||
}
|
||||
ffmpegSettings.ffmpegPath = ffmpegPath;
|
||||
|
||||
if (step == 0) {
|
||||
res.writeHead(200, {
|
||||
@ -174,14 +175,14 @@ function video( channelService, fillerDB, db, programmingService, activeChannelS
|
||||
|
||||
let isBetween = ( (typeof req.query.between !== 'undefined') && (req.query.between=='1') );
|
||||
|
||||
let ffmpegSettings = db['ffmpeg-settings'].find()[0]
|
||||
|
||||
// Check if ffmpeg path is valid
|
||||
if (!fs.existsSync(ffmpegSettings.ffmpegPath)) {
|
||||
res.status(500).send("FFMPEG path is invalid. The file (executable) doesn't exist.")
|
||||
console.error("The FFMPEG Path is invalid. Please check your configuration.")
|
||||
let ffmpegSettings = db['ffmpeg-settings'].find()[0]
|
||||
let ffmpegPath = await ffmpegInfo.getPath();
|
||||
if (ffmpegPath == null) {
|
||||
res.status(500).send("Missing FFmpeg.")
|
||||
return
|
||||
}
|
||||
ffmpegSettings.ffmpegPath = ffmpegPath;
|
||||
|
||||
if (ffmpegSettings.disablePreludes === true) {
|
||||
//disable the preludes
|
||||
|
||||
@ -6,7 +6,14 @@ module.exports = function (dizquetv, resolutionOptions) {
|
||||
scope: {
|
||||
},
|
||||
link: function (scope, element, attrs) {
|
||||
//add validations to ffmpeg settings, speciall commas in codec name
|
||||
|
||||
scope.ffmpegPathLoading = true;
|
||||
scope.ffmpegPath = ""
|
||||
dizquetv.getFFMpegPath().then( (fpath) => {
|
||||
scope.ffmpegPath = fpath.ffmpegPath;
|
||||
scope.ffmpegPathLoading = false;
|
||||
});
|
||||
//add validations to ffmpeg settings, special commas in codec name
|
||||
dizquetv.getFfmpegSettings().then((settings) => {
|
||||
scope.settings = settings
|
||||
})
|
||||
|
||||
@ -15,40 +15,20 @@
|
||||
|
||||
<hr></hr>
|
||||
<h6>FFMPEG Executable Path</h6>
|
||||
<div class="row" ng-show="settings.lock !== true">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
<div class="form-group">
|
||||
<div class="form-group">
|
||||
<label>Path</label>
|
||||
<input id="ffmpegPath" ria-describedby="ffmpegHelp" type="text" class="form-control form-control-sm" ng-model="settings.ffmpegPath"></input>
|
||||
<small class="form-text text-muted">
|
||||
The path to the ffmpeg executable. (e.g: /usr/bin/ffmpeg or C:\ffmpeg\bin\ffmpeg.exe) FFMPEG version 4.2+ required. Check by opening the version tab.
|
||||
|
||||
<div class='loader' ng-show='ffmpegPathLoading'></div>
|
||||
<input id="ffmpegPath" ria-describedby="ffmpegHelp" type="text" class="form-control form-control-sm" ng-model="ffmpegPath" readonly ng-hide="ffmpegPathLoading"></input>
|
||||
<small class="form-text text-muted" ng-show="ffmpegPath != null">
|
||||
The path to the ffmpeg executable. Please check the instructions if you need to change it.
|
||||
</small>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div class="form-group">
|
||||
<input id="lockFfmpeg" type="checkbox" ng-model="settings.addLock"></input>
|
||||
<label for="lockFfmpeg">Lock ffmpeg path setting</label>
|
||||
<small class="form-text text-muted">This will lock the ffmpeg path setting so that it is no longer editable from UI. Even if you don't toggle this option, the setting will get locked in 24 hours.</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row" ng-show="settings.lock === true">
|
||||
<div class="col-sm-9">
|
||||
<div class="form-group">
|
||||
<div class="form-group">
|
||||
<label>Path</label>
|
||||
<input id="ffmpegPath" ria-describedby="ffmpegHelp" type="text" class="form-control form-control-sm" ng-model="settings.ffmpegPath" readonly></input>
|
||||
<small class="form-text text-muted">
|
||||
The ffmpeg path setting is currently locked and can't be edited from the UI. It's not usually necessary to update this path once it's known to be working. Run dizquetv with the <b>--unlock</b> command line argument to enable editing it again.
|
||||
<small class="form-text text-muted" ng-show="ffmpegPath == null">
|
||||
dizqueTV uses FFmpeg to create video streams. Please check the instructions for info about how to set this up.
|
||||
</small>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user