This shows how to set up a digital video recorder using webcamd, Tvheadend, nginx, and Samba on a FreeBSD box. I have been using an Elgato EyeTV Hybrid USB stick which seems to be compatible to some Terratec devices according to the LinuxTV V4L-DVB wiki. The em28xx driver of webcamd supports this stick. Thus, this howto should be applicable to any supported device.
# make -C /usr/ports/multimedia/webcamd config install clean
# make -C /usr/ports/multimedia/tvheadend config install clean
# make -C /usr/ports/www/nginx config install cleanI have used nginx to serve recordings to my local PC via http. Therefore, just a few build options are needed:
# make -C /usr/ports/net/samba411 config install cleanI just selected these options:
# pkg autoremove # rm -rv /usr/ports/distfiles/*
# sysrc dbus_enable=YES # sysrc avahi_daemon_enable=YES # service dbus start # service avahi-daemon start
# sysrc kld_list+=cuseManually load it without rebooting the machine:
# kldload cuse
# cd /boot/modules # fetch https://github.com/OpenELEC/dvb-firmware/raw/master/firmware/dvb-usb-terratec-htc-stick-drxk.fw
# sysrc webcamd_enable=YES
# sysrc webcamd_devd_starts_unspecified=NO
# webcamd -lThe output should look like this:
Available device(s): webcamd [-d ugen1.1] -N AMD-EHCI-root-HUB -S unknown -M 0 webcamd [-d ugen0.1] -N 0x1022-XHCI-root-HUB -S unknown -M 0 webcamd [-d ugen0.2] -N Elgato-EyeTV-Hybrid -S 081xxxxxxxxx -M 0 Show webcamd usage: webcamd -h
# sysrc webcamd_0_flags="-N Elgato-EyeTV-Hybrid -S 081xxxxxxxxx"
# ls -Rl /dev/dvb total 1 dr-xr-xr-x 2 root wheel 512 Jul 7 16:55 adapter0 /dev/dvb/adapter0: total 0 crw-rw---- 1 webcamd webcamd 0x81 Jul 7 16:55 demux0 crw-rw---- 1 webcamd webcamd 0x82 Jul 7 16:55 dvr0 crw-rw---- 1 webcamd webcamd 0x83 Jul 7 16:55 frontend0
# pw groupmod webcamd -m tvheadend
# cat <<EOF >/etc/syslog.d/tvheadend.conf !tvheadend daemon.* /var/log/tvheadend.log EOF # cat <<EOF >/etc/newsyslog.conf.d/tvheadend.conf /var/log/tvheadend.log 644 14 * @T00 JC EOF
# touch /var/log/tvheadend.log # service syslogd reload
# mkdir /var/log/tvheadend # ln -s /dev/null /var/log/tvheadend/tvheadend.log
# sysrc tvheadend_enable=YES # sysrc tvheadend_flags="-C -U"
# service tvheadend start
# mkdir -m 0755 /tvheadend # chown tvheadend:tvheadend /tvheadendIf you use ZFS, you may create a dedicated filesystem for this and disable compression and/or deduplication.
--- nginx.conf-dist 2020-06-13 10:44:52.850585000 +0200 +++ nginx.conf 2020-07-07 20:44:47.072723000 +0200 @@ -13,9 +13,11 @@ #pid logs/nginx.pid; +load_module /usr/local/libexec/nginx/ngx_http_fancyindex_module.so; events { - worker_connections 1024; + use kqueue; + worker_connections 1024; } @@ -27,18 +29,21 @@ # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; - #access_log logs/access.log main; + access_log off; sendfile on; - #tcp_nopush on; + tcp_nopush on; + tcp_nodelay on; #keepalive_timeout 0; keepalive_timeout 65; - #gzip on; + gzip off; + directio off; + aio on; server { - listen 80; + listen 80 accept_filter=httpready reuseport; server_name localhost; #charset koi8-r; @@ -46,8 +51,15 @@ #access_log logs/host.access.log main; location / { - root /usr/local/www/nginx; + root /tvheadend; index index.html index.htm; + fancyindex on; + fancyindex_exact_size off; + fancyindex_localtime on; + } + + location = /favicon.ico { + root /usr/local/www/nginx; } #error_page 404 /404.html;
# sysrc kld_list+=accf_http # sysrc nginx_enable=YES
# kldload accf_http # service nginx start
# cat <<EOF >/usr/local/etc/smb4.conf [global] interfaces = bridge0 workgroup = WORKGROUP security = user netbios name = tvserver server string = tvserver.local hostname lookups = yes load printers = no show add printer wizard = no time server = yes map to guest = Bad User use mmap = yes dos charset = 850 unix charset = UTF-8 mangled names = no log level = 0 server min protocol = LANMAN1 [tvheadend] guest ok = yes hide dot files = no path = /tvheadend read only = yes use sendfile = yes EOF
# sysrc samba_server_enable=YES # service samba_server start
check_tvh.py checks and restarts webcamd and Tvheadend if Tvheadend does not report any active TV device.