How to create a Manual Time/Channel based recording job

Stumbled around a bit until I got it working.

Using curl from Windows command line.
Curious just how minimal the post has to be. I'm specifying;
Name
Time
Duration
Channels
Serial:0
Airing.Source:"manual"
Airing.Channel
Airing.Time
Airing.Duration
Airing.Title
Airing.EpisodeTitle
Airing.Summary

Passing these as null
Channel
DeviceID
Error
FileID
RuleID
Airing.Raw

and setting these to false
Failed
Skipped

1 Like

Added Season, Episode and image.

Found this site useful for getting the Time to put in the scheduled job json data.

I have a json file that I edit to create the schedule and just use curl to send that file using the curl option
--data-binary @filename.json

Care to share an example of your JSON payload?

2 Likes
{
    "Name": "Manual Recordings",
    "Time": 1601316000,
    "Duration": 120,
    "Channels": ["6750"],
    "Channel": "",
    "DeviceID": "",
    "RuleID": "",
    "Serial": 0,
    "FileID": "",
    "Skipped": false,
    "Failed": false,
    "Error": "",
    "Airing": {
        "Source": "manual",
        "Channel": "6750",
        "Time": 1601316000,
        "Duration": 120,
        "Title": "Manual Recordings",
        "EpisodeTitle": "BUZZR Test Recording",
        "Summary": "Record BUZZR-6750 on Monday, September 28, 2020 6:00:00 PM GMT for 2 minutes.",
        "Image": "https://tmsimg.fancybits.co/assets/p9467679_st_h6_aa.jpg",
        "SeasonNumber": 1,
        "EpisodeNumber": 1,
        "Raw": ""
    }
}
1 Like

The only fields necessary are Name, Time, Duration, Channel and Airing.

Here's a quick and dirty script in POSIX shell. It requires cURL, but that is the only requirement. The parameters are as follows:

  • channel - This is the channel you wish to record.
  • start - This is the time to begin recording. Fuzzy options are permitted, such as "5:00PM next Friday", "Oct 2 17:00", or even a specific "10/2/2020 17:00". If your date string is going to have spaces in it, then you need to quote the string. (The order of date versus time does not matter; time should include the colon; times before noon do not require AM, but after noon times must include PM or be in 24-hour notation; if using, it must be AM/PMa, pm, or P will not work, nor will 5:00 PM with a space.)
  • duration - How long (in minutes) should the recording be.
  • title - This is the title for your recording. (Optional)
  • description - If you are assigning a title, you may also optionally specify a description for the recording. (Optional)

