How to create a Manual Time/Channel based recording job

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

Another lesson learned about manual recordings.

Don't set a manual recording for the same show/episode at the same time your pass is recording it from another channel. Change the Title, EpisodeTitle, or time to make it unique. The "Name" doesn't matter, it's only used for the recording rule (Scheduled Job Name).

I ended up with 'A Charlie Brown Christmas' recorded from both my local PBS-HD and PBS kids on different channels into the same recording file on Channels DVR. The file contained both, the HD and SD broadcasts which were broadcast at the same time on different channels. I didn't even think this was possible.

I'm sure the reason it happened was the Title to record and the time was the same on each scheduled job.

I had to use my video editor to extract the correct PID's from the file.

Logs for Devs if interested. I already recovered the recording with my video editor and deleted it from Channels DVR. Here is the DVR log info.

PBS Kids-SD Manual Recording
2020/12/13 19:29:30.010185 [DVR] Starting job 1607916570-ch387 A Charlie Brown Christmas on ch=[387]
2020/12/13 19:29:30.497273 [TNR] Opened connection to 1323AADB/0 for ch387 KVIEDT4
2020/12/13 19:29:30.497621 [DVR] Recording for job 1607916570-ch387 from 1323AADB ch387 into "TV/A Charlie Brown Christmas/A Charlie Brown Christmas 1965-12-09 2020-12-13-1929.mpg" for 30m59.989688606s
2020/12/13 20:00:30.487208 [TNR] Closed connection to 1323AADB/0 for ch387 KVIEDT4
2020/12/13 20:00:30.502623 [SNR] Statistics for "TV/A Charlie Brown Christmas/A Charlie Brown Christmas 1965-12-09 2020-12-13-1929.mpg": ss=95%-96% snq=100% seq=100% bps=3161636,455712-5124128 pps=314,66-499
2020/12/13 20:00:30.505666 [DVR] Finished job 1607916570-ch387 A Charlie Brown Christmas

PBS-HD Scheduled Recording
2020/12/12 11:06:25.776434 [DVR] Rule 'A Charlie Brown Christmas-706' (375) found 1 new airings
2020/12/12 11:06:25.780223 [DVR]   queued recording job for SH000527390000 @ Sun Dec 13 7:29:30PM (1607916570-375)
2020/12/13 19:29:30.497404 [DVR] Starting job 1607916570-375 A Charlie Brown Christmas on ch=[706]
2020/12/13 19:29:30.996144 [TNR] Opened connection to 1323AADB/1 for ch706 KVIEDT
2020/12/13 19:29:30.996333 [DVR] Recording for job 1607916570-375 from 1323AADB ch706 into "TV/A Charlie Brown Christmas/A Charlie Brown Christmas 1965-12-09 2020-12-13-1929.mpg" for 30m59.502520688s
2020/12/13 20:00:30.498961 [TNR] Closed connection to 1323AADB/1 for ch706 KVIEDT
2020/12/13 20:00:30.505872 [SNR] Statistics for "TV/A Charlie Brown Christmas/A Charlie Brown Christmas 1965-12-09 2020-12-13-1929.mpg": ss=95%-96% snq=100% seq=100% bps=4091867,303808-5501632 pps=394,29-528
2020/12/13 20:00:30.511960 [DVR] Finished job 1607916570-375 A Charlie Brown Christmas

Working on how to re-schedule recordings (jobs/rules) that failed (Delayed/Interrupted).
I'm sure the devs will beat me to it as I'm not a dev and it doesn't look easy.
But manually fixing those are a P.I.T.A. so I have some motivation until I run out of steam...

I'm so happy someone finally figured this, I always struggled to make web request listening to discover what has to be in POST request payload.
@chDVRuser send me a message if you still are motivated maybe I can help with development :slight_smile:

