Hi Klaas,
I've created a program to generate lots of manual recordings. It breaks my backend with 'taking more than 15000 ms to get a lock'. I have not had it lock up the tuner and prevent subsequent recordings though
It seems to have a preference to break with multiplex 1 (channel 22) but that may be a coincidence.
https://en.wikipedia.org/wiki/Crystal_P ... television
In my case, I have 7 multiplexes and 4 tuners so I alternated recordings from a batch with channels in multiplexes 1,2,3,4 and a batch with 5,6,7.
Code: Select all
Chan Start End Mpx CallSign
10019 2023-02-05T18:47:00Z 2023-02-05T18:48:00Z 1 Dave
10002 2023-02-05T18:47:00Z 2023-02-05T18:48:00Z 2 BBC TWO
10020 2023-02-05T18:47:00Z 2023-02-05T18:48:00Z 3 Drama
10003 2023-02-05T18:47:00Z 2023-02-05T18:48:00Z 4 ITV1
-----
10027 2023-02-05T18:53:00Z 2023-02-05T18:54:00Z 5 Yesterday
10101 2023-02-05T18:53:00Z 2023-02-05T18:54:00Z 6 BBC ONE HD
10008 2023-02-05T18:53:00Z 2023-02-05T18:54:00Z 7 London Live
To set it up:
Install scan_database module. See
https://www.mythtv.org/wiki/Perl_API_examples
Put code in swamp.pl
chmod 755 swamp.pl
See the user parameters near the start.
Set $backend, $batchesneeded
Check timings: $preroll, $postroll, $reclength and $gap. All in minutes.
$stagger - all recordings within a batch start at the same time. Set this to put an additional delay of $stagger seconds between them.
Use ./swamp.pl --list to get a list of your channels and multiplexes.
Set channel numbers in @batch. eg:
Code: Select all
my @batch=('10019,10002,10020,10003', #first batch of channels
'10027,10101,10008' #second batch
#add more if needed
);
Have as as many channels in each batch and as many batches as you wish (it will just rotate through them).
Run ./swamp.pl - it will list proposed batches.
If happy with this, do ./swamp.pl --fullrun. It will trigger the recordings then give a list of upcoming recordings.
Thanks for your continued support.
Phil
Code: Select all
#!/usr/bin/perl -w
use strict;
use Getopt::Long;
use Time::Local;
use lib '.'; #add current dir to perl path if not already there
use scan_database; #See https://www.mythtv.org/wiki/Perl_API_examples
#
#swamp a backend with manual recordings
#
# Usage: --list list channels in backend
# --fullrun allow program to trigger recordings - otherwise it just lists proposed recordings.
#
#====== user parameters === Set to suit your setup ===
my $backend='http://192.168.2.109:6544';
my $batchesneeded=7; #no of batches of recordings to be made.
#List of channels to be used in the batches - select different multiplexes.
my @batch=('10019,10002,10020,10003', #channels in first wave - all from different multiplexes
'10027,10101,10008' #second wave
#further ones loop round
);
#Timings
my $stagger=0; #gap between start of recordings within a batch (in seconds)
my $preroll=2;
my $postroll=2;
my $reclength=1; #length of recording in mins
my $gap=1; #gap after postroll before next preroll in minutes
#==== End of user parameters ====
#recording template
my %template=(
AutoCommflag => 'false',
AutoExpire => 'true',
AutoMetaLookup => 'false',
AutoTranscode => 'false',
AutoUserJob1 => 'false',
AutoUserJob2 => 'false',
AutoUserJob3 => 'false',
AutoUserJob4 => 'false',
AverageDelay => '0',
CallSign => 'BBC TWO',
Category => '',
ChanId => '10002',
Description => 'Swamp test (Manual Record)',
DupIn => 'All Recordings',
DupMethod => 'None',
EndOffset => '2',
EndTime => '2023-02-03T12:55:00Z',
Episode => '0',
Filter => '0',
FindDay => '6',
FindTime => '12:45:00.000',
Inactive => 'false',
Inetref => '',
LastRecorded => '2023-02-03T12:43:48Z',
MaxEpisodes => '0',
MaxNewest => 'false',
NewEpisOnly => 'false',
ParentId => '0',
PlayGroup => 'Default',
PreferredInput => '0',
ProgramId => '',
RecGroup => 'Default',
RecPriority => '2',
RecProfile => 'Default',
SearchType => 'Manual Search',
Season => '0',
SeriesId => '',
StartOffset => '2',
StartTime => '2023-02-03T12:45:00Z',
StorageGroup => 'Default',
SubTitle => '',
Title => 'Swamp (Manual Record)',
Transcoder => '0',
Type => 'Single Record'
);
my $content;
my %Channelinfo;
#check calling parameters
my $fullrun=0; my $listchannels=0;
GetOptions ('list'=>\$listchannels, 'fullrun'=>\$fullrun);
#get channel details from backend
getchannels();
#list them if needed
if ($listchannels){listchannels(); exit 0};
#timekeeping
my $epoch=time();
print ZTime($epoch), " = time now\n";
$epoch+=59;
$epoch -= $epoch%60;
print ZTime($epoch), " = rounded\n";
$epoch+= 60*($gap+$preroll); #starttime of next wave
print ZTime($epoch), " = Time of First batch\n";
#list recordings - generate them if --fullrun
print "Proposed $batchesneeded batches of recordings:\n";
print "Chan Start End Mpx CallSign\n";
my $batchnumber=0;
while ($batchnumber<$batchesneeded){
for my $set (@batch){
if ($batchnumber<$batchesneeded){
my $delay=0; #stagger start of recordingd within a batch
my @chlist = split /,/,$set;
for my $chan (@chlist){
unless (exists $Channelinfo{$chan}){die "channel $chan not known"};
record($chan, $epoch+$delay);
$delay+=$stagger;
}
$batchnumber++;
print "-----\n";
}
$epoch += 60*($gap+$preroll+$reclength+$postroll); #starttime of next wave
}
}
if ($fullrun){
#list upcoming recordings
sleep(5);
getupcoming();
}else{
print "To trigger these recordings, please re-run with --fullrun\n";
}
exit 0;
sub record{ #list recording and trigger it if --fullrun
(my $chan, my $epochstart)=@_;
my $starttime=ZTime($epochstart);
my $endtime=ZTime($epochstart + 60*$reclength);
print "$chan $starttime $endtime $Channelinfo{$chan}{Mpx} $Channelinfo{$chan}{Name}\n";
return unless ($fullrun);
#get template recording rule
my %recrule=%template;
#modify it
$recrule{StartTime}=$starttime;
$recrule{EndTime}=$endtime;
$recrule{CallSign}=$Channelinfo{$chan}{Name};
$recrule{Station}=$recrule{CallSign};
$recrule{ChanId}=$chan;
#Trigger the recording:
my $url=$backend .'/Dvr/AddRecordSchedule';
ValidatePost(%recrule, $url, 'raw', 12);
print "Recording triggered\n";
sleep(1);
}
sub getchannels{
#query backend and get all channel names and multiplexes
my $temp; my %sources; my %ChanData;
#get sources
my $url=$backend. '/Channel/GetVideoSourceList';
scan_database::ReadBackend($url, $temp);
scan_database::FillHashofHash(%sources, $temp, 'VideoSource', 'Id', 'SourceName');
#get all channels per source
for my $source (keys %sources){
scan_database::ReadBackend($backend . '/Channel/GetChannelInfoList?SourceID='.$source.
'&OnlyVisible=false&Details=true', $temp);
my %temphash;
scan_database::FillHashofHash(%temphash, $temp, 'ChannelInfo', 'ChanId', 'CallSign','Visible','MplexId');
%ChanData = (%ChanData, %temphash);
}
for (sort keys %ChanData){
if ($ChanData{$_}{Visible} eq 'true'){
$Channelinfo{$_}{Mpx}=$ChanData{$_}{MplexId};
$Channelinfo{$_}{Name}= $ChanData{$_}{CallSign};
}
}
}
sub listchannels{ #called if --list
for (sort {$a <=>$b} keys %Channelinfo){
print "$_ = Mpx:$Channelinfo{$_}{Mpx} $Channelinfo{$_}{Name}\n";
}
}
sub ZTime{ #convert epoch time to 2021-12-03T13:44:04Z form
(my $epoch)=@_;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($epoch);
$year+=1900; $mon++;
return sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", $year, $mon, $mday, $hour, $min, $sec);
}
sub getupcoming{
print "Upcoming recordings\n";
my $url="$backend/Dvr/GetUpcomingList";
unless (scan_database::ReadBackend($url,$content)){die "Could not get guide data"};
#extract fields
my %guide;
scan_database::FillHashofHash(%guide, $content,'Program','#','StartTime','ChanId','Title');
print "Start Chan Title\n";
for (sort {$a <=> $b} keys %guide){
print "$guide{$_}{StartTime} $guide{$_}{ChanId} $guide{$_}{Title}\n";
};
}