By default, the script will use 127.0.0.1 as the address for your DVR server. If you wish to provide one of your own, set the environment variable CHANNELS to the IP address of your DVR server. (Alternatively, you may set the CHANNELS variable at the head of the script, or modify the script's _DVR variable to point to your DVR server.)

(Note: There is one short-coming with this script: recordings made will not appear in the Library. However, they will be listed in the Recordings page. This is just a bare-bones POC, so feel free to modify to your liking. Thanks to @chDVRuser for their initial work. The only error-checking is to ensure that at least 3 parameters are passed, not to verify they are properly formatted.)

 #!/bin/sh

_DVR=${CHANNELS:-127.0.0.1}

if [ -z $3 ]; then
	echo "Usage: $0 channel start duration [title [description]]"
	exit 0
fi

_CH=$1
_START=$(date -d "$2" +%s)
_DUR=$(("$3" * 60))
_TITLE=${4:-"Manual Recording"}
_DESC=$5

create_job() {
cat << EOF
{
  "Name": "${_TITLE}",
  "Time": ${_START},
  "Duration": ${_DUR},
  "Channels": ["${_CH}"],
  "Airing": {
    "Source": "manual",
    "Channel": "${_CH}",
    "Time": ${_START},
    "Duration": ${_DUR},
    "Title": "${_TITLE}",
    "Summary": "${_DESC}",
    "Image": "https://tmsimg.fancybits.co/assets/p9467679_st_h6_aa.jpg",
    "Raw": ""
  }
}
EOF
}

curl -XPOST --data-binary "$(create_job)" "http://${_DVR}:8089/dvr/jobs/new"

(Note 2: After the recording has been made, you can access it from your primary storage location. If LOC is the location of your primary storage location, then recordings are stored as: ${LOC}/TV/${_TITLE}/${_TITLE} $(date -d "@${_START} +%F-%H%M).mpg, where:

  • LOC is the storage location referenced earlier
  • _TITLE is the title you set when creating the recording; if you omitted it, it defaults to Manual Recording
  • _START is when the recording began as seconds since midnight 1 Jan 1970 (ie, Unix epoch time)
  • $(date ...) is the time recording started as YYY-MM-DD-HHMM

Since the recordings don't show in the Library, and the Recordings page is not exhaustive/comprehensive, I figured I should include where the files are located and how they're named so they can be found.)

2 Likes

Do you mean Channels ?
I tried without that and it errored out.

So I pared it down and chose to keep
Airing.SeasonNumber
Airing.EpisodeNumber
Airing.OriginalDate

One could also add the following if they want to
Airing.Categories
Airing.Genres
Airing.Tags
Airing.Directors
Airing.Cast

{
    "Name": "Manual Recordings",
    "Time": 1601391600,
    "Duration": 120,
    "Channels": ["6750"],
    "Airing": {
        "Source": "manual",
        "Channel": "6750",
        "OriginalDate": "2020-09-29",
        "Time": 1601391600,
        "Duration": 120,
        "Title": "Manual Recordings",
        "EpisodeTitle": "BUZZR Test Recording",
        "Summary": "Record BUZZR-6750 on Tuesday, September 29, 2020 3:00:00 PM GMT for 2 minutes.",
        "Image": "https://tmsimg.fancybits.co/assets/p9467679_st_h6_aa.jpg",
        "ProgramID": "SH030703030000",
        "SeasonNumber": 0,
        "EpisodeNumber": 0,
        "Raw": ""
    }
}

Airing.ProgramID doesn't seem to do anything, I guess since the Airing.Source is "manual", not "tms".

I meant Channel, which is a string with a single channel number. What was the error in the logs?

Key: 'Job.Channels' Error:Field validation for 'Channels' failed on the 'required' tag
If I set "Channels":["6750","6000"] I see both channel numbers in the schedule view

Ah, okay then I guess Channels is the correct one. The other one is set internally after one of the channels is picked, so the recording knows which channel it was and can resume from the same channel in case of interruption.

I also found that Raw needs to be set to an empty string (""); null gives an error, too.

What is the error?

The DVR log shows:

2020/09/28 18:07:15.945719 Key: 'Job.Airing.Source' Error:Field validation for 'Source' failed on the 'required' tag
Key: 'Job.Airing.Channel' Error:Field validation for 'Channel' failed on the 'required' tag
Key: 'Job.Airing.Time' Error:Field validation for 'Time' failed on the 'required' tag
Key: 'Job.Airing.Duration' Error:Field validation for 'Duration' failed on the 'required' tag
Key: 'Job.Airing.Title' Error:Field validation for 'Title' failed on the 'required' tag

And the response is:

{"error":"invalid job"}

Not sure what processes the json (heard it was a programming language called Go).
But there must be a difference between setting Job.Airing.Raw:null and Job.Airing.Raw:""
Setting Job.Airing.Raw:null is the same as leaving out Job.Airing.Raw:"" and you get the same errors.

So, it appears that means set Job.Airing.Raw:""

null vs null terminated string, IDK

Thanks for getting me started on creating manual recordings.
I hope someday this will be a feature of your Channels DVR product.

2 Likes

I think that most Channels users are hoping for this. A quick, easy timed recording feature.

It's been working fine!
Just don't use an actual tms ProgramID, even though you set the source to 'manual', it still uses it.

As a test case, I set a Series pass and made a manual recording. Both of these will record.
The first one on Sunday is from the series pass, the other one on Monday is the manual recording.


You can record "everything".
Including recording the same episode on different channels at the same time.
Only problem is if the guide data changes and it doesn't air, since you're saying to record a specific channel at a specefic date/time, Channels DVR will not update it based on new guide data.

Example;

I've added these optional values to mine;
Airing.OriginalDate
Airing.Title
Airing.EpisodeTitle
Airing.Summary
Airing.Image
Airing.Tags
Airing.SeriesID
Airing.SeasonNumber
Airing.EpisodeNumber

OK to use Airing.SeriesID
Don't use Airing.ProgramID or it will override series pass scheduled jobs

{
  "Name": "Rick Steves' Europe",
  "Time": 1603583990,
  "Duration": 1820,
  "Channels": [
    "6004"
  ],
  "Airing": {
    "Source": "manual",
    "Channel": "6004",
    "OriginalDate": "2020-10-15",
    "Time": 1603583990,
    "Duration": 1820,
    "Title": "Rick Steves' Europe",
    "EpisodeTitle": "Austrian and Italian Alps",
    "Summary": "Zugspitze; Innsbruck, Austria; Tyrolean village festival; medieval castle; Dolomite Mountains.",
    "Image": "https://tmsimg.fancybits.co/assets/p477118_b_h6_aa.jpg",
    "Tags": [
      "CC",
      "HD 1080i",
      "HDTV",
      "New",
      "Stereo"
    ],
    "SeriesID": "477118",
    "SeasonNumber": 11,
    "EpisodeNumber": 1,
    "Raw": ""
  }
}
3 Likes

Wow :astonished: chDVRuser I'm impressed! I wish I had a better understanding of 'computers'(& programming/coding) to fully appreciate the amount of effort & ingenuity that you put into this.

Sorry I didn't respond sooner, (this year has been a doozy :confounded:) but I wanted to mention that your work did not go unnoticed. :+1:
(In addition to the devs,) it's people like You, racameron & others that make this such a Great Community. :smile:

Once I can set aside sometime, I plan on setting up a 2nd DVR (server) . Then after that, reading about cURL (& maybe 'coding 4 dummies' :face_with_hand_over_mouth:). I think I might try & tackle setting up a 'Manual Recording'. :grinning:

2 Likes