Also, I have to convert @racameron script to bash or better zsh. There is no need for POSIX in 2020s unless you have big IBM Mainframe in your room.
if there is no bash/zsh on server you simply install it. I would be surprised if one haden't, good shell with modern features is a must-have on Linux and MacOS systems.
Anyway thanks for something to keep my brain busy during pandemic :slight_smile:

Here's what I've been using to create manual recordings.
I do this from a Windows PC on the same network as my Channels DVR Server which runs on a NAS.

Another use for it - I used this today to 'Mark as Recorded' some Series Episodes I already have that my pass wanted to record because it was recorded by Channels DVR before I wiped it and reinstalled, so Channels DVR had no memory of recording it. I just created a manual recording for the episode using its metadata and had it record for 30 seconds on a random channel. I then deleted that recording and now Channels DVR thinks it recorded my episodes (which it actually did a couple years ago, but forgot).

Thanks for reporting this. I've put in a fix for the next build to detect when there's a filename conflict and pick a different file name.

1 Like

On the back of an issue with UK guide data (UK Guide data about to run out?) and repeated questions from my wife as to how she could schedule recordings without the guide data, I decided to wrap the script from @racameron in a Mac Automator workflow so that she could use it.

It's not particularly elegant from a UI perspective as Automator only lets you get one data entry element at a time, and it doesn't do any error checking, but at least it lets her enter the data in a standard format, does the duration calculation, and adds on the before / after padding automatically.

Happy to share it or post it somewhere if anyone else wants to try it out on their Mac.

1 Like

Can someone share an example json entry for a recording that was made manually? I want to make sure it is handled correctly with the upcoming changes in DVR: Performance improvements (v2021.05.13.0008)

I have some I can share, but I want to experiment a little with my script to include optional SeriesIDs to allow for display/grouping in the Library views.

Let me work on that tomorrow and Sat am, and I ought to have a couple to share, along with some additional notes/observations.

You looking for the curl payload or the recording /dvr/files json?
If both, I can create a short manual recording and post them.

The /dvr/files json payload from something that has recorded already.

I had to bail on the manual recording for the TVE channel and redo it using my HDHR Prime channel since my Xfinity TVE failed auth again.

This is using v2021.05.05.0011 if it matters.

curl payload

{
  "Name": "Pool Kings",
  "Time": 1620948540,
  "Duration": 2040,
  "Channels": [
    "204"
  ],
  "Airing": {
    "Source": "manual",
    "Channel": "204",
    "OriginalDate": "2019-07-29",
    "Time": 1620948540,
    "Duration": 2040,
    "Title": "Pool Kings",
    "EpisodeTitle": "Game Time",
    "Summary": "The Pool Kings create a sports pool that will provide entertainment for a client and his children.",
    "Image": "https://tmsimg.fancybits.co/assets/p12848663_b_h9_ai.jpg?w=720&h=540",
    "Categories": [
      "Episode",
      "Series"
    ],
    "Genres": [
      "Reality",
      "House/garden",
      "Home improvement"
    ],
    "Tags": [
      "CC",
      "HD 1080i",
      "HDTV"
    ],
    "SeriesID": "12848663",
    "SeasonNumber": 5,
    "EpisodeNumber": 8,
    "Cast": [
      "Justin Peek",
      "Kyle Peek"
    ],
    "Raw": ""
  }
}

scheduled job /dvr/jobs json

