{"id":225,"date":"2022-09-04T11:10:21","date_gmt":"2022-09-04T18:10:21","guid":{"rendered":"https:\/\/my.apolonio.tech\/?p=225"},"modified":"2022-09-04T11:11:09","modified_gmt":"2022-09-04T18:11:09","slug":"view-hdhr-from-a-web-browser","status":"publish","type":"post","link":"https:\/\/my.apolonio.tech\/?p=225","title":{"rendered":"View HDHR from a Web Browser"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">Introduction<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This document shows you how to set up a system so you can view your web channels from a web browser.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Prerequisites<\/h1>\n\n\n\n<ul class=\"wp-block-list\"><li>Linux Web Server (in this case we will use Rocky Linux 8.5)<\/li><li>Browser that supports HTML5<\/li><li>Configured and working HD Homerun<\/li><li>Linux and HDHR device should be on same network (vlan\/subnet).<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you are going to access the web server remotely, it is assumed that port 80 and 443 are opened on the internet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The linux web server is based on this<br><a href=\"https:\/\/my.apolonio.tech\/?p=221\" data-type=\"URL\" data-id=\"https:\/\/my.apolonio.tech\/?p=221\">https:\/\/my.apolonio.tech\/?p=221<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It needs to have enough horsepower to run ffmpeg<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step #1 Install 3rd party repos so you can install ffmpeg and vlc<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Do these as root technically you don\u2019t need vlc, its in here due to some other things I have planned, there are other ways to install ffmpeg and you after you compile the hdhomerun utility you can delete it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wget https:\/\/mirrors.rpmfusion.org\/nonfree\/el\/rpmfusion-nonfree-release-8.noarch.rpm\r\ndnf -y localinstall rpmfusion-nonfree-release-8.noarch.rpm\r\ndnf -y install epel-release\r\ndnf -y install dnf-plugins-core\r\ndnf config-manager --set-enabled epel-testing\r\ndnf config-manager --set-enabled powertools\r\ndnf -y makecache\r\ndnf -y install ffmpeg vlc gcc\r\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Step #2 Configure firewall rules<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Do these as root<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>firewall-cmd --permanent --add-port=1935\/tcp\r\nfirewall-cmd --permanent --add-port=1935\/udp\r\nfirewall-cmd --permanent --add-port=5000\/tcp\r\nfirewall-cmd --permanent --add-port=5000\/udp\r\nfirewall-cmd --permanent --add-source-port=65001\/udp\r\nfirewall-cmd --permanent --add-service={http,https,samba,nfs,nfs3,mountd,rpc-bind}\r\nfirewall-cmd --reload\r\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For the lazy with bad security habits, commented out so not to encourage simple copy and pasting.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#systemctl stop firewalld\r\n#systemctl disable firewalld\r\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Step #3 Install hdhomerun utility<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Do these as a normal user with sudo rights<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd\r\nmkdir src\r\ncd src\r\nwget https:\/\/download.silicondust.com\/hdhomerun\/libhdhomerun_20220822.tgz\r\ntar zxvf libhdhomerun_20220822.tgz\r\ncd libhdhomerun\/\r\nmake\r\nsudo cp -p hdhomerun_config \/usr\/local\/bin\/\r\nsudo cp -p libhdhomerun.so \/usr\/local\/lib64\/\r\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Test it<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>hdhomerun_config discover<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Step #4 Setup script thto transcode hdhr<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Do these as a normal user with sudo rights<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instructions are based from this guys page, so credit is due where credit is due<br><a href=\"https:\/\/www.rickmakes.com\/streaming-live-tv-from-a-hdhomerun-to-a-web-browser-using-ffmpeg\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.rickmakes.com\/streaming-live-tv-from-a-hdhomerun-to-a-web-browser-using-ffmpeg\/<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And his video <a rel=\"noreferrer noopener\" href=\"https:\/\/www.youtube.com\/watch?v=Nc7qx2Go2MY\" target=\"_blank\">https:\/\/www.youtube.com\/watch?v=Nc7qx2Go2MY<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step #4A create a location for transcoded files to stream from<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You will need a location to store the transcoded files, I recommend \/run which is RAM, but sometimes you want it on a disk filesystem, in this example I am using myself.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>udo mkdir \/var\/lib\/stream\/\r\nsudo chown larry:larry \/var\/lib\/stream\/\r\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step #4B Create the transcoding script<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the script that actually does the transcoding, you should run this as a normal user.  First create a bin directory in the user&#8217;s home directory to create the script.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd \r\nmkdir bin\r\ntouch ~\/bin\/stream.sh\r\nchmod +x ~\/bin\/stream.sh\r\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here is the script itself, place it in the stream.sh file created above<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\r\nexport HDHRID=10XXXXXX \r\n# The following may work as well\r\n#export HDHRID=`hdhomerun_config discover | cut -d\\  -f3`\r\nexport TUNER=tuner1\r\nexport MYIP=`hostname -i`\r\nexport CHANNEL=23\r\nexport PROGRAM=1\r\nexport DEST=\"\/var\/lib\/stream\/mystream.m3u8\"\r\n\r\n# Choose the desired AUDIO Options\r\nAUDIO_OPTS=\"-c:a aac -b:a 160000 -ac 2\"\r\n\r\n# Choose the desired VIDEO Options\r\nVIDEO_OPTS=\"-vcodec libx264 -vprofile high -preset slow -b:v 2500000 -vf scale=-1:720\"\r\nVIDEO_OPTS=\"-vcodec libx264 -vprofile main -preset fast -b:v 500000 -threads 0\"\r\nVIDEO_OPTS=\"-vcodec libx264 -vprofile baseline -preset fast -b:v 500000 -threads 0\"\r\nVIDEO_OPTS=\"-vcodec libx264 -preset veryfast -threads 0\"\r\n\r\nOUTPUT_HLS=\"-hls_time 10 -hls_list_size 10 -start_number 1\"\r\n\r\nhdhomerun_config $HDHRID set \/${TUNER}\/channel auto:${CHANNEL}\r\nhdhomerun_config $HDHRID set \/${TUNER}\/program ${PROGRAM}\r\nhdhomerun_config $HDHRID save \/${TUNER} - | ffmpeg -i - -y $AUDIO_OPTS $VIDEO_OPTS \\\r\n$OUTPUT_HLS $DEST\r\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once and a while you will have to clean up the stream folder<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">find \/var\/lib\/stream -type f -mmin +5 -exec rm -f {} \\;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Better to put this in cron<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">0,30 * * * * find \/var\/lib\/stream -type f -mmin +5 -exec rm -f {} \\;<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Step #5 Configure Apache<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Now you need to configure apache, do these as root, you can use these config files to password protect the site as well.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\/etc\/httpd\/conf.d\/stream.conf<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Alias \/stream \/var\/lib\/stream\r\n\r\n&lt;Directory \"\/var\/lib\/stream\">\r\n   Options None\r\n   AllowOverride None\r\n   &lt;IfVersion >= 2.3>\r\n      &lt;RequireAll>\r\n         Require all granted\r\n      &lt;\/RequireAll>\r\n   &lt;\/IfVersion>\r\n   &lt;IfVersion &lt; 2.3>\r\n      Order allow,deny\r\n      Allow from all\r\n   &lt;\/IfVersion>\r\n&lt;\/Directory>\r\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here is the actual html file, will have it go under \/var\/www\/html\/livetv so you will access it via http:\/\/myserver\/livetv<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The magic is the hls.js java script, you can compile it and run it locally, but it is just javascript.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo mkdir \/var\/www\/html\/livetv\r\nsudo chown larry \/var\/www\/html\/livetv\r\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then as the user create the web page at \/var\/www\/html\/livetv\/index.html<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;html>\r\n  &lt;head>\r\n    &lt;title>Live TV&lt;\/title>\r\n  &lt;\/head>\r\n\r\n  &lt;body>\r\n    &lt;script src=\"https:\/\/cdn.jsdelivr.net\/npm\/hls.js@latest\">&lt;\/script>\r\n    &lt;center>\r\n      &lt;h1>PRIVATE USE ONLY&lt;\/h1>\r\n      &lt;video height=\"360\" id=\"video\" controls>&lt;\/video>\r\n    &lt;\/center>\r\n\r\n    &lt;script>\r\n      var video = document.getElementById('video');\r\n      if (Hls.isSupported()) {\r\n        var hls = new Hls({\r\n          debug: true,\r\n        });\r\n        hls.loadSource('\/stream\/mystream.m3u8');\r\n        hls.attachMedia(video);\r\n        hls.on(Hls.Events.MEDIA_ATTACHED, function () {\r\n          video.muted = false;\r\n          video.play();\r\n        });\r\n      }\r\n      \/\/ hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.\r\n      \/\/ When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video element through the `src` property.\r\n      \/\/ This is using the built-in support of the plain video element, without using hls.js.\r\n      else if (video.canPlayType('application\/vnd.apple.mpegurl')) {\r\n        video.src = '\/stream\/mystream.m3u8';\r\n        video.addEventListener('canplay', function () {\r\n          video.play();\r\n        });\r\n      }\r\n    &lt;\/script>\r\n  &lt;!-- injected in netlify post processing step -->\r\n&lt;\/body>\r\n&lt;\/html>\r\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Restart the web server enable it on reboot<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl enable --now httpd<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Done<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Just go to there server web page http:\/\/whatever\/livetv<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can make it ssl, enable authentication, make it auto start on reboot, etc.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction This document shows you how to set up a system so you can view your web channels from a web browser. Prerequisites Linux Web Server (in this case we will use Rocky Linux&#46;&#46;&#46;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-225","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/my.apolonio.tech\/index.php?rest_route=\/wp\/v2\/posts\/225","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/my.apolonio.tech\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/my.apolonio.tech\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/my.apolonio.tech\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/my.apolonio.tech\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=225"}],"version-history":[{"count":2,"href":"https:\/\/my.apolonio.tech\/index.php?rest_route=\/wp\/v2\/posts\/225\/revisions"}],"predecessor-version":[{"id":227,"href":"https:\/\/my.apolonio.tech\/index.php?rest_route=\/wp\/v2\/posts\/225\/revisions\/227"}],"wp:attachment":[{"href":"https:\/\/my.apolonio.tech\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=225"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/my.apolonio.tech\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=225"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/my.apolonio.tech\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=225"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}