It's difficult not to lock yourself up in "I Need Channels DVR subscription" mindset, sure channels server adds lot of convenience factor but 8$ is not cheap especially in countries when citizens don't get salary in dollars and times are difficult and lot of people seeks to spare some money here and there.
Besides, Channels DVR makes sense only in countries that use Gracenote - in other countries there is really no way to have marked things in XMLTV guide as "new" because there is no absolute valid legal source of XMLTV guides and without this "series recording" option makes no sense at all. Gracenote itself has its flaws as Discovery constantly feed their database with wrong description of the shows and after Discovery Time Warner merge situation may be even worse. So this is small tutorial about how to deal with recordings from over-the-air since lot of users here own HDHomeRun anyway. It is also true for any direct link to stream you can find in m3u8 format.
Requirements
- HDHomeRun
- ffmpeg - you may install it by using homebrew, macports or download from here
- Keyboard Maestro (not necessary but good to have)
Recording from stream
This is really straightforward. To record stream from TVP1 I am using command
ffmpeg -i http://192.168.0.18:5004/auto/v1 -c:v copy -c:a copy -f mpegts -t 1:00:00 output.mpeg
-i <source>
indicates source url. The schema for HDHome run is http://<ipadress>:5004/auto/v<channel_number>
-c:v -c:a
are option for video and audio codec respectively, 'copy' ensures streams is recorded without re-encoding. This is mandatory even if you know source quality is 1080p, this is good practice to force this option because if you download from m3u8 playlist you find on other webpages the quallity of recorded content is matched to quality of broadband speed and it may vary and in result you may get recording with 480p or worse.
-f mpegts
not sure about this, I use it most of the time if recording from stream that offers mpeg it's good for both HLS and TS streams
-t hh:mm:ss
specifies how long recording should last.
If you want re-encode stream broadcasted in 1080 to 720 to save some space in real time instead of -c:v copy
use -c:v h264
in conjunction with -vf scale=1280:720
Scheduling using at command
That method may increase your power usage so better not use this on laptops but most of you use standalone machines for DVR anyway so addition to total energy usage in the mix should be minimal.
On Linux servers at deamon should be enabled by default. On MacOS you should run as root:
launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist
to enable at
command.
Syntax is really simple - at <time> <date>
hit enter the commands you want to launch and finish it with ctrl-D
. At supports many formats of entering time and date, so for example if I know TVP1 airs "Ekstradycja" today at 22:00 then I do:
at 22:00
[hit enter]
ffmpeg -i http://192.168.0.18:5004/auto/v1 -c:v copy -c:a copy -f mpegts -t 1:00:00 EkstradycjaS01E01.mpeg
[ctrl-D]
at -l
list current jobs at -m <jobnumber>
list what tasks are executed in specified job, in my case example listing looks that:
#!/bin/sh
# atrun uid=501 gid=20
# mail sebastian 0
umask 22
TERM_SESSION_ID=w2t0p0:C738113D-0CFF-4117-8A91-4463B5D5A39B; export TERM_SESSION_ID
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.J4On1F9E71/Listeners; export SSH_AUTH_SOCK
LC_TERMINAL_VERSION=3.4.16; export LC_TERMINAL_VERSION
Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.q0QBaW5hFd/Render; export Apple_PubSub_Socket_Render
COLORFGBG=15\;0; export COLORFGBG
ITERM_PROFILE=Darkula; export ITERM_PROFILE
XPC_FLAGS=0x0; export XPC_FLAGS
LANG=pl_PL.UTF-8; export LANG
PWD=/Users/sebastian; export PWD
SHELL=/bin/zsh; export SHELL
TERM_PROGRAM_VERSION=3.4.16; export TERM_PROGRAM_VERSION
TERM_PROGRAM=iTerm.app; export TERM_PROGRAM
PATH=/usr/local/opt/[email protected]/bin:/usr/local/opt/[email protected]/bin:/usr/local/opt/python@2/libexec/bin:/Users/sebastian/Library/Python/2.7/bin:/Users/sebastian/.rvm/gems/ruby-2.6.3@global/bin:/Users/sebastian/.yarn/bin:/Users/sebastian/bin:/Users/sebastian/.rvm/gems/ruby-3.0.0/bin:/Users/sebastian/.rvm/gems/ruby-3.0.0@global/bin:/Users/sebastian/.rvm/rubies/ruby-3.0.0/bin:/usr/local/bin:/usr/local/sbin:/Users/sebastian/.composer/vendor/bin:/opt/local/bin:/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin:/Users/sebastian/Skrypty:/usr/texbin:/usr/local/bin:/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/usr/local/MacGPG2/bin:/tools:/Users/sebastian/.rvm/bin:/Users/sebastian/.fzf/bin; export PATH
LC_TERMINAL=iTerm2; export LC_TERMINAL
COLORTERM=truecolor; export COLORTERM
TERM=xterm-256color; export TERM
HOME=/Users/sebastian; export HOME
TMPDIR=/var/folders/y4/6ggmr4bs5qld7j9n_mlplmtr0000gn/T/; export TMPDIR
USER=sebastian; export USER
XPC_SERVICE_NAME=0; export XPC_SERVICE_NAME
LOGNAME=sebastian; export LOGNAME
ITERM_SESSION_ID=w2t0p0:C738113D-0CFF-4117-8A91-4463B5D5A39B; export ITERM_SESSION_ID
__CF_USER_TEXT_ENCODING=0x0:29:42; export __CF_USER_TEXT_ENCODING
SHLVL=1; export SHLVL
OLDPWD=/Users/sebastian; export OLDPWD
PAGER=less; export PAGER
LESS=-R; export LESS
LSCOLORS=Gxfxcxdxbxegedabagacad; export LSCOLORS
SASS_LIBSASS_PATH=/Users/sebastian/src/libsass; export SASS_LIBSASS_PATH
LDFLAGS=-L/usr/local/opt/libffi/lib; export LDFLAGS
PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig; export PKG_CONFIG_PATH
CPPFLAGS=-I/usr/local/opt/libffi/include; export CPPFLAGS
CORRECT_IGNORE=\�\�\�subl\�\�\�; export CORRECT_IGNORE
rvm_prefix=/Users/sebastian; export rvm_prefix
rvm_path=/Users/sebastian/.rvm; export rvm_path
rvm_bin_path=/Users/sebastian/.rvm/bin; export rvm_bin_path
rvm_version=1.29.12\ \(latest\); export rvm_version
GEM_HOME=/Users/sebastian/.rvm/gems/ruby-3.0.0; export GEM_HOME
GEM_PATH=/Users/sebastian/.rvm/gems/ruby-3.0.0:/Users/sebastian/.rvm/gems/ruby-3.0.0@global; export GEM_PATH
MY_RUBY_HOME=/Users/sebastian/.rvm/rubies/ruby-3.0.0; export MY_RUBY_HOME
IRBRC=/Users/sebastian/.rvm/rubies/ruby-3.0.0/.irbrc; export IRBRC
RUBY_VERSION=ruby-3.0.0; export RUBY_VERSION
_=/usr/bin/at; export _
cd /Users/sebastian || {
echo 'Execution directory inaccessible' >&2
exit 1
}
OLDPWD=/Users/sebastian; export OLDPWD
ffmpeg -i http://192.168.0.18:5004/auto/v2 -c:v copy -c:a copy -f mpegts -t 01:45:00 LekarkaZRajskiejWyspy-Tajemnica.mpeg
Scheduling using cron
if you know you need recurring task instead of manually setting at jobs that may be cumbersome it's better to use cron deamon available in both linux and Mac in system. to edit cron jobs enter crontab -e
and you may enter jobs. Cron syntax is simple every line is 6 arguments - 5 for time specification and 6th for command to be executed. there are many crontab generators online to help. For example
00 22 * * 6 /bin/bash /home/sebastian/skynews.sh
means that on 22:00 only on saturdays (6) run script that records content from SkyNews.
** Scheduling using Keyboard Maestro**
Keyboard Maestro support time-triggered macros so settings is actually simple:
when triggering scripts using KM or in better to use absolute path to ffmpeg. In this example command I used -map 0:v
and -map 0:a
- TVP broadcast most of tv shows with 3 audio tracks - original, voice narrated translation and voice over desriptive for hearing impaired, this setting ensures all tracks are captured.
I undestand this may looks complicated at first but believe me it's really not. I hope this can people spare some money and better know machines they using and to have some fun seeing it really works