- HTTP/1.1 server [keepalive, byte serving, chunked encoding, and more]
- Gapless streaming web audio player using AudioWorklet and miniaudio with fallback players for incompatible browsers
- server-side audio and video transcoding
- Kodi interface - plugin and accompanying JSON API [video only currently]
- M3U8 playlist interface for easy streaming in video players such as VLC
- [Incomplete] web video players to stream your movies and tv shows in the browser
- automatic media library scanning
youtube-dl
web interface
If you want to skip the setting up Perl and installing Perl modules steps, check out the mhfs.com
binary version of MHFS in releases. It does not have any of the extension modules, but it should run on most unix-like operating systems as it's packaged into Actually Portable Perl.
- A C compiler (needed for building MHFS::XS encoding module and Alien::Tar::Size library).
apt-get install build-essential
ffmpeg
andsox
somewhere into path.ffmpeg
is used for transcoding in the MusicLibrary subsystem and for videos in the video subsystem.sox
is used for resampling in the MusicLibrary subsystem.apt-get install ffmpeg sox
- libFLAC with headers. libFLAC is required to build the XS module [needed for server-side audio decoding and encoding].
Alien::libFLAC
will download and build libFLAC from source if not found.apt-get install libflac-dev
- ssl dev libraries. needed to fetch libFLAC sources using
IO::Socket::SSL
andNet::SSLeay
, for building the XS module iflibflac-dev
is not installed.apt-get install libssl-dev libz-dev
For security it's recommended to create a user account exclusively for running MHFS.
# adduser --system mhfs
- create the daemon user and home directory
# su - mhfs -s /bin/bash
- switch to the new mhfs
user to continue installation
Installing packages under system perl is not recommended. local::lib
is a light-weight solution that installs libraries seperately, but still uses system perl binary. If perl
is unavailable or you prefer to install a perl version just for mhfs, perlbrew
is recommended.
Setup local::lib for existing perl [Recommended]
Follow the local:: lib bootstrapping technique and be sure to load it into the current shell, i.e:eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)"
Install cpanm: curl -L https://cpanmin.us | perl - App::cpanminus
Setup perlbrew distribution
export PERLBREW_ROOT=ABSPATHTOREPO/perl5/perlbrew
replacing ABSPATHTOREPO
with the absolute path to the repo
curl -L https://install.perlbrew.pl | bash
source "$PERLBREW_ROOT/etc/bashrc"
perlbrew install perl-5.34.0
perlbrew list
perlbrew switch perl-5.34.0
where perl-5.34.0
is the version listed.
perlbrew install-cpamn
cd /usr/include/x86_64-linux-gnu/ && h2ph -r -l . && cd sys && h2ph syscall.h && cd ABSPATHTOREPO
where /usr/include/x86_64-linux-gnu
is the kernel header files and ABSPATHTOREPO
is the absolute path to the repo used before.
From cpan [Recommended]: cpanm --with-recommends App::MHFS
From github: Download from releases and extract (tar -xvf MHFS-VERSIONHERE.tar
). Install the perl modules: cd MHFS-VERSIONHERE && cpanm Alien-Tar-Size*.tar.gz Alien-libFLAC*.tar.gz MHFS-XS*.tar.gz App-MHFS*.tar.gz
Start the server, mhfs
to create the settings file: settings.pl
The settings file is created at $XDG_CONFIG_DIRS/mhfs
, by default $HOME/.config/mhfs
. Fill in your settings as needed.
HOST
- address to bind too, i.e. '127.0.0.1'
for localhost or '0.0.0.0'
for all interfaces.
PORT
- port to bind too, i.e. 8000
.
ALLOWED_REMOTEIP_HOSTS
- whitelist to specify allowed remote ip addresses, an optional required Host
header value, and an absolute url override if desired. By default the absolute url is derived from the Host
header. CIDR notation is supported to allow remote ip address ranges in a single item.
'ALLOWED_REMOTEIP_HOSTS' => [
# localhost connections for reverse proxy, use https://domain.net/mhfs to build absolute urls
# the optional forth parameter is needed to ensure the the request came from the reverse proxy.
# It is checked against X-MHFS-PROXY-KEY request header. It MUST be set for features requiring
# headers (X-Forwarded-For, etc) from the reverse proxy such as MHFS::Plugin::BitTorrent::Tracker
['127.0.0.1', undef, 'https://domain.net/mhfs', 'SETME_SUPER_SEKRET_PLEASE'],
['192.168.1.0/24'], # anyone on our LAN
['0.0.0.0/0', 'domain.net:8000'] # direct connections with the correct Host header
],
NETMAP
- a HACK for deciphering routing netmap shenigans, where clients on LAN connect with an alternative address than their real LAN address. Currently just used by MHFS::Plugin::BitTorrent::Tracker
to properly allow peers to work both on the LAN and the internet. [FAKE_IPV4_START, REAL_IPV4_START]
, i.e. [10, 192]
.
PUBLICIP
- Currently just used by MHFS::Plugin::BitTorrent::Tracker
to expose LAN peers to the internet with the external IP address of network, i.e. '1.1.1.1'
MEDIALIBRARIES
- hash of library to folder path mapping.
'MEDIALIBRARIES' => {
'movies' => "/path/to/movies",
'tv' => "/path/to/tv",
'music' => "/path/to/music",
}
Timeouts are used to boot idle or non-responsive connections.
recvrequestimeout
- maximum time [in seconds] to recieve an http request line and headers. Starts when no request is active on connection. default value: 10
sendresponsetimeout
- maximum time [in seconds] allowed between send
's when sending an http response. default value: TIMEOUT
TIMEOUT
- the default timeout value [in seconds] for sendresponsetimeout
. default value: 75
In the case of a mhfs
account, you can just take ownership of it's home directory, but allow it to still own it's temp files
# chown -R YOURUSERNAME:YOURUSERNAME /home/mhfs
- allow your account to manage the files in the mhfs
account instead
# mkdir -p /home/mhfs/.cache/mhfs && chown -R mhfs:nogroup /home/mhfs/.cache/mhfs
- allow mhfs to manage temp files
# mkdir -p /home/mhfs/.local/share/mhfs && chown -R mhfs:nogroup /home/mhfs/.local/share/mhfs
- allow mhfs to save permanent files
mhfs
Navigate to the url, by default http://127.0.0.1:8080/
you are presented with a few different routes:
/music
to enter the music library and player. See below for info on the MusicLibrary
subsystem.
/video
to enter the movie and tv library and player. See below for info on the Video
subsystem.
To add TLS and allow access without entering a port in the URL, reverse proxying is recommended.
Setup TLS, Let's Encrypt certbot recommended.
Add the following to your site config i.e. /etc/apache2/sites-available/000-default-le-ssl.conf
replacing mhfs
with the name you want on your site. Set X-MHFS-PROXY-KEY
request header to the same secret as before. Keep the trailing slashes [or absense of] the same.
RewriteEngine On
RewriteRule ^/mhfs$ mhfs/ [R,L]
<Location "/mhfs/">
RequestHeader set X-MHFS-PROXY-KEY SAME_SUPER_SEKRET_AS_SET_IN_CONFIG
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/wasm
ProxyPass "http://127.0.0.1:8000/"
</Location>
Reload apache2 # service apache2 reload
. If it fails install mod_headers
: maybe a2enmod headers && service apache2 restart
On web servers with connection reuse bugs (even much of Apache 2.4), disable connection reuse:
ProxyPass "http://127.0.0.1:8000/" disablereuse=On
A sample service set to use the local::lib is provided.
cp resources/mhfs.service /etc/systemd/system/mhfs.service
systemctl daemon-reload
systemctl enable mhfs.service
systemctl start mhfs.service
The music player is by default accessed with /music
.
/music?fmt=worklet
- AudioWorklet
based player.
- Gapless streaming of FLAC, WAV, and MP3 without needing server-side decoding support
- Shows embedded or file based cover art.
- Shows metadata (Trackname, Artist, and Album) instead of file path.
- Keyboard based controls and MediaSession support for media key usage.
/music?fmt=legacy
- Legacy browser player. Uses html audio tag to load and play audio.
/music?fmt=musicinc
- Incremental gapless player. Uses AudioBufferSourceNode
s to play audio.
/music
Request a music player or the music library in a variety of formats. See MusicLibrary::SendLibrary
.
/music_dl?name=folderpath
Download a track [or part of one] by filename with optional resampling, channel mixing, and encoding. See MusicLibrary::SendLocalTrack
.
/music_resources?name=folderpath
Download a flac audio track's vorbis comments as json. See MusicLibrary::SendResources
.
The video player is accessed with /video
.
For convenience M3U
playlist files are provided to ease streaming outside of the browser in software such as VLC. Note, this may only work well on LAN.
There is a MHFS Kodi plugin (video add-on) and accompanying JSON API.
/kodi/
- plugin installation instructions and link to repository add-on. The repository add-on only connects to your instance of MHFS.
/kodi/movies/
- Movies JSON API, somewhat available as HTML with ?fmt=html
/kodi/tv/
- TV JSON API, somewhat available as HTML with ?fmt=html
Install the perl dependencies from cpanfile
with cpanm --with-develop --with-configure --installdeps .
emscripten is required to build the web music players (they use Wasm).
A full build is done with make -j4
.
./runintree.pl
allows running MHFS directly from this source code tree
./debug.pl
terminates instances of MHFS, builds MHFS, and runs ./runintree.pl
Tejas Rao for source code review early on. mackron for great audio libraries and answering questions.
This software is copyright (c) 2018-2024 by Gavin Hayes.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. See LICENSE.