{
  "ID": "1620948540-ch204",
  "Name": "Pool Kings",
  "Time": 1620948540,
  "Duration": 2040,
  "Channels": [
    "204"
  ],
  "Channel": "204",
  "DeviceID": "1323AADB",
  "RuleID": "",
  "Serial": 0,
  "FileID": "3444",
  "Skipped": false,
  "Failed": false,
  "Error": "",
  "Airing": {
    "Source": "manual",
    "Channel": "204",
    "OriginalDate": "2019-07-29",
    "Time": 1620948540,
    "Duration": 2040,
    "Title": "Pool Kings",
    "EpisodeTitle": "Game Time",
    "Summary": "The Pool Kings create a sports pool that will provide entertainment for a client and his children.",
    "Image": "https://tmsimg.fancybits.co/assets/p12848663_b_h9_ai.jpg?w=720&h=540",
    "Categories": [
      "Episode",
      "Series"
    ],
    "Genres": [
      "Reality",
      "House/garden",
      "Home improvement"
    ],
    "Tags": [
      "CC",
      "HD 1080i",
      "HDTV"
    ],
    "SeriesID": "12848663",
    "ProgramID": "",
    "TeamIDs": null,
    "SeasonNumber": 5,
    "EpisodeNumber": 8,
    "Directors": null,
    "Cast": [
      "Justin Peek",
      "Kyle Peek"
    ],
    "Raw": null
  },
  "UpdatedAt": 1620949476959
}

recording /dvr/files json

{
  "ID": "3444",
  "JobID": "1620948540-ch204",
  "RuleID": "",
  "GroupID": "12848663",
  "Path": "TV/Pool Kings/Pool Kings S05E08 2019-07-29 Game Time 2021-05-13-1644.mpg",
  "Checksum": "",
  "CreatedAt": 1620949476,
  "Watched": false,
  "Deleted": false,
  "PlaybackTime": 0,
  "Duration": 1103.476511,
  "Commercials": null,
  "Delayed": true,
  "Corrupted": false,
  "Cancelled": false,
  "Completed": true,
  "Processed": true,
  "Favorited": false,
  "Locked": false,
  "Airing": {
    "Source": "manual",
    "Channel": "204",
    "OriginalDate": "2019-07-29",
    "Time": 1620948540,
    "Duration": 2040,
    "Title": "Pool Kings",
    "EpisodeTitle": "Game Time",
    "Summary": "The Pool Kings create a sports pool that will provide entertainment for a client and his children.",
    "Image": "https://tmsimg.fancybits.co/assets/p12848663_b_h9_ai.jpg?w=720&h=540",
    "Categories": [
      "Episode",
      "Series"
    ],
    "Genres": [
      "Reality",
      "House/garden",
      "Home improvement"
    ],
    "Tags": [
      "CC",
      "HD 1080i",
      "HDTV"
    ],
    "SeriesID": "12848663",
    "ProgramID": "",
    "TeamIDs": null,
    "SeasonNumber": 5,
    "EpisodeNumber": 8,
    "Directors": null,
    "Cast": [
      "Justin Peek",
      "Kyle Peek"
    ],
    "Raw": null
  },
  "ChannelNumber": "204",
  "DeviceID": "1323AADB",
  "PlayedAt": 0,
  "UpdatedAt": 1620950580240,
  "DeletedAt": 0,
  "FavoritedAt": 0,
  "DeletedReason": "",
  "DeleteNow": false,
  "JobTime": 1620948540,
  "JobDuration": 2040,
  "HighestPTS": 0,
  "SignalStats": {
    "SS": {
      "Initial": 94,
      "Last": 94,
      "Min": 94,
      "Max": 95,
      "Sum": 51865,
      "GoodCount": 551,
      "BadCount": 0
    },
    "SNQ": {
      "Initial": 100,
      "Last": 100,
      "Min": 100,
      "Max": 100,
      "Sum": 55100,
      "GoodCount": 551,
      "BadCount": 0
    },
    "SEQ": {
      "Initial": 100,
      "Last": 100,
      "Min": 100,
      "Max": 100,
      "Sum": 55100,
      "GoodCount": 551,
      "BadCount": 0
    },
    "BPS": {
      "Initial": 42112,
      "Last": 2246976,
      "Min": 42112,
      "Max": 2847072,
      "Sum": 1151439840,
      "GoodCount": 551,
      "BadCount": 0
    },
    "PPS": {
      "Initial": 0,
      "Last": 228,
      "Min": 0,
      "Max": 286,
      "Sum": 117647,
      "GoodCount": 550,
      "BadCount": 1
    },
    "TSERR": {
      "Initial": 0,
      "Last": 0,
      "Min": 0,
      "Max": 0,
      "Sum": 0,
      "GoodCount": 551,
      "BadCount": 0
    },
    "NETERR": {
      "Initial": 0,
      "Last": 0,
      "Min": 0,
      "Max": 0,
      "Sum": 0,
      "GoodCount": 551,
      "BadCount": 0
    },
    "Grade": {
      "GoodCount": 551,
      "BadCount": 0
    },
    "NetworkGrade": {
      "GoodCount": 551,
      "BadCount": 0
    },
    "SignalGrade": {
      "GoodCount": 551,
      "BadCount": 0
    }
  },
  "CommercialsAligned": false,
  "CommercialsEdited": false,
  "CommercialsVerified": false,
  "CommercialDetectSource": "",
  "CloudComskip": {
    "Successful": false
  },
  "ImportPath": "",
  "ImportQuery": "",
  "ImportGroup": "",
  "ImportedAt": 0,
  "StreamLinks": null,
  "DeleteScheduledFor": 864000000
}
1 Like

