Add support for configuring DVR settings.
This commit is contained in:
parent
37b001e481
commit
026a7bbc2c
5 changed files with 198 additions and 10 deletions
|
@ -27,7 +27,7 @@
|
|||
extern char *dvr_storage;
|
||||
extern char *dvr_format;
|
||||
extern char *dvr_file_postfix;
|
||||
|
||||
extern uint32_t dvr_retention_days;
|
||||
|
||||
LIST_HEAD(dvr_rec_stream_list, dvr_rec_stream);
|
||||
|
||||
|
@ -127,6 +127,9 @@ void dvr_entry_cancel(dvr_entry_t *de);
|
|||
|
||||
void dvr_entry_dec_ref(dvr_entry_t *de);
|
||||
|
||||
void dvr_storage_set(const char *storage);
|
||||
|
||||
void dvr_retention_set(int days);
|
||||
|
||||
/**
|
||||
* Query interface
|
||||
|
|
109
dvr/dvr_db.c
109
dvr/dvr_db.c
|
@ -17,6 +17,8 @@
|
|||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -29,15 +31,15 @@
|
|||
char *dvr_storage;
|
||||
char *dvr_format;
|
||||
char *dvr_file_postfix;
|
||||
uint32_t dvr_retention_days;
|
||||
|
||||
|
||||
static int de_tally;
|
||||
|
||||
static int dvr_retention_time = 86400 * 31;
|
||||
|
||||
struct dvr_entry_list dvrentries;
|
||||
|
||||
static void dvr_save(dvr_entry_t *de);
|
||||
static void dvr_entry_save(dvr_entry_t *de);
|
||||
|
||||
static void dvr_timer_expire(void *aux);
|
||||
static void dvr_timer_start_recording(void *aux);
|
||||
|
@ -75,7 +77,7 @@ dvr_entry_link(dvr_entry_t *de)
|
|||
if(now >= de->de_stop || de->de_dont_reschedule) {
|
||||
de->de_sched_state = DVR_COMPLETED;
|
||||
gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de,
|
||||
de->de_stop + dvr_retention_time);
|
||||
de->de_stop + dvr_retention_days * 86400);
|
||||
|
||||
} else {
|
||||
de->de_sched_state = DVR_SCHEDULED;
|
||||
|
@ -125,7 +127,7 @@ dvr_entry_create_by_event(event_t *e, const char *creator)
|
|||
de->de_title, de->de_channel->ch_name, tbuf, creator);
|
||||
|
||||
dvrdb_changed();
|
||||
dvr_save(de);
|
||||
dvr_entry_save(de);
|
||||
}
|
||||
|
||||
|
||||
|
@ -244,7 +246,7 @@ dvr_db_load(void)
|
|||
*
|
||||
*/
|
||||
static void
|
||||
dvr_save(dvr_entry_t *de)
|
||||
dvr_entry_save(dvr_entry_t *de)
|
||||
{
|
||||
htsmsg_t *m = htsmsg_create();
|
||||
|
||||
|
@ -304,10 +306,10 @@ dvr_stop_recording(dvr_entry_t *de, const char *errmsg)
|
|||
de->de_error ?: "Program ended");
|
||||
|
||||
dvrdb_changed();
|
||||
dvr_save(de);
|
||||
dvr_entry_save(de);
|
||||
|
||||
gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de,
|
||||
de->de_stop + dvr_retention_time);
|
||||
de->de_stop + dvr_retention_days * 86400);
|
||||
}
|
||||
|
||||
|
||||
|
@ -387,13 +389,104 @@ dvr_entry_cancel(dvr_entry_t *de)
|
|||
void
|
||||
dvr_init(void)
|
||||
{
|
||||
dvr_storage = strdup("/home/andoma/media/dvr");
|
||||
htsmsg_t *m;
|
||||
char buf[500];
|
||||
const char *homedir;
|
||||
struct stat st;
|
||||
|
||||
/* Default settings */
|
||||
|
||||
dvr_retention_days = 31;
|
||||
dvr_format = strdup("matroska");
|
||||
dvr_file_postfix = strdup("mkv");
|
||||
|
||||
/* Override settings with config */
|
||||
|
||||
if((m = hts_settings_load("dvr")) != NULL) {
|
||||
htsmsg_get_u32(m, "retention-days", &dvr_retention_days);
|
||||
tvh_str_set(&dvr_storage, htsmsg_get_str(m, "storage"));
|
||||
|
||||
htsmsg_destroy(m);
|
||||
}
|
||||
|
||||
if(dvr_storage == NULL) {
|
||||
/* Try to figure out a good place to put them videos */
|
||||
|
||||
homedir = getenv("HOME");
|
||||
|
||||
if(homedir != NULL) {
|
||||
snprintf(buf, sizeof(buf), "%s/Videos", homedir);
|
||||
if(stat(buf, &st) == 0 && S_ISDIR(st.st_mode))
|
||||
dvr_storage = strdup(buf);
|
||||
|
||||
else if(stat(homedir, &st) == 0 && S_ISDIR(st.st_mode))
|
||||
dvr_storage = strdup(homedir);
|
||||
else
|
||||
dvr_storage = strdup(getcwd(buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"\nNotice: Digital Video Recorder\n");
|
||||
fprintf(stderr,
|
||||
" Output directory for video recording is not yet configured.\n");
|
||||
fprintf(stderr,
|
||||
" Defaulting to to \"%s\".\n", dvr_storage);
|
||||
fprintf(stderr,
|
||||
" This can be changed from the web user interface.\n");
|
||||
}
|
||||
|
||||
dvr_db_load();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void
|
||||
dvr_save(void)
|
||||
{
|
||||
htsmsg_t *m = htsmsg_create();
|
||||
htsmsg_add_str(m, "storage", dvr_storage);
|
||||
htsmsg_add_u32(m, "retention-days", dvr_retention_days);
|
||||
|
||||
hts_settings_save(m, "dvr");
|
||||
htsmsg_destroy(m);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvr_storage_set(const char *storage)
|
||||
{
|
||||
if(!strcmp(dvr_storage, storage))
|
||||
return;
|
||||
|
||||
tvh_str_set(&dvr_storage, storage);
|
||||
dvr_save();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
dvr_retention_set(int days)
|
||||
{
|
||||
dvr_entry_t *de;
|
||||
if(days < 1 || dvr_retention_days == days)
|
||||
return;
|
||||
|
||||
dvr_retention_days = days;
|
||||
|
||||
/* Also, rearm all timres */
|
||||
|
||||
LIST_FOREACH(de, &dvrentries, de_global_link)
|
||||
if(de->de_sched_state == DVR_COMPLETED)
|
||||
gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de,
|
||||
de->de_stop + dvr_retention_days * 86400);
|
||||
dvr_save();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -887,11 +887,14 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
|
|||
{
|
||||
htsbuf_queue_t *hq = &hc->hc_reply;
|
||||
const char *op = http_arg_get(&hc->hc_req_args, "op");
|
||||
htsmsg_t *out;
|
||||
htsmsg_t *out, *r;
|
||||
event_t *e;
|
||||
dvr_entry_t *de;
|
||||
const char *s;
|
||||
|
||||
if(op == NULL)
|
||||
op = "loadSettings";
|
||||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
|
||||
if(!strcmp(op, "recordEvent")) {
|
||||
|
@ -918,6 +921,26 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
out = htsmsg_create();
|
||||
htsmsg_add_u32(out, "success", 1);
|
||||
|
||||
} else if(!strcmp(op, "loadSettings")) {
|
||||
|
||||
r = htsmsg_create();
|
||||
htsmsg_add_str(r, "storage", dvr_storage);
|
||||
htsmsg_add_u32(r, "retention", dvr_retention_days);
|
||||
out = json_single_record(r, "dvrSettings");
|
||||
|
||||
} else if(!strcmp(op, "saveSettings")) {
|
||||
|
||||
if((s = http_arg_get(&hc->hc_req_args, "storage")) != NULL)
|
||||
dvr_storage_set(s);
|
||||
|
||||
if((s = http_arg_get(&hc->hc_req_args, "retention")) != NULL)
|
||||
dvr_retention_set(atoi(s));
|
||||
|
||||
|
||||
out = htsmsg_create();
|
||||
htsmsg_add_u32(out, "success", 1);
|
||||
|
||||
} else {
|
||||
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
|
|
|
@ -188,3 +188,71 @@ tvheadend.dvr = function() {
|
|||
return panel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Configuration panel (located under configuration)
|
||||
*/
|
||||
tvheadend.dvrsettings = function() {
|
||||
|
||||
var confreader = new Ext.data.JsonReader({
|
||||
root: 'dvrSettings',
|
||||
}, ['storage','retention']);
|
||||
|
||||
|
||||
var confpanel = new Ext.FormPanel({
|
||||
title:'Digital Video Recorder',
|
||||
border:false,
|
||||
bodyStyle:'padding:15px',
|
||||
anchor: '100% 50%',
|
||||
labelAlign: 'right',
|
||||
labelWidth: 150,
|
||||
waitMsgTarget: true,
|
||||
reader: confreader,
|
||||
defaultType: 'textfield',
|
||||
layout: 'form',
|
||||
items: [{
|
||||
width: 300,
|
||||
fieldLabel: 'Recording system path',
|
||||
name: 'storage'
|
||||
}, new Ext.form.NumberField({
|
||||
allowNegative: false,
|
||||
allowDecimals: false,
|
||||
minValue: 1,
|
||||
fieldLabel: 'Retention time (days)',
|
||||
name: 'retention'
|
||||
})],
|
||||
tbar: [{
|
||||
tooltip: 'Save changes made to channel configuration below',
|
||||
iconCls:'save',
|
||||
text: "Save configuration",
|
||||
handler: saveChanges
|
||||
}],
|
||||
|
||||
});
|
||||
|
||||
confpanel.on('render', function() {
|
||||
confpanel.getForm().load({
|
||||
url:'/dvr',
|
||||
params:{'op':'loadSettings'},
|
||||
success:function(form, action) {
|
||||
confpanel.enable();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function saveChanges() {
|
||||
confpanel.getForm().submit({
|
||||
url:'/dvr',
|
||||
params:{'op':'saveSettings'},
|
||||
waitMsg:'Saving Data...',
|
||||
failure: function(form, action) {
|
||||
Ext.Msg.alert('Save failed', action.result.errormsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return confpanel;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ tvheadend.app = function() {
|
|||
title: 'Configuration',
|
||||
items: [new tvheadend.chconf,
|
||||
new tvheadend.cteditor,
|
||||
new tvheadend.dvrsettings,
|
||||
new tvheadend.dvb,
|
||||
new tvheadend.acleditor,
|
||||
new tvheadend.cwceditor]
|
||||
|
|
Loading…
Add table
Reference in a new issue