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:
Andreas Öman 2009-08-19 19:44:33 +00:00
parent 72ff81e25c
commit 5dfdbc7a9b
6 changed files with 95 additions and 11 deletions

6
debian/changelog vendored
View file

@ -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

View file

@ -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
*/ */

View file

@ -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();
}
/** /**
* *
*/ */

View file

@ -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 */

View file

@ -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)

View file

@ -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'