Thank you.

With v2021.05.14.0010, I believe the payload for curl doesn't need to contain Raw anymore.

1 Like

I can verify that.

With v2021.05.05.0011
the curl post returns {"error":"invalid job"}
and the DVR log shows
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

After updating to v2021.05.14.0010
the curl post succeeds, returning the scheduled job json

I also verified that including "Raw": "" doesn't cause an error.

1 Like

Here is one of mine.

{
 "Name":"Fox Weekend Dinner",
"Time": 1621116060,
"Duration": 3300,
"Channels": ["6073"],
"Airing": {
"Source": "TV_Data",
"Channel": "6073",
"Time": 1621116060,
"Duration": 3300,
"Title": "Fox Weekend Dinner",
"EpisodeTitle": "Saturday 05/15/21",
"Summary": "",
"Image": "https://tmsimg.fancybits.co/assets/p8529464_b_h9_ag.jpg?w=720\u0026h=540",
"Categories":["Episode","Series"],
"SeriesID":"",
"ProgramID":"",
"SeasonNumber": 2021,
"EpisodeNumber": 135,
"Raw": ""
}}

Here's one from today.

{"ID":"1811","JobID":"1620996975-ch6074","RuleID":"","GroupID":"Episode","Path":"TV\Varney\Varney S2021E134 Friday 051421 2021-05-14-0856.mpg","Checksum":"","CreatedAt":1620996975,"Watched":false,"Deleted":false,"PlaybackTime":7947,"Duration":11063.424,"Commercials":null,"Delayed":false,"Corrupted":false,"Cancelled":false,"Completed":true,"Processed":true,"Favorited":false,"Locked":false,"Airing":{"Source":"TV_Data","Channel":"6074","OriginalDate":"","Time":1620996975,"Duration":11040,"Title":"Varney","EpisodeTitle":"Friday 05/14/21","Summary":"","Image":"https://tmsimg.fancybits.co/assets/p7999086_b_h6_ac.jpg","Categories":["Episode","Series"],"Genres":null,"Tags":null,"SeriesID":"","ProgramID":"","TeamIDs":null,"SeasonNumber":2021,"EpisodeNumber":134,"Directors":null,"Cast":null,"Raw":null},"ChannelNumber":"6074","DeviceID":"TVE-Fubo","PlayedAt":1621007560639,"UpdatedAt":1621008015573,"DeletedAt":0,"FavoritedAt":0,"DeletedReason":"","DeleteNow":false,"JobTime":1620996975,"JobDuration":11040,"HighestPTS":995708891,"SignalStats":null,"CommercialsAligned":false,"CommercialsEdited":false,"CommercialsVerified":false,"CommercialDetectSource":"","CloudComskip":{"Successful":false},"ImportPath":"","ImportQuery":"","ImportGroup":"","ImportedAt":0,"StreamLinks":null},

1 Like