Add support for setting default extra times to add before and after a recording. Useful if your TV shows never start on time.
This commit is contained in:
parent
72ff81e25c
commit
5dfdbc7a9b
6 changed files with 95 additions and 11 deletions
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -8,7 +8,11 @@ hts-tvheadend (2.5) hts; urgency=low
|
||||||
|
|
||||||
* The HTSP service is now announced via AVAHI (mDNS service discovery)
|
* The HTSP service is now announced via AVAHI (mDNS service discovery)
|
||||||
|
|
||||||
* Support for IPTV has been added.
|
* Support for IPTV has been added. Only RAW TS in UDP is supported
|
||||||
|
at the moment.
|
||||||
|
|
||||||
|
* Add support for setting default extra times to add before and after
|
||||||
|
a recording. Useful if your TV shows never start on time.
|
||||||
|
|
||||||
hts-tvheadend (2.4) hts; urgency=low
|
hts-tvheadend (2.4) hts; urgency=low
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ extern char *dvr_file_postfix;
|
||||||
extern uint32_t dvr_retention_days;
|
extern uint32_t dvr_retention_days;
|
||||||
extern int dvr_flags;
|
extern int dvr_flags;
|
||||||
extern char *dvr_postproc;
|
extern char *dvr_postproc;
|
||||||
|
extern int dvr_extra_time_pre;
|
||||||
|
extern int dvr_extra_time_post;
|
||||||
|
|
||||||
#define DVR_DIR_PER_DAY 0x1
|
#define DVR_DIR_PER_DAY 0x1
|
||||||
#define DVR_DIR_PER_CHANNEL 0x2
|
#define DVR_DIR_PER_CHANNEL 0x2
|
||||||
|
@ -75,6 +77,9 @@ typedef struct dvr_entry {
|
||||||
time_t de_start;
|
time_t de_start;
|
||||||
time_t de_stop;
|
time_t de_stop;
|
||||||
|
|
||||||
|
time_t de_start_extra;
|
||||||
|
time_t de_stop_extra;
|
||||||
|
|
||||||
char *de_creator;
|
char *de_creator;
|
||||||
char *de_filename; /* Initially null if no filename has been
|
char *de_filename; /* Initially null if no filename has been
|
||||||
generated yet */
|
generated yet */
|
||||||
|
@ -155,6 +160,10 @@ void dvr_retention_set(int days);
|
||||||
|
|
||||||
void dvr_flags_set(int flags);
|
void dvr_flags_set(int flags);
|
||||||
|
|
||||||
|
void dvr_extra_time_pre_set(int d);
|
||||||
|
|
||||||
|
void dvr_extra_time_post_set(int d);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query interface
|
* Query interface
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -33,6 +33,8 @@ char *dvr_format;
|
||||||
char *dvr_file_postfix;
|
char *dvr_file_postfix;
|
||||||
uint32_t dvr_retention_days;
|
uint32_t dvr_retention_days;
|
||||||
int dvr_flags;
|
int dvr_flags;
|
||||||
|
int dvr_extra_time_pre;
|
||||||
|
int dvr_extra_time_post;
|
||||||
char *dvr_postproc;
|
char *dvr_postproc;
|
||||||
|
|
||||||
static int de_tally;
|
static int de_tally;
|
||||||
|
@ -112,7 +114,7 @@ dvr_entry_link(dvr_entry_t *de)
|
||||||
|
|
||||||
time(&now);
|
time(&now);
|
||||||
|
|
||||||
preamble = de->de_start - 30;
|
preamble = de->de_start - (60 * de->de_start_extra) - 30;
|
||||||
|
|
||||||
if(now >= de->de_stop || de->de_dont_reschedule) {
|
if(now >= de->de_stop || de->de_dont_reschedule) {
|
||||||
de->de_sched_state = DVR_COMPLETED;
|
de->de_sched_state = DVR_COMPLETED;
|
||||||
|
@ -137,6 +139,7 @@ dvr_entry_create_by_event(event_t *e, const char *creator)
|
||||||
dvr_entry_t *de;
|
dvr_entry_t *de;
|
||||||
char tbuf[30];
|
char tbuf[30];
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
time_t t;
|
||||||
|
|
||||||
if(e->e_channel == NULL || e->e_title == NULL)
|
if(e->e_channel == NULL || e->e_title == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -153,14 +156,16 @@ dvr_entry_create_by_event(event_t *e, const char *creator)
|
||||||
|
|
||||||
de->de_start = e->e_start;
|
de->de_start = e->e_start;
|
||||||
de->de_stop = e->e_stop;
|
de->de_stop = e->e_stop;
|
||||||
|
de->de_start_extra = dvr_extra_time_pre;
|
||||||
|
de->de_stop_extra = dvr_extra_time_post;
|
||||||
de->de_creator = strdup(creator);
|
de->de_creator = strdup(creator);
|
||||||
de->de_title = strdup(e->e_title);
|
de->de_title = strdup(e->e_title);
|
||||||
de->de_desc = e->e_desc ? strdup(e->e_desc) : NULL;
|
de->de_desc = e->e_desc ? strdup(e->e_desc) : NULL;
|
||||||
|
|
||||||
dvr_entry_link(de);
|
dvr_entry_link(de);
|
||||||
|
|
||||||
localtime_r(&de->de_start, &tm);
|
t = de->de_start - de->de_start_extra;
|
||||||
|
localtime_r(&t, &tm);
|
||||||
strftime(tbuf, sizeof(tbuf), "%c", &tm);
|
strftime(tbuf, sizeof(tbuf), "%c", &tm);
|
||||||
|
|
||||||
tvhlog(LOG_INFO, "dvr", "\"%s\" on \"%s\" starting at %s, "
|
tvhlog(LOG_INFO, "dvr", "\"%s\" on \"%s\" starting at %s, "
|
||||||
|
@ -226,6 +231,7 @@ dvr_db_load_one(htsmsg_t *c, int id)
|
||||||
const char *s, *title, *creator;
|
const char *s, *title, *creator;
|
||||||
channel_t *ch;
|
channel_t *ch;
|
||||||
uint32_t start, stop;
|
uint32_t start, stop;
|
||||||
|
int d;
|
||||||
|
|
||||||
if(htsmsg_get_u32(c, "start", &start))
|
if(htsmsg_get_u32(c, "start", &start))
|
||||||
return;
|
return;
|
||||||
|
@ -256,6 +262,18 @@ dvr_db_load_one(htsmsg_t *c, int id)
|
||||||
de->de_creator = strdup(creator);
|
de->de_creator = strdup(creator);
|
||||||
de->de_title = strdup(title);
|
de->de_title = strdup(title);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(htsmsg_get_s32(c, "start_extra", &d))
|
||||||
|
de->de_start_extra = dvr_extra_time_pre;
|
||||||
|
else
|
||||||
|
de->de_start_extra = d;
|
||||||
|
|
||||||
|
if(htsmsg_get_s32(c, "stop_extra", &d))
|
||||||
|
de->de_stop_extra = dvr_extra_time_post;
|
||||||
|
else
|
||||||
|
de->de_stop_extra = d;
|
||||||
|
|
||||||
tvh_str_set(&de->de_desc, htsmsg_get_str(c, "description"));
|
tvh_str_set(&de->de_desc, htsmsg_get_str(c, "description"));
|
||||||
tvh_str_set(&de->de_filename, htsmsg_get_str(c, "filename"));
|
tvh_str_set(&de->de_filename, htsmsg_get_str(c, "filename"));
|
||||||
tvh_str_set(&de->de_error, htsmsg_get_str(c, "error"));
|
tvh_str_set(&de->de_error, htsmsg_get_str(c, "error"));
|
||||||
|
@ -299,6 +317,9 @@ dvr_entry_save(dvr_entry_t *de)
|
||||||
htsmsg_add_str(m, "channel", de->de_channel->ch_name);
|
htsmsg_add_str(m, "channel", de->de_channel->ch_name);
|
||||||
htsmsg_add_u32(m, "start", de->de_start);
|
htsmsg_add_u32(m, "start", de->de_start);
|
||||||
htsmsg_add_u32(m, "stop", de->de_stop);
|
htsmsg_add_u32(m, "stop", de->de_stop);
|
||||||
|
|
||||||
|
htsmsg_add_s32(m, "start_extra", de->de_start_extra);
|
||||||
|
htsmsg_add_s32(m, "stop_extra", de->de_stop_extra);
|
||||||
|
|
||||||
htsmsg_add_str(m, "creator", de->de_creator);
|
htsmsg_add_str(m, "creator", de->de_creator);
|
||||||
|
|
||||||
|
@ -387,7 +408,8 @@ dvr_timer_start_recording(void *aux)
|
||||||
|
|
||||||
dvr_rec_subscribe(de);
|
dvr_rec_subscribe(de);
|
||||||
|
|
||||||
gtimer_arm_abs(&de->de_timer, dvr_timer_stop_recording, de, de->de_stop);
|
gtimer_arm_abs(&de->de_timer, dvr_timer_stop_recording, de,
|
||||||
|
de->de_stop + (60 * de->de_stop_extra));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -491,6 +513,9 @@ dvr_init(void)
|
||||||
/* Override settings with config */
|
/* Override settings with config */
|
||||||
|
|
||||||
if((m = hts_settings_load("dvr/config")) != NULL) {
|
if((m = hts_settings_load("dvr/config")) != NULL) {
|
||||||
|
|
||||||
|
htsmsg_get_s32(m, "pre-extra-time", &dvr_extra_time_pre);
|
||||||
|
htsmsg_get_s32(m, "post-extra-time", &dvr_extra_time_post);
|
||||||
htsmsg_get_u32(m, "retention-days", &dvr_retention_days);
|
htsmsg_get_u32(m, "retention-days", &dvr_retention_days);
|
||||||
tvh_str_set(&dvr_storage, htsmsg_get_str(m, "storage"));
|
tvh_str_set(&dvr_storage, htsmsg_get_str(m, "storage"));
|
||||||
|
|
||||||
|
@ -552,6 +577,8 @@ dvr_save(void)
|
||||||
htsmsg_t *m = htsmsg_create_map();
|
htsmsg_t *m = htsmsg_create_map();
|
||||||
htsmsg_add_str(m, "storage", dvr_storage);
|
htsmsg_add_str(m, "storage", dvr_storage);
|
||||||
htsmsg_add_u32(m, "retention-days", dvr_retention_days);
|
htsmsg_add_u32(m, "retention-days", dvr_retention_days);
|
||||||
|
htsmsg_add_u32(m, "pre-extra-time", dvr_extra_time_pre);
|
||||||
|
htsmsg_add_u32(m, "post-extra-time", dvr_extra_time_post);
|
||||||
htsmsg_add_u32(m, "day-dir", !!(dvr_flags & DVR_DIR_PER_DAY));
|
htsmsg_add_u32(m, "day-dir", !!(dvr_flags & DVR_DIR_PER_DAY));
|
||||||
htsmsg_add_u32(m, "channel-dir", !!(dvr_flags & DVR_DIR_PER_CHANNEL));
|
htsmsg_add_u32(m, "channel-dir", !!(dvr_flags & DVR_DIR_PER_CHANNEL));
|
||||||
htsmsg_add_u32(m, "channel-in-title", !!(dvr_flags & DVR_CHANNEL_IN_TITLE));
|
htsmsg_add_u32(m, "channel-in-title", !!(dvr_flags & DVR_CHANNEL_IN_TITLE));
|
||||||
|
@ -627,6 +654,32 @@ dvr_flags_set(int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dvr_extra_time_pre_set(int d)
|
||||||
|
{
|
||||||
|
if(dvr_extra_time_pre == d)
|
||||||
|
return;
|
||||||
|
dvr_extra_time_pre = d;
|
||||||
|
dvr_save();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dvr_extra_time_post_set(int d)
|
||||||
|
{
|
||||||
|
if(dvr_extra_time_post == d)
|
||||||
|
return;
|
||||||
|
dvr_extra_time_post = d;
|
||||||
|
dvr_save();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -418,7 +418,7 @@ dvr_thread(void *aux)
|
||||||
|
|
||||||
switch(sm->sm_type) {
|
switch(sm->sm_type) {
|
||||||
case SMT_PACKET:
|
case SMT_PACKET:
|
||||||
if(dispatch_clock > de->de_start)
|
if(dispatch_clock > de->de_start - (60 * de->de_start_extra))
|
||||||
dvr_thread_new_pkt(de, sm->sm_data);
|
dvr_thread_new_pkt(de, sm->sm_data);
|
||||||
pkt_ref_dec(sm->sm_data);
|
pkt_ref_dec(sm->sm_data);
|
||||||
break;
|
break;
|
||||||
|
@ -649,7 +649,8 @@ dvr_thread_new_pkt(dvr_entry_t *de, th_pkt_t *pkt)
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void dvr_spawn_postproc(dvr_entry_t *de)
|
static void
|
||||||
|
dvr_spawn_postproc(dvr_entry_t *de)
|
||||||
{
|
{
|
||||||
char *fmap[256];
|
char *fmap[256];
|
||||||
char **args;
|
char **args;
|
||||||
|
@ -666,8 +667,8 @@ static void dvr_spawn_postproc(dvr_entry_t *de)
|
||||||
}
|
}
|
||||||
|
|
||||||
fbasename = strdup(de->de_filename);
|
fbasename = strdup(de->de_filename);
|
||||||
snprintf(start, sizeof(start), "%ld", de->de_start);
|
snprintf(start, sizeof(start), "%ld", de->de_start - de->de_start_extra);
|
||||||
snprintf(stop, sizeof(stop), "%ld", de->de_stop);
|
snprintf(stop, sizeof(stop), "%ld", de->de_stop + de->de_stop_extra);
|
||||||
|
|
||||||
memset(fmap, 0, sizeof(fmap));
|
memset(fmap, 0, sizeof(fmap));
|
||||||
fmap['f'] = de->de_filename; /* full path to recoding */
|
fmap['f'] = de->de_filename; /* full path to recoding */
|
||||||
|
|
|
@ -765,6 +765,8 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
|
||||||
if(dvr_postproc != NULL)
|
if(dvr_postproc != NULL)
|
||||||
htsmsg_add_str(r, "postproc", dvr_postproc);
|
htsmsg_add_str(r, "postproc", dvr_postproc);
|
||||||
htsmsg_add_u32(r, "retention", dvr_retention_days);
|
htsmsg_add_u32(r, "retention", dvr_retention_days);
|
||||||
|
htsmsg_add_u32(r, "preExtraTime", dvr_extra_time_pre);
|
||||||
|
htsmsg_add_u32(r, "postExtraTime", dvr_extra_time_post);
|
||||||
htsmsg_add_u32(r, "dayDirs", !!(dvr_flags & DVR_DIR_PER_DAY));
|
htsmsg_add_u32(r, "dayDirs", !!(dvr_flags & DVR_DIR_PER_DAY));
|
||||||
htsmsg_add_u32(r, "channelDirs", !!(dvr_flags & DVR_DIR_PER_CHANNEL));
|
htsmsg_add_u32(r, "channelDirs", !!(dvr_flags & DVR_DIR_PER_CHANNEL));
|
||||||
htsmsg_add_u32(r, "channelInTitle", !!(dvr_flags & DVR_CHANNEL_IN_TITLE));
|
htsmsg_add_u32(r, "channelInTitle", !!(dvr_flags & DVR_CHANNEL_IN_TITLE));
|
||||||
|
@ -784,6 +786,12 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
|
||||||
if((s = http_arg_get(&hc->hc_req_args, "retention")) != NULL)
|
if((s = http_arg_get(&hc->hc_req_args, "retention")) != NULL)
|
||||||
dvr_retention_set(atoi(s));
|
dvr_retention_set(atoi(s));
|
||||||
|
|
||||||
|
if((s = http_arg_get(&hc->hc_req_args, "preExtraTime")) != NULL)
|
||||||
|
dvr_extra_time_pre_set(atoi(s));
|
||||||
|
|
||||||
|
if((s = http_arg_get(&hc->hc_req_args, "postExtraTime")) != NULL)
|
||||||
|
dvr_extra_time_post_set(atoi(s));
|
||||||
|
|
||||||
if(http_arg_get(&hc->hc_req_args, "dayDirs") != NULL)
|
if(http_arg_get(&hc->hc_req_args, "dayDirs") != NULL)
|
||||||
flags |= DVR_DIR_PER_DAY;
|
flags |= DVR_DIR_PER_DAY;
|
||||||
if(http_arg_get(&hc->hc_req_args, "channelDirs") != NULL)
|
if(http_arg_get(&hc->hc_req_args, "channelDirs") != NULL)
|
||||||
|
|
|
@ -334,7 +334,8 @@ tvheadend.dvrsettings = function() {
|
||||||
root: 'dvrSettings'
|
root: 'dvrSettings'
|
||||||
}, ['storage','postproc','retention','dayDirs',
|
}, ['storage','postproc','retention','dayDirs',
|
||||||
'channelDirs','channelInTitle',
|
'channelDirs','channelInTitle',
|
||||||
'dateInTitle','timeInTitle']);
|
'dateInTitle','timeInTitle',
|
||||||
|
'preExtraTime', 'postExtraTime']);
|
||||||
|
|
||||||
var confpanel = new Ext.FormPanel({
|
var confpanel = new Ext.FormPanel({
|
||||||
title:'Digital Video Recorder',
|
title:'Digital Video Recorder',
|
||||||
|
@ -343,7 +344,7 @@ tvheadend.dvrsettings = function() {
|
||||||
bodyStyle:'padding:15px',
|
bodyStyle:'padding:15px',
|
||||||
anchor: '100% 50%',
|
anchor: '100% 50%',
|
||||||
labelAlign: 'right',
|
labelAlign: 'right',
|
||||||
labelWidth: 200,
|
labelWidth: 250,
|
||||||
waitMsgTarget: true,
|
waitMsgTarget: true,
|
||||||
reader: confreader,
|
reader: confreader,
|
||||||
defaultType: 'textfield',
|
defaultType: 'textfield',
|
||||||
|
@ -358,6 +359,14 @@ tvheadend.dvrsettings = function() {
|
||||||
minValue: 1,
|
minValue: 1,
|
||||||
fieldLabel: 'DVR Log retention time (days)',
|
fieldLabel: 'DVR Log retention time (days)',
|
||||||
name: 'retention'
|
name: 'retention'
|
||||||
|
}), new Ext.form.NumberField({
|
||||||
|
allowDecimals: false,
|
||||||
|
fieldLabel: 'Extra time before recordings (minutes)',
|
||||||
|
name: 'preExtraTime'
|
||||||
|
}), new Ext.form.NumberField({
|
||||||
|
allowDecimals: false,
|
||||||
|
fieldLabel: 'Extra time after recordings (minutes)',
|
||||||
|
name: 'postExtraTime'
|
||||||
}), new Ext.form.Checkbox({
|
}), new Ext.form.Checkbox({
|
||||||
fieldLabel: 'Make subdirectories per day',
|
fieldLabel: 'Make subdirectories per day',
|
||||||
name: 'dayDirs'
|
name: 'dayDirs'
|
||||||
|
|
Loading…
Add table
Reference in